[#583] Fix list-buckets vhs routing
The problem is that with VHS requests, the list-buckets operation does not work because the request is filtered on list-objects-v1. Since list-buckets can also have query parameters, in the end it is necessary to distinguish list-buckets from list-objects-v1 only by the presence of the bucket name in the URL (provided that the request is in VHS style). Signed-off-by: Roman Loginov <r.loginov@yadro.com>
This commit is contained in:
parent
f2274b2786
commit
09412d8f20
4 changed files with 126 additions and 35 deletions
|
@ -159,7 +159,7 @@ func NewRouter(cfg Config) *chi.Mux {
|
|||
defaultRouter.Get("/", named(s3middleware.ListBucketsOperation, cfg.Handler.ListBucketsHandler))
|
||||
attachErrorHandler(defaultRouter)
|
||||
|
||||
vhsRouter := bucketRouter(cfg.Handler)
|
||||
vhsRouter := newDomainRouter(cfg.Handler)
|
||||
router := newGlobalRouter(defaultRouter, vhsRouter)
|
||||
|
||||
api.Mount("/", router)
|
||||
|
@ -169,12 +169,43 @@ func NewRouter(cfg Config) *chi.Mux {
|
|||
return api
|
||||
}
|
||||
|
||||
type globalRouter struct {
|
||||
pathStyleRouter chi.Router
|
||||
vhsRouter chi.Router
|
||||
type domainRouter struct {
|
||||
bucketRouter chi.Router
|
||||
defaultRouter chi.Router
|
||||
}
|
||||
|
||||
func newGlobalRouter(pathStyleRouter, vhsRouter chi.Router) *globalRouter {
|
||||
func newDomainRouter(handler Handler) *domainRouter {
|
||||
defaultRouter := chi.NewRouter()
|
||||
defaultRouter.Group(func(r chi.Router) {
|
||||
r.Method(http.MethodGet, "/", NewHandlerFilter().
|
||||
Add(NewFilter().
|
||||
AllowedQueries(s3middleware.QueryMaxBuckets, s3middleware.QueryPrefix,
|
||||
s3middleware.QueryContinuationToken, s3middleware.QueryBucketRegion).
|
||||
Handler(named(s3middleware.ListBucketsOperation, handler.ListBucketsHandler))).
|
||||
DefaultHandler(notSupportedHandler()))
|
||||
})
|
||||
attachErrorHandler(defaultRouter)
|
||||
|
||||
return &domainRouter{
|
||||
bucketRouter: bucketRouter(handler),
|
||||
defaultRouter: defaultRouter,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *domainRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if reqInfo := s3middleware.GetReqInfo(r.Context()); reqInfo.BucketName != "" {
|
||||
g.bucketRouter.ServeHTTP(w, r)
|
||||
} else {
|
||||
g.defaultRouter.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
type globalRouter struct {
|
||||
pathStyleRouter chi.Router
|
||||
vhsRouter *domainRouter
|
||||
}
|
||||
|
||||
func newGlobalRouter(pathStyleRouter chi.Router, vhsRouter *domainRouter) *globalRouter {
|
||||
return &globalRouter{
|
||||
pathStyleRouter: pathStyleRouter,
|
||||
vhsRouter: vhsRouter,
|
||||
|
@ -182,12 +213,11 @@ func newGlobalRouter(pathStyleRouter, vhsRouter chi.Router) *globalRouter {
|
|||
}
|
||||
|
||||
func (g *globalRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
router := g.pathStyleRouter
|
||||
if reqInfo := s3middleware.GetReqInfo(r.Context()); reqInfo.RequestVHSEnabled {
|
||||
router = g.vhsRouter
|
||||
g.vhsRouter.ServeHTTP(w, r)
|
||||
} else {
|
||||
g.pathStyleRouter.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
router.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func named(name string, handlerFunc http.HandlerFunc) http.HandlerFunc {
|
||||
|
@ -338,9 +368,6 @@ func bucketRouter(h Handler) chi.Router {
|
|||
AllowedQueries(s3middleware.QueryDelimiter, s3middleware.QueryMaxKeys, s3middleware.QueryPrefix,
|
||||
s3middleware.QueryMarker, s3middleware.QueryEncodingType).
|
||||
Handler(named(s3middleware.ListObjectsV1Operation, h.ListObjectsV1Handler))).
|
||||
Add(NewFilter().
|
||||
NoQueries().
|
||||
Handler(listWrapper(h))).
|
||||
DefaultHandler(notSupportedHandler()))
|
||||
})
|
||||
|
||||
|
@ -422,18 +449,6 @@ func bucketRouter(h Handler) chi.Router {
|
|||
return bktRouter
|
||||
}
|
||||
|
||||
func listWrapper(h Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if reqInfo := s3middleware.GetReqInfo(r.Context()); reqInfo.BucketName == "" {
|
||||
reqInfo.API = s3middleware.ListBucketsOperation
|
||||
h.ListBucketsHandler(w, r)
|
||||
} else {
|
||||
reqInfo.API = s3middleware.ListObjectsV1Operation
|
||||
h.ListObjectsV1Handler(w, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func objectRouter(h Handler) chi.Router {
|
||||
objRouter := chi.NewRouter()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue