mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
Refactor: using middleware for policy valication.
Signed-off-by: Mofei Zhang <mofei2816@gmail.com>
This commit is contained in:
parent
22944e11cc
commit
aec409ffcf
@ -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)
|
||||
|
||||
@ -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'
|
||||
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"`
|
||||
|
||||
@ -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
|
||||
|
||||
@ -165,6 +165,7 @@ func (o *ObjectNode) startMuxRestAPI() (err error) {
|
||||
router.Use(
|
||||
o.traceMiddleware,
|
||||
o.authMiddleware,
|
||||
o.policyCheckMiddleware,
|
||||
o.contentMiddleware,
|
||||
)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user