Refactor: using middleware for policy valication.

Signed-off-by: Mofei Zhang <mofei2816@gmail.com>
This commit is contained in:
Mofei Zhang 2020-02-27 20:35:04 +08:00
parent 22944e11cc
commit aec409ffcf
8 changed files with 391 additions and 183 deletions

View File

@ -38,6 +38,10 @@ type RequestParam struct {
accessKey string
}
func (p *RequestParam) GetVar(name string) string {
return p.vars[name]
}
func (o *ObjectNode) parseRequestParam(r *http.Request) (*RequestParam, error) {
p := new(RequestParam)
p.vars = mux.Vars(r)

View File

@ -18,6 +18,7 @@ import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"io/ioutil"
@ -819,7 +820,7 @@ func (o *ObjectNode) putObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
}
var tagging = NewTagging()
if err = UnmarshalXMLEntity(requestBody, tagging); err != nil {
if err = xml.Unmarshal(requestBody, tagging); err != nil {
log.LogWarnf("putObjectTaggingHandler: decode request body fail: requestID(%v) err(%v)", GetRequestID(r), err)
_ = InvalidArgument.ServeResponse(w, r)
return
@ -846,7 +847,7 @@ func (o *ObjectNode) deleteObjectTaggingHandler(w http.ResponseWriter, r *http.R
var err error
var param *RequestParam
if param, err = o.parseRequestParam(r); err != nil {
log.LogErrorf("deleteObjectTaggingHandler: parse request param fail: requestID(%v) err(%v)", GetRequestID(r), err)
log.LogWarnf("deleteObjectTaggingHandler: parse request param fail: requestID(%v) err(%v)", GetRequestID(r), err)
_ = InvalidArgument.ServeResponse(w, r)
return
}
@ -863,21 +864,154 @@ func (o *ObjectNode) deleteObjectTaggingHandler(w http.ResponseWriter, r *http.R
}
// Put object extend attribute (xattr)
func (o *ObjectNode) putObjectXAttr(w http.ResponseWriter, r *http.Request) {
// TODO: implement 'putObjectXAttr'
func (o *ObjectNode) putObjectXAttrHandler(w http.ResponseWriter, r *http.Request) {
var err error
var param *RequestParam
if param, err = o.parseRequestParam(r); err != nil {
log.LogWarnf("putObjectXAttrHandler: parse request param fail: requestID(%v) err(%v)", GetRequestID(r), err)
_ = InvalidArgument.ServeResponse(w, r)
return
}
if len(param.bucket) == 0 {
_ = NoSuchBucket.ServeResponse(w, r)
return
}
var vol *volume
if vol, err = o.getVol(param.bucket); err != nil {
_ = NoSuchBucket.ServeResponse(w, r)
return
}
if len(param.object) == 0 {
_ = NoSuchKey.ServeResponse(w, r)
return
}
var requestBody []byte
if requestBody, err = ioutil.ReadAll(r.Body); err != nil {
_ = ErrorCode{
ErrorCode: "BadRequest",
ErrorMessage: err.Error(),
StatusCode: http.StatusBadRequest,
}.ServeResponse(w, r)
return
}
var putXAttrRequest = PutXAttrRequest{}
if err = xml.Unmarshal(requestBody, &putXAttrRequest); err != nil {
_ = ErrorCode{
ErrorCode: "BadRequest",
ErrorMessage: err.Error(),
StatusCode: http.StatusBadRequest,
}.ServeResponse(w, r)
return
}
var key, value = putXAttrRequest.XAttr.Key, putXAttrRequest.XAttr.Value
if len(key) == 0 {
return
}
if err = vol.SetXAttr(param.object, key, []byte(value)); err != nil {
if err == syscall.ENOENT {
_ = NoSuchKey.ServeResponse(w, r)
return
}
_ = InternalError.ServeResponse(w, r)
return
}
return
}
// Get object extend attribute (xattr)
func (o *ObjectNode) getObjectXAttr(w http.ResponseWriter, r *http.Request) {
// TODO: implement 'getObjectXAttr'
var err error
var param *RequestParam
if param, err = o.parseRequestParam(r); err != nil {
log.LogWarnf("deleteObjectXAttrHandler: parse request param fail: requestID(%v) err(%v)", GetRequestID(r), err)
_ = InvalidArgument.ServeResponse(w, r)
return
}
if len(param.bucket) == 0 {
_ = InvalidArgument.ServeResponse(w, r)
return
}
var vol *volume
if vol, err = o.getVol(param.bucket); err != nil {
_ = NoSuchBucket.ServeResponse(w, r)
return
}
if len(param.object) == 0 {
_ = InvalidArgument.ServeResponse(w, r)
return
}
var xattrKey string
if xattrKey = param.GetVar("key"); len(xattrKey) == 0 {
_ = InvalidArgument.ServeResponse(w, r)
return
}
var info *proto.XAttrInfo
if info, err = vol.GetXAttr(param.object, xattrKey); err != nil {
if err == syscall.ENOENT {
_ = NoSuchKey.ServeResponse(w, r)
return
}
_ = InternalError.ServeResponse(w, r)
return
}
var response = GetXAttrOutput{
XAttr: &XAttr{
Key: xattrKey,
Value: string(info.Get(xattrKey)),
},
}
var marshaled []byte
if marshaled, err = MarshalXMLEntity(&response); err != nil {
_ = InternalError.ServeResponse(w, r)
return
}
_, _ = w.Write(marshaled)
return
}
// Delete object extend attribute (xattr)
func (o *ObjectNode) deleteObjectXAttr(w http.ResponseWriter, r *http.Request) {
// TODO: implement 'deleteObjectXAttr'
func (o *ObjectNode) deleteObjectXAttrHandler(w http.ResponseWriter, r *http.Request) {
var err error
var param *RequestParam
if param, err = o.parseRequestParam(r); err != nil {
log.LogWarnf("deleteObjectXAttrHandler: parse request param fail: requestID(%v) err(%v)", GetRequestID(r), err)
_ = InvalidArgument.ServeResponse(w, r)
return
}
if len(param.bucket) == 0 {
_ = InvalidArgument.ServeResponse(w, r)
return
}
var vol *volume
if vol, err = o.getVol(param.bucket); err != nil {
_ = NoSuchBucket.ServeResponse(w, r)
return
}
if len(param.object) == 0 {
_ = InvalidArgument.ServeResponse(w, r)
return
}
var xattrKey string
if xattrKey = param.GetVar("key"); len(xattrKey) == 0 {
_ = InvalidArgument.ServeResponse(w, r)
return
}
if err = vol.DeleteXAttr(param.object, xattrKey); err != nil {
if err == syscall.ENOENT {
_ = NoSuchKey.ServeResponse(w, r)
return
}
_ = InternalError.ServeResponse(w, r)
return
}
return
}
// List object xattrs
func (o *ObjectNode) listObjectXAttrs(w http.ResponseWriter, r *http.Request) {
// TODO: implement 'listObjectXAttrs'
}

View File

@ -70,10 +70,14 @@ func (o *ObjectNode) traceMiddleware(next http.Handler) http.Handler {
}
log.LogDebugf("traceMiddleware: trace request:\n"+
" action(%v)\n"+
" requestID(%v) host(%v) method(%v) url(%v)\n"+
" header(%v)\n"+
" remote(%v) cost(%v)",
requestID, r.Host, r.Method, r.URL.String(), headerToString(r.Header), getRequestIP(r), time.Since(startTime))
ActionFromRouteName(mux.CurrentRoute(r).GetName()).String(),
requestID, r.Host, r.Method, r.URL.String(),
headerToString(r.Header),
getRequestIP(r), time.Since(startTime))
}
return handlerFunc
@ -81,15 +85,6 @@ func (o *ObjectNode) traceMiddleware(next http.Handler) http.Handler {
func (o *ObjectNode) authMiddleware(next http.Handler) http.Handler {
var parseActionName = func(r *http.Request) string {
routeName := mux.CurrentRoute(r).GetName()
routeSNLoc := routeSNRegexp.FindStringIndex(routeName)
if len(routeSNLoc) != 2 {
return routeName
}
return routeName[:len(routeName)-33]
}
var isSignatureIgnoredAction = func(action Action) bool {
if len(o.signatureIgnoredActions) == 0 {
return false
@ -104,7 +99,7 @@ func (o *ObjectNode) authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
var currentAction = ActionFromString(parseActionName(r))
var currentAction = ActionFromRouteName(mux.CurrentRoute(r).GetName())
if currentAction.IsKnown() && isSignatureIgnoredAction(currentAction) {
next.ServeHTTP(w, r)
return
@ -152,6 +147,16 @@ func (o *ObjectNode) authMiddleware(next http.Handler) http.Handler {
})
}
func (o *ObjectNode) policyCheckMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
action := ActionFromRouteName(mux.CurrentRoute(r).GetName())
wrappedNext := o.policyCheck(next.ServeHTTP, action)
wrappedNext.ServeHTTP(w, r)
return
})
}
func (o *ObjectNode) contentMiddleware(next http.Handler) http.Handler {
var handlerFunc http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
if len(r.Header) > 0 && len(r.Header.Get(http.CanonicalHeaderKey(HeaderNameDecodeContentLength))) > 0 {

View File

@ -160,7 +160,6 @@ func (v *volume) OSSMeta() *OSSMeta {
}
func (v *volume) getInodeFromPath(path string) (inode uint64, err error) {
// path == "/"
if path == "/" {
return volumeRootInode, nil
}
@ -193,9 +192,22 @@ func (v *volume) getInodeFromPath(path string) (inode uint64, err error) {
}
func (v *volume) SetXAttr(path string, key string, data []byte) error {
inode, err1 := v.getInodeFromPath(path)
if err1 != nil {
return err1
var err error
var inode uint64
if inode, err = v.getInodeFromPath(path); err != nil && err != syscall.ENOENT {
return err
}
if err == syscall.ENOENT {
var dirs, filename = splitPath(path)
var parentID uint64
if parentID, err = v.lookupDirectories(dirs, true); err != nil {
return err
}
var inodeInfo *proto.InodeInfo
if inodeInfo, err = v.mw.Create_ll(parentID, filename, 0600, 0, 0, nil); err != nil {
return err
}
inode = inodeInfo.Inode
}
return v.mw.XAttrSet_ll(inode, []byte(key), data)
}

View File

@ -14,6 +14,13 @@
package objectnode
import (
"strings"
"github.com/chubaofs/chubaofs/util"
"github.com/google/uuid"
)
// https://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
// https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html
@ -28,54 +35,65 @@ func (a Action) IsKnown() bool {
return len(a) != 0 && a != UnknownAction
}
func (a Action) UniqueRouteName() (name string) {
var id uuid.UUID
var err error
if id, err = uuid.NewRandom(); err != nil {
name = a.String() + ":" + util.RandomString(32, util.UpperLetter|util.LowerLetter)
return
}
name = a.String() + ":" + strings.ReplaceAll(id.String(), "-", "")
return
}
const (
OSSActionPrefix = "oss:action:"
GetObjectAction Action = OSSActionPrefix + "GetObject"
PutObjectAction = OSSActionPrefix + "PutObject"
CopyObjectAction = OSSActionPrefix + "CopyObject"
ListObjectsAction = OSSActionPrefix + "ListObjects"
DeleteObjectAction = OSSActionPrefix + "DeleteObject"
DeleteObjectsAction = OSSActionPrefix + "DeleteObjects"
HeadObjectAction = OSSActionPrefix + "HeadObject"
CreateBucketAction = OSSActionPrefix + "CreateBucket"
DeleteBucketAction = OSSActionPrefix + "DeleteBucket"
HeadBucketAction = OSSActionPrefix + "HeadBucket"
ListBucketAction = OSSActionPrefix + "ListBucket"
ListBucketVersionsAction = OSSActionPrefix + "ListBucketVersions"
ListBucketMultipartUploadsAction = OSSActionPrefix + "ListBucketMultipartUploads"
GetBucketPolicyAction = OSSActionPrefix + "GetBucketPolicy"
PutBucketPolicyAction = OSSActionPrefix + "PutBucketPolicy"
GetBucketAclAction = OSSActionPrefix + "GetBucketAcl"
PutBucketAclAction = OSSActionPrefix + "PutBucketAcl"
GetObjectAclAction = OSSActionPrefix + "GetObjectAcl"
GetObjectVersionAction = OSSActionPrefix + "GetObjectVersion"
PutObjectVersionAction = OSSActionPrefix + "PutObjectVersion"
GetObjectTorrentAction = OSSActionPrefix + "GetObjectTorrent"
PutObjectTorrentAction = OSSActionPrefix + "PutObjectTorrent"
PutObjectAclAction = OSSActionPrefix + "PutObjectAcl"
GetObjectVersionAclAction = OSSActionPrefix + "GetObjectVersionAcl"
PutObjectVersionAclAction = OSSActionPrefix + "PutObjectVersionAcl"
DeleteBucketPolicyAction = OSSActionPrefix + "DeleteBucketPolicy"
CreateMultipartUploadAction = OSSActionPrefix + "CreateMultipartUpload"
ListMultipartUploadsAction = OSSActionPrefix + "ListMultipartUploads"
UploadPartAction = OSSActionPrefix + "UploadPart"
ListPartsAction = OSSActionPrefix + "ListParts"
CompleteMultipartUploadAction = OSSActionPrefix + "CompleteMultipartUpload"
AbortMultipartUploadAction = OSSActionPrefix + "AbortMultipartUpload"
GetBucketLocationAction = OSSActionPrefix + "GetBucketLocation"
GetObjectXAttrAction = OSSActionPrefix + "GetObjectXAttr"
PutObjectXAttrAction = OSSActionPrefix + "PutObjectAttr"
ListObjectXAttrsAction = OSSActionPrefix + "ListObjectXAttrs"
DeleteObjectXAttrAction = OSSActionPrefix + "DeleteObjectXAttr"
GetObjectTaggingAction = OSSActionPrefix + "GetObjectTagging"
PutObjectTaggingAction = OSSActionPrefix + "PutObjectTagging"
DeleteObjectTaggingAction = OSSActionPrefix + "DeleteObjectTagging"
GetBucketTaggingAction = OSSActionPrefix + "GetBucketTagging"
PutBucketTaggingAction = OSSActionPrefix + "PutBucketTagging"
DeleteBucketTaggingAction = OSSActionPrefix + "DeleteBucketTagging"
PutObjectAction Action = OSSActionPrefix + "PutObject"
CopyObjectAction Action = OSSActionPrefix + "CopyObject"
ListObjectsAction Action = OSSActionPrefix + "ListObjects"
DeleteObjectAction Action = OSSActionPrefix + "DeleteObject"
DeleteObjectsAction Action = OSSActionPrefix + "DeleteObjects"
HeadObjectAction Action = OSSActionPrefix + "HeadObject"
CreateBucketAction Action = OSSActionPrefix + "CreateBucket"
DeleteBucketAction Action = OSSActionPrefix + "DeleteBucket"
HeadBucketAction Action = OSSActionPrefix + "HeadBucket"
ListBucketAction Action = OSSActionPrefix + "ListBucket"
ListBucketVersionsAction Action = OSSActionPrefix + "ListBucketVersions"
ListBucketMultipartUploadsAction Action = OSSActionPrefix + "ListBucketMultipartUploads"
GetBucketPolicyAction Action = OSSActionPrefix + "GetBucketPolicy"
PutBucketPolicyAction Action = OSSActionPrefix + "PutBucketPolicy"
GetBucketAclAction Action = OSSActionPrefix + "GetBucketAcl"
PutBucketAclAction Action = OSSActionPrefix + "PutBucketAcl"
GetObjectAclAction Action = OSSActionPrefix + "GetObjectAcl"
GetObjectVersionAction Action = OSSActionPrefix + "GetObjectVersion"
PutObjectVersionAction Action = OSSActionPrefix + "PutObjectVersion"
GetObjectTorrentAction Action = OSSActionPrefix + "GetObjectTorrent"
PutObjectTorrentAction Action = OSSActionPrefix + "PutObjectTorrent"
PutObjectAclAction Action = OSSActionPrefix + "PutObjectAcl"
GetObjectVersionAclAction Action = OSSActionPrefix + "GetObjectVersionAcl"
PutObjectVersionAclAction Action = OSSActionPrefix + "PutObjectVersionAcl"
DeleteBucketPolicyAction Action = OSSActionPrefix + "DeleteBucketPolicy"
CreateMultipartUploadAction Action = OSSActionPrefix + "CreateMultipartUpload"
ListMultipartUploadsAction Action = OSSActionPrefix + "ListMultipartUploads"
UploadPartAction Action = OSSActionPrefix + "UploadPart"
ListPartsAction Action = OSSActionPrefix + "ListParts"
CompleteMultipartUploadAction Action = OSSActionPrefix + "CompleteMultipartUpload"
AbortMultipartUploadAction Action = OSSActionPrefix + "AbortMultipartUpload"
GetBucketLocationAction Action = OSSActionPrefix + "GetBucketLocation"
GetObjectXAttrAction Action = OSSActionPrefix + "GetObjectXAttr"
PutObjectXAttrAction Action = OSSActionPrefix + "PutObjectAttr"
ListObjectXAttrsAction Action = OSSActionPrefix + "ListObjectXAttrs"
DeleteObjectXAttrAction Action = OSSActionPrefix + "DeleteObjectXAttr"
GetObjectTaggingAction Action = OSSActionPrefix + "GetObjectTagging"
PutObjectTaggingAction Action = OSSActionPrefix + "PutObjectTagging"
DeleteObjectTaggingAction Action = OSSActionPrefix + "DeleteObjectTagging"
GetBucketTaggingAction Action = OSSActionPrefix + "GetBucketTagging"
PutBucketTaggingAction Action = OSSActionPrefix + "PutBucketTagging"
DeleteBucketTaggingAction Action = OSSActionPrefix + "DeleteBucketTagging"
UnknownAction = OSSActionPrefix + "Unknown"
UnknownAction Action = OSSActionPrefix + "Unknown"
)
var (
@ -137,6 +155,14 @@ func ActionFromString(str string) Action {
return UnknownAction
}
func ActionFromRouteName(name string) Action {
routeSNLoc := routeSNRegexp.FindStringIndex(name)
if len(routeSNLoc) != 2 {
return ActionFromString(name)
}
return ActionFromString(name[:len(name)-33])
}
func (s Statement) checkActions(p *RequestParam) bool {
if s.Actions.Empty() {
return true

View File

@ -298,6 +298,11 @@ type PutXAttrRequest struct {
XAttr *XAttr `xml:"XAttr"`
}
type GetXAttrOutput struct {
XMLName xml.Name `xml:"GetXAttrOutput"`
XAttr *XAttr `xml:"XAttr"`
}
type ListXAttrsResult struct {
XMLName xml.Name `xml:"ListXAttrsResult"`
XAttrs []*XAttr `xml:"XAttrs>XAttr"`

View File

@ -16,10 +16,6 @@ package objectnode
import (
"net/http"
"strings"
"github.com/chubaofs/chubaofs/util"
"github.com/google/uuid"
"github.com/gorilla/mux"
)
@ -35,264 +31,288 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
}
bucketRouters = append(bucketRouters, bRouter.PathPrefix("/{bucket}").Subrouter())
var unionRouteName = func(action Action) (name string) {
var id uuid.UUID
var err error
if id, err = uuid.NewRandom(); err != nil {
name = action.String() + ":" + util.RandomString(32, util.UpperLetter|util.LowerLetter)
return
}
name = action.String() + ":" + strings.ReplaceAll(id.String(), "-", "")
return
}
var registerBucketHttpHeadRouters = func(r *mux.Router) {
// Head object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html
r.Methods(http.MethodHead).
r.NewRoute().Name(HeadObjectAction.UniqueRouteName()).
Methods(http.MethodHead).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.headObjectHandler, HeadObjectAction)).
Name(unionRouteName(HeadObjectAction))
HandlerFunc(o.headObjectHandler)
// Head bucket
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html
r.Methods(http.MethodHead).
HandlerFunc(o.policyCheck(o.headBucketHandler, HeadBucketAction)).
Name(unionRouteName(HeadBucketAction))
r.NewRoute().Name(HeadBucketAction.UniqueRouteName()).
Methods(http.MethodHead).
HandlerFunc(o.headBucketHandler)
}
var registerBucketHttpGetRouters = func(r *mux.Router) {
// Get object with pre-signed auth signature v2
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
r.Methods(http.MethodGet).
r.NewRoute().Name(GetObjectAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.getObjectHandler, GetObjectAction)).
Queries("AWSAccessKeyId", "{accessKey:.+}",
"Expires", "{expires:[0-9]+}", "Signature", "{signature:.+}").
Name(unionRouteName(GetObjectAction))
HandlerFunc(o.getObjectHandler)
// Get object with pre-signed auth signature v4
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
r.Methods(http.MethodGet).
r.NewRoute().Name(GetObjectAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.getObjectHandler, GetObjectAction)).
Queries("X-Amz-Credential", "{creadential:.+}",
"X-Amz-Algorithm", "{algorithm:.+}", "X-Amz-Signature", "{signature:.+}",
"X-Amz-Date", "{date:.+}", "X-Amz-SignedHeaders", "{signedHeaders:.+}",
"X-Amz-Expires", "{expires:[0-9]+}")
"X-Amz-Expires", "{expires:[0-9]+}").
HandlerFunc(o.getObjectHandler)
// Get object tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html
r.Methods(http.MethodGet).
r.NewRoute().Name(GetObjectTaggingAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.getObjectTaggingHandler, GetObjectTaggingAction)).
Queries("tagging", "")
Queries("tagging", "").
HandlerFunc(o.getObjectTaggingHandler)
// Get object XAttr
// Notes: ChubaoFS owned API for XAttr operation
r.Methods(http.MethodGet).
r.NewRoute().Name(GetObjectXAttrAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.getObjectXAttr, GetObjectXAttrAction)).
Queries("xattr", "", "key", "{key:.+}")
Queries("xattr", "", "key", "{key:.+}").
HandlerFunc(o.getObjectXAttr)
// List object XAttrs
r.Methods(http.MethodGet).
r.NewRoute().Name(ListObjectXAttrsAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.listObjectXAttrs, ListObjectXAttrsAction)).
Queries("xattr", "")
Queries("xattr", "").
HandlerFunc(o.listObjectXAttrs)
// Get object acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html
r.Methods(http.MethodGet).
r.NewRoute().Name(GetObjectAclAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{objject:.+}").
HandlerFunc(o.policyCheck(o.getObjectACLHandler, GetObjectAclAction)).
Queries("acl", "")
Queries("acl", "").
HandlerFunc(o.getObjectACLHandler)
// Get object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
r.Methods(http.MethodGet).
r.NewRoute().Name(GetObjectAction.UniqueRouteName()).
Methods(http.MethodGet).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.getObjectHandler, GetObjectAction))
HandlerFunc(o.getObjectHandler)
// List objects version 2
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.getBucketV2Handler, ListObjectsAction)).
Queries("list-type", "2")
r.NewRoute().Name(ListObjectsAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("list-type", "2").
HandlerFunc(o.getBucketV2Handler)
// List multipart uploads
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.listMultipartUploadsHandler, ListMultipartUploadsAction)).
Queries("uploads", "")
r.NewRoute().Name(ListMultipartUploadsAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("uploads", "").
HandlerFunc(o.listMultipartUploadsHandler)
// List parts
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.listPartsHandler, ListPartsAction)).
Queries("uploadId", "{uploadId:.*}")
r.NewRoute().Name(ListPartsAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("uploadId", "{uploadId:.*}").
HandlerFunc(o.listPartsHandler)
// Get bucket location
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.getBucketLocation, GetBucketLocationAction)).
Queries("location", "")
r.NewRoute().Name(GetBucketLocationAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("location", "").
HandlerFunc(o.getBucketLocation)
// Get bucket policy
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicy.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.getBucketPolicyHandler, GetBucketPolicyAction)).
Queries("policy", "")
r.NewRoute().Name(GetBucketPolicyAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("policy", "").
HandlerFunc(o.getBucketPolicyHandler)
// Get bucket acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.getBucketACLHandler, GetBucketAclAction)).
Queries("acl", "")
r.NewRoute().Name(GetBucketAclAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("acl", "").
HandlerFunc(o.getBucketACLHandler)
// Get bucket tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.getBucketTaggingHandler, GetBucketTaggingAction)).
Queries("tagging", "")
r.NewRoute().Name(GetBucketTaggingAction.UniqueRouteName()).
Methods(http.MethodGet).
Queries("tagging", "").
HandlerFunc(o.getBucketTaggingHandler)
// List objects version 1
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html
r.Methods(http.MethodGet).
HandlerFunc(o.policyCheck(o.getBucketV1Handler, ListObjectsAction))
r.NewRoute().Name(ListObjectsAction.UniqueRouteName()).
Methods(http.MethodGet).
HandlerFunc(o.getBucketV1Handler)
}
var registerBucketHttpPostRouters = func(r *mux.Router) {
// Create multipart upload
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html
r.Methods(http.MethodPost).
r.NewRoute().Name(CreateMultipartUploadAction.UniqueRouteName()).
Methods(http.MethodPost).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.createMultipleUploadHandler, CreateMultipartUploadAction)).
Queries("uploads", "")
Queries("uploads", "").
HandlerFunc(o.createMultipleUploadHandler)
// Complete multipart
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html
r.Methods(http.MethodPost).
r.NewRoute().Name(CompleteMultipartUploadAction.UniqueRouteName()).
Methods(http.MethodPost).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.completeMultipartUploadHandler, CompleteMultipartUploadAction)).
Queries("uploadId", "{uploadId:.*}")
Queries("uploadId", "{uploadId:.*}").
HandlerFunc(o.completeMultipartUploadHandler)
// Delete objects (multiple objects)
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html
r.Methods(http.MethodPost).
HandlerFunc(o.policyCheck(o.deleteObjectsHandler, DeleteObjectsAction)).
Queries("delete", "")
r.NewRoute().Name(DeleteObjectsAction.UniqueRouteName()).
Methods(http.MethodPost).
Queries("delete", "").
HandlerFunc(o.deleteObjectsHandler)
}
var registerBucketHttpPutRouters = func(r *mux.Router) {
// Upload part
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html .
r.Methods(http.MethodPut).
r.NewRoute().Name(UploadPartAction.UniqueRouteName()).
Methods(http.MethodPut).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.uploadPartHandler, UploadPartAction)).
Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}")
Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}").
HandlerFunc(o.uploadPartHandler)
// Copy object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html .
r.Methods(http.MethodPut).
r.NewRoute().Name(CopyObjectAction.UniqueRouteName()).
Methods(http.MethodPut).
Path("/{object:.+}").
HeadersRegexp(HeaderNameCopySource, ".*?(\\/|%2F).*?").
HandlerFunc(o.policyCheck(o.copyObjectHandler, CopyObjectAction))
HandlerFunc(o.copyObjectHandler)
// Put object tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html
r.Methods(http.MethodPut).
r.NewRoute().Name(PutObjectTaggingAction.UniqueRouteName()).
Methods(http.MethodPut).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.putObjectTaggingHandler, PutObjectTaggingAction)).
Queries("tagging", "")
Queries("tagging", "").
HandlerFunc(o.putObjectTaggingHandler)
// Put object xattrs
// Notes: ChubaoFS owned API for XAttr operation
r.Methods(http.MethodPut).
r.NewRoute().Name(PutObjectXAttrAction.UniqueRouteName()).
Methods(http.MethodPut).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.putObjectXAttr, PutObjectXAttrAction)).
Queries("xattr", "")
Queries("xattr", "").
HandlerFunc(o.putObjectXAttrHandler)
// Put object acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
r.Methods(http.MethodPut).
r.NewRoute().Name(PutObjectAclAction.UniqueRouteName()).
Methods(http.MethodPut).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.putObjectACLHandler, PutObjectAclAction)).
Queries("acl", "")
Queries("acl", "").
HandlerFunc(o.putObjectACLHandler)
// Put object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html
r.Methods(http.MethodPut).
r.NewRoute().Name(PutObjectAction.UniqueRouteName()).
Methods(http.MethodPut).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.putObjectHandler, PutObjectAction))
HandlerFunc(o.putObjectHandler)
// Put bucket acl
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
r.Methods(http.MethodPut).
HandlerFunc(o.policyCheck(o.putBucketACLHandler, PutBucketAclAction)).
Queries("acl", "")
r.NewRoute().Name(PutBucketAclAction.UniqueRouteName()).
Methods(http.MethodPut).
Queries("acl", "").
HandlerFunc(o.putBucketACLHandler)
// Put bucket policy
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html
r.Methods(http.MethodPut).
HandlerFunc(o.policyCheck(o.putBucketPolicyHandler, PutBucketPolicyAction)).
Queries("policy", "")
r.NewRoute().Name(PutBucketPolicyAction.UniqueRouteName()).
Methods(http.MethodPut).
Queries("policy", "").
HandlerFunc(o.putBucketPolicyHandler)
// Put bucket tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html
r.Methods(http.MethodPut).
HandlerFunc(o.policyCheck(o.putBucketTaggingHandler, PutBucketTaggingAction)).
Queries("tagging", "")
r.NewRoute().Name(PutBucketTaggingAction.UniqueRouteName()).
Methods(http.MethodPut).
Queries("tagging", "").
HandlerFunc(o.putBucketTaggingHandler)
// Create bucket
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html
r.Methods(http.MethodPut).
r.NewRoute().Name(CreateBucketAction.UniqueRouteName()).
Methods(http.MethodPut).
HandlerFunc(o.createBucketHandler)
}
var registerBucketHttpDeleteRouters = func(r *mux.Router) {
// Abort multipart upload
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html .
r.Methods(http.MethodDelete).
r.NewRoute().Name(AbortMultipartUploadAction.UniqueRouteName()).
Methods(http.MethodDelete).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.abortMultipartUploadHandler, AbortMultipartUploadAction)).
Queries("uploadId", "{uploadId:.*}")
Queries("uploadId", "{uploadId:.*}").
HandlerFunc(o.abortMultipartUploadHandler)
// Delete object tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html
r.Methods(http.MethodDelete).
r.NewRoute().Name(DeleteObjectTaggingAction.UniqueRouteName()).
Methods(http.MethodDelete).
Path("/{object:.+").
HandlerFunc(o.policyCheck(o.deleteObjectTaggingHandler, DeleteObjectTaggingAction)).
Queries("tagging", "")
Queries("tagging", "").
HandlerFunc(o.deleteObjectTaggingHandler)
// Delete object xattrs
// Notes: ChubaoFS owned API for XAttr operation
r.Methods(http.MethodDelete).
r.NewRoute().Name(DeleteObjectXAttrAction.UniqueRouteName()).
Methods(http.MethodDelete).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.deleteObjectXAttr, DeleteObjectXAttrAction)).
Queries("xattr", "key", "{key:.+}}")
Queries("xattr", "key", "{key:.+}}").
HandlerFunc(o.deleteObjectXAttrHandler)
// Delete object
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html .
r.Methods(http.MethodDelete).
r.NewRoute().Name(DeleteObjectAction.UniqueRouteName()).
Methods(http.MethodDelete).
Path("/{object:.+}").
HandlerFunc(o.policyCheck(o.deleteObjectHandler, DeleteObjectAction))
HandlerFunc(o.deleteObjectHandler)
// Delete bucket policy
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketPolicy.html
r.Methods(http.MethodDelete).
HandlerFunc(o.policyCheck(o.deleteBucketPolicyHandler, DeleteBucketPolicyAction)).
Queries("policy", "")
r.NewRoute().Name(DeleteBucketPolicyAction.UniqueRouteName()).
Methods(http.MethodDelete).
Queries("policy", "").
HandlerFunc(o.deleteBucketPolicyHandler)
// Delete bucket tagging
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html
r.Methods(http.MethodDelete).
Handler(o.policyCheck(o.deleteBucketTaggingHandler, DeleteBucketTaggingAction)).
Queries("tagging", "")
r.NewRoute().Name(DeleteBucketTaggingAction.UniqueRouteName()).
Methods(http.MethodDelete).
Queries("tagging", "").
HandlerFunc(o.deleteBucketTaggingHandler)
// Delete bucket
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html
r.Methods(http.MethodDelete).HandlerFunc(o.policyCheck(o.deleteBucketHandler, DeleteBucketAction))
r.NewRoute().Name(DeleteBucketAction.UniqueRouteName()).
Methods(http.MethodDelete).
HandlerFunc(o.deleteBucketHandler)
}
@ -306,7 +326,8 @@ func (o *ObjectNode) registerApiRouters(router *mux.Router) {
// List buckets
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html
router.Methods(http.MethodGet).
router.NewRoute().Name(ListBucketAction.UniqueRouteName()).
Methods(http.MethodGet).
HandlerFunc(o.listBucketsHandler)
// Unsupported operation

View File

@ -165,6 +165,7 @@ func (o *ObjectNode) startMuxRestAPI() (err error) {
router.Use(
o.traceMiddleware,
o.authMiddleware,
o.policyCheckMiddleware,
o.contentMiddleware,
)