2020-07-22 13:02:32 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2020-08-11 11:30:02 +00:00
|
|
|
"context"
|
2023-07-05 14:05:45 +00:00
|
|
|
"fmt"
|
2020-07-22 13:02:32 +00:00
|
|
|
"net/http"
|
|
|
|
|
2023-03-07 14:38:08 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
|
2023-07-05 14:05:45 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
|
|
|
|
s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
|
2023-08-23 11:07:52 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
2023-04-07 14:28:21 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics"
|
2024-03-01 14:07:08 +00:00
|
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
2023-11-30 08:28:29 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
2023-07-05 14:05:45 +00:00
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"github.com/go-chi/chi/v5/middleware"
|
2020-07-22 19:48:34 +00:00
|
|
|
"go.uber.org/zap"
|
2020-07-22 13:02:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
2021-05-13 20:25:31 +00:00
|
|
|
// Handler is an S3 API handler interface.
|
2020-07-22 13:02:32 +00:00
|
|
|
Handler interface {
|
|
|
|
HeadObjectHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetObjectACLHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutObjectACLHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetObjectTaggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutObjectTaggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteObjectTaggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
SelectObjectContentHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetObjectRetentionHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetObjectLegalHoldHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetObjectHandler(http.ResponseWriter, *http.Request)
|
2022-05-12 21:15:08 +00:00
|
|
|
GetObjectAttributesHandler(http.ResponseWriter, *http.Request)
|
2020-07-22 13:02:32 +00:00
|
|
|
CopyObjectHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutObjectRetentionHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutObjectLegalHoldHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutObjectHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteObjectHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketLocationHandler(http.ResponseWriter, *http.Request)
|
2024-03-05 06:56:12 +00:00
|
|
|
GetBucketPolicyStatusHandler(http.ResponseWriter, *http.Request)
|
2020-07-22 13:02:32 +00:00
|
|
|
GetBucketPolicyHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketLifecycleHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketEncryptionHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketACLHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketACLHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketCorsHandler(http.ResponseWriter, *http.Request)
|
2021-10-04 14:32:35 +00:00
|
|
|
PutBucketCorsHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketCorsHandler(http.ResponseWriter, *http.Request)
|
2020-07-22 13:02:32 +00:00
|
|
|
GetBucketWebsiteHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketAccelerateHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketRequestPaymentHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketLoggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketReplicationHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketTaggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketWebsiteHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketTaggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketObjectLockConfigHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketVersioningHandler(http.ResponseWriter, *http.Request)
|
|
|
|
GetBucketNotificationHandler(http.ResponseWriter, *http.Request)
|
|
|
|
ListenBucketNotificationHandler(http.ResponseWriter, *http.Request)
|
|
|
|
ListObjectsV2MHandler(http.ResponseWriter, *http.Request)
|
|
|
|
ListObjectsV2Handler(http.ResponseWriter, *http.Request)
|
|
|
|
ListBucketObjectVersionsHandler(http.ResponseWriter, *http.Request)
|
|
|
|
ListObjectsV1Handler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketLifecycleHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketEncryptionHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketPolicyHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketObjectLockConfigHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketTaggingHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketVersioningHandler(http.ResponseWriter, *http.Request)
|
|
|
|
PutBucketNotificationHandler(http.ResponseWriter, *http.Request)
|
2021-06-23 20:21:15 +00:00
|
|
|
CreateBucketHandler(http.ResponseWriter, *http.Request)
|
2020-07-22 13:02:32 +00:00
|
|
|
HeadBucketHandler(http.ResponseWriter, *http.Request)
|
2021-08-30 19:44:53 +00:00
|
|
|
PostObject(http.ResponseWriter, *http.Request)
|
2020-07-22 13:02:32 +00:00
|
|
|
DeleteMultipleObjectsHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketPolicyHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketLifecycleHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketEncryptionHandler(http.ResponseWriter, *http.Request)
|
|
|
|
DeleteBucketHandler(http.ResponseWriter, *http.Request)
|
|
|
|
ListBucketsHandler(http.ResponseWriter, *http.Request)
|
2021-10-04 14:32:35 +00:00
|
|
|
Preflight(w http.ResponseWriter, r *http.Request)
|
|
|
|
AppendCORSHeaders(w http.ResponseWriter, r *http.Request)
|
2021-11-25 15:05:58 +00:00
|
|
|
CreateMultipartUploadHandler(http.ResponseWriter, *http.Request)
|
|
|
|
UploadPartHandler(http.ResponseWriter, *http.Request)
|
|
|
|
UploadPartCopy(w http.ResponseWriter, r *http.Request)
|
|
|
|
CompleteMultipartUploadHandler(http.ResponseWriter, *http.Request)
|
|
|
|
AbortMultipartUploadHandler(http.ResponseWriter, *http.Request)
|
|
|
|
ListPartsHandler(w http.ResponseWriter, r *http.Request)
|
|
|
|
ListMultipartUploadsHandler(http.ResponseWriter, *http.Request)
|
2024-08-13 15:21:16 +00:00
|
|
|
PatchObjectHandler(http.ResponseWriter, *http.Request)
|
2022-12-23 12:28:30 +00:00
|
|
|
|
|
|
|
ResolveBucket(ctx context.Context, bucket string) (*data.BucketInfo, error)
|
2024-03-01 14:07:08 +00:00
|
|
|
ResolveCID(ctx context.Context, bucket string) (cid.ID, error)
|
2020-07-22 13:02:32 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2023-11-30 08:25:05 +00:00
|
|
|
type Settings interface {
|
|
|
|
s3middleware.RequestSettings
|
|
|
|
s3middleware.PolicySettings
|
|
|
|
s3middleware.MetricsSettings
|
2024-07-31 06:45:46 +00:00
|
|
|
s3middleware.VHSSettings
|
2024-07-12 12:31:43 +00:00
|
|
|
s3middleware.LogHTTPSettings
|
2023-11-30 08:25:05 +00:00
|
|
|
}
|
|
|
|
|
2023-12-13 14:44:18 +00:00
|
|
|
type FrostFSID interface {
|
|
|
|
s3middleware.FrostFSIDValidator
|
|
|
|
s3middleware.FrostFSIDInformer
|
|
|
|
}
|
|
|
|
|
2023-10-05 13:25:25 +00:00
|
|
|
type Config struct {
|
|
|
|
Throttle middleware.ThrottleOpts
|
|
|
|
Handler Handler
|
|
|
|
Center s3middleware.Center
|
|
|
|
Log *zap.Logger
|
|
|
|
Metrics *metrics.AppMetrics
|
|
|
|
|
2023-11-30 08:25:05 +00:00
|
|
|
MiddlewareSettings Settings
|
2023-12-01 11:16:19 +00:00
|
|
|
|
2023-12-13 14:44:18 +00:00
|
|
|
FrostfsID FrostFSID
|
|
|
|
|
|
|
|
FrostFSIDValidation bool
|
2023-11-30 08:25:05 +00:00
|
|
|
|
2023-12-08 07:44:13 +00:00
|
|
|
PolicyChecker engine.ChainRouter
|
2024-04-10 06:41:07 +00:00
|
|
|
|
|
|
|
XMLDecoder s3middleware.XMLDecoder
|
|
|
|
Tagging s3middleware.ResourceTagging
|
2023-10-05 13:25:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewRouter(cfg Config) *chi.Mux {
|
|
|
|
api := chi.NewRouter()
|
2024-07-12 12:31:43 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
api.Use(
|
2024-07-12 12:31:43 +00:00
|
|
|
s3middleware.LogHTTP(cfg.Log, cfg.MiddlewareSettings),
|
2023-11-30 08:25:05 +00:00
|
|
|
s3middleware.Request(cfg.Log, cfg.MiddlewareSettings),
|
2023-10-05 13:25:25 +00:00
|
|
|
middleware.ThrottleWithOpts(cfg.Throttle),
|
2023-07-05 14:05:45 +00:00
|
|
|
middleware.Recoverer,
|
2024-03-01 14:07:08 +00:00
|
|
|
s3middleware.Metrics(cfg.Log, cfg.Handler.ResolveCID, cfg.Metrics, cfg.MiddlewareSettings),
|
2023-10-05 13:25:25 +00:00
|
|
|
s3middleware.LogSuccessResponse(cfg.Log),
|
|
|
|
s3middleware.Auth(cfg.Center, cfg.Log),
|
2023-07-05 14:05:45 +00:00
|
|
|
)
|
2021-10-04 14:32:35 +00:00
|
|
|
|
2023-12-13 14:44:18 +00:00
|
|
|
if cfg.FrostFSIDValidation {
|
2023-10-05 13:25:25 +00:00
|
|
|
api.Use(s3middleware.FrostfsIDValidation(cfg.FrostfsID, cfg.Log))
|
|
|
|
}
|
|
|
|
|
2024-07-31 06:45:46 +00:00
|
|
|
api.Use(s3middleware.PrepareAddressStyle(cfg.MiddlewareSettings, cfg.Log))
|
2024-02-27 09:45:37 +00:00
|
|
|
api.Use(s3middleware.PolicyCheck(s3middleware.PolicyConfig{
|
|
|
|
Storage: cfg.PolicyChecker,
|
|
|
|
FrostfsID: cfg.FrostfsID,
|
|
|
|
Settings: cfg.MiddlewareSettings,
|
|
|
|
Log: cfg.Log,
|
|
|
|
BucketResolver: cfg.Handler.ResolveBucket,
|
2024-04-10 06:41:07 +00:00
|
|
|
Decoder: cfg.XMLDecoder,
|
|
|
|
Tagging: cfg.Tagging,
|
2024-02-27 09:45:37 +00:00
|
|
|
}))
|
2023-11-30 08:25:05 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
defaultRouter := chi.NewRouter()
|
2024-07-31 06:45:46 +00:00
|
|
|
defaultRouter.Mount("/{bucket}", bucketRouter(cfg.Handler))
|
|
|
|
defaultRouter.Get("/", named(s3middleware.ListBucketsOperation, cfg.Handler.ListBucketsHandler))
|
2024-02-21 14:32:58 +00:00
|
|
|
attachErrorHandler(defaultRouter)
|
2022-12-23 12:28:30 +00:00
|
|
|
|
2024-07-31 06:45:46 +00:00
|
|
|
vhsRouter := bucketRouter(cfg.Handler)
|
|
|
|
router := newGlobalRouter(defaultRouter, vhsRouter)
|
|
|
|
|
|
|
|
api.Mount("/", router)
|
2022-12-23 12:28:30 +00:00
|
|
|
|
2023-07-19 14:55:00 +00:00
|
|
|
attachErrorHandler(api)
|
2023-10-05 13:25:25 +00:00
|
|
|
|
|
|
|
return api
|
2022-12-23 12:28:30 +00:00
|
|
|
}
|
|
|
|
|
2024-07-31 06:45:46 +00:00
|
|
|
type globalRouter struct {
|
|
|
|
pathStyleRouter chi.Router
|
|
|
|
vhsRouter chi.Router
|
|
|
|
}
|
|
|
|
|
|
|
|
func newGlobalRouter(pathStyleRouter, vhsRouter chi.Router) *globalRouter {
|
|
|
|
return &globalRouter{
|
|
|
|
pathStyleRouter: pathStyleRouter,
|
|
|
|
vhsRouter: vhsRouter,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *globalRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
router := g.pathStyleRouter
|
|
|
|
if reqInfo := s3middleware.GetReqInfo(r.Context()); reqInfo.RequestVHSEnabled {
|
|
|
|
router = g.vhsRouter
|
|
|
|
}
|
|
|
|
|
|
|
|
router.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
func named(name string, handlerFunc http.HandlerFunc) http.HandlerFunc {
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
reqInfo := s3middleware.GetReqInfo(r.Context())
|
|
|
|
reqInfo.API = name
|
|
|
|
handlerFunc.ServeHTTP(w, r)
|
2020-08-19 23:28:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// If none of the http routes match respond with appropriate errors.
|
|
|
|
func errorResponseHandler(w http.ResponseWriter, r *http.Request) {
|
2023-07-19 14:55:00 +00:00
|
|
|
ctx := r.Context()
|
|
|
|
reqInfo := s3middleware.GetReqInfo(ctx)
|
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
desc := fmt.Sprintf("Unknown API request at %s", r.URL.Path)
|
2024-03-04 12:53:00 +00:00
|
|
|
_, wrErr := s3middleware.WriteErrorResponse(w, reqInfo, errors.Error{
|
2023-07-05 14:05:45 +00:00
|
|
|
Code: "UnknownAPIRequest",
|
|
|
|
Description: desc,
|
|
|
|
HTTPStatusCode: http.StatusBadRequest,
|
2022-12-27 12:30:11 +00:00
|
|
|
})
|
|
|
|
|
2023-07-19 14:55:00 +00:00
|
|
|
if log := s3middleware.GetReqLog(ctx); log != nil {
|
2024-03-04 12:53:00 +00:00
|
|
|
fields := []zap.Field{
|
|
|
|
zap.String("method", reqInfo.API),
|
|
|
|
zap.String("http method", r.Method),
|
|
|
|
zap.String("url", r.RequestURI),
|
|
|
|
}
|
|
|
|
|
|
|
|
if wrErr != nil {
|
|
|
|
fields = append(fields, zap.NamedError("write_response_error", wrErr))
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Error(logs.RequestUnmatched, fields...)
|
2022-12-27 12:30:11 +00:00
|
|
|
}
|
2023-07-19 14:55:00 +00:00
|
|
|
}
|
2022-12-27 12:30:11 +00:00
|
|
|
|
2024-10-01 14:43:55 +00:00
|
|
|
func notSupportedHandler() http.HandlerFunc {
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx := r.Context()
|
|
|
|
reqInfo := s3middleware.GetReqInfo(ctx)
|
|
|
|
|
|
|
|
_, wrErr := s3middleware.WriteErrorResponse(w, reqInfo, errors.GetAPIError(errors.ErrNotSupported))
|
|
|
|
|
|
|
|
if log := s3middleware.GetReqLog(ctx); log != nil {
|
|
|
|
fields := []zap.Field{
|
|
|
|
zap.String("http method", r.Method),
|
|
|
|
zap.String("url", r.RequestURI),
|
|
|
|
}
|
|
|
|
|
|
|
|
if wrErr != nil {
|
|
|
|
fields = append(fields, zap.NamedError("write_response_error", wrErr))
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Error(logs.NotSupported, fields...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-19 14:55:00 +00:00
|
|
|
// attachErrorHandler set NotFoundHandler and MethodNotAllowedHandler for chi.Router.
|
|
|
|
func attachErrorHandler(api *chi.Mux) {
|
|
|
|
errorHandler := http.HandlerFunc(errorResponseHandler)
|
2022-12-27 12:30:11 +00:00
|
|
|
|
|
|
|
// If none of the routes match, add default error handler routes
|
2023-07-19 14:55:00 +00:00
|
|
|
api.NotFound(named("NotFound", errorHandler))
|
|
|
|
api.MethodNotAllowed(named("MethodNotAllowed", errorHandler))
|
2022-12-27 12:30:11 +00:00
|
|
|
}
|
|
|
|
|
2024-07-31 06:45:46 +00:00
|
|
|
func bucketRouter(h Handler) chi.Router {
|
2023-07-05 14:05:45 +00:00
|
|
|
bktRouter := chi.NewRouter()
|
|
|
|
bktRouter.Use(
|
|
|
|
s3middleware.WrapHandler(h.AppendCORSHeaders),
|
2020-08-19 23:28:16 +00:00
|
|
|
)
|
2020-08-11 11:30:02 +00:00
|
|
|
|
2024-07-31 06:45:46 +00:00
|
|
|
bktRouter.Mount("/", objectRouter(h))
|
2023-07-05 14:05:45 +00:00
|
|
|
|
2024-05-31 13:55:37 +00:00
|
|
|
bktRouter.Options("/", named(s3middleware.OptionsBucketOperation, h.Preflight))
|
2023-07-05 14:05:45 +00:00
|
|
|
|
2023-11-30 08:28:29 +00:00
|
|
|
bktRouter.Head("/", named(s3middleware.HeadBucketOperation, h.HeadBucketHandler))
|
2023-07-05 14:05:45 +00:00
|
|
|
|
|
|
|
// GET method handlers
|
|
|
|
bktRouter.Group(func(r chi.Router) {
|
|
|
|
r.Method(http.MethodGet, "/", NewHandlerFilter().
|
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.UploadsQuery).
|
|
|
|
Handler(named(s3middleware.ListMultipartUploadsOperation, h.ListMultipartUploadsHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LocationQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketLocationOperation, h.GetBucketLocationHandler))).
|
2024-03-05 06:56:12 +00:00
|
|
|
Add(NewFilter().
|
|
|
|
Queries(s3middleware.PolicyStatusQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketPolicyStatusOperation, h.GetBucketPolicyStatusHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.PolicyQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketPolicyOperation, h.GetBucketPolicyHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LifecycleQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketLifecycleOperation, h.GetBucketLifecycleHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.EncryptionQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketEncryptionOperation, h.GetBucketEncryptionHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.CorsQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketCorsOperation, h.GetBucketCorsHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ACLQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketACLOperation, h.GetBucketACLHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.WebsiteQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketWebsiteOperation, h.GetBucketWebsiteHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.AccelerateQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketAccelerateOperation, h.GetBucketAccelerateHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.RequestPaymentQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketRequestPaymentOperation, h.GetBucketRequestPaymentHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LoggingQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketLoggingOperation, h.GetBucketLoggingHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ReplicationQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketReplicationOperation, h.GetBucketReplicationHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.TaggingQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketTaggingOperation, h.GetBucketTaggingHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ObjectLockQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketObjectLockConfigOperation, h.GetBucketObjectLockConfigHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.VersioningQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketVersioningOperation, h.GetBucketVersioningHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.NotificationQuery).
|
|
|
|
Handler(named(s3middleware.GetBucketNotificationOperation, h.GetBucketNotificationHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.EventsQuery).
|
|
|
|
Handler(named(s3middleware.ListenBucketNotificationOperation, h.ListenBucketNotificationHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
QueriesMatch(s3middleware.ListTypeQuery, "2", s3middleware.MetadataQuery, "true").
|
|
|
|
Handler(named(s3middleware.ListObjectsV2MOperation, h.ListObjectsV2MHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
QueriesMatch(s3middleware.ListTypeQuery, "2").
|
|
|
|
Handler(named(s3middleware.ListObjectsV2Operation, h.ListObjectsV2Handler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.VersionsQuery).
|
|
|
|
Handler(named(s3middleware.ListBucketObjectVersionsOperation, h.ListBucketObjectVersionsHandler))).
|
2024-10-01 14:43:55 +00:00
|
|
|
Add(NewFilter().
|
|
|
|
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()))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-07-22 13:02:32 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// PUT method handlers
|
|
|
|
bktRouter.Group(func(r chi.Router) {
|
|
|
|
r.Method(http.MethodPut, "/", NewHandlerFilter().
|
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.CorsQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketCorsOperation, h.PutBucketCorsHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ACLQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketACLOperation, h.PutBucketACLHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LifecycleQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketLifecycleOperation, h.PutBucketLifecycleHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.EncryptionQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketEncryptionOperation, h.PutBucketEncryptionHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.PolicyQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketPolicyOperation, h.PutBucketPolicyHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ObjectLockQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketObjectLockConfigOperation, h.PutBucketObjectLockConfigHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.TaggingQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketTaggingOperation, h.PutBucketTaggingHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.VersioningQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketVersioningOperation, h.PutBucketVersioningHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.NotificationQuery).
|
|
|
|
Handler(named(s3middleware.PutBucketNotificationOperation, h.PutBucketNotificationHandler))).
|
2024-10-01 14:43:55 +00:00
|
|
|
Add(NewFilter().
|
|
|
|
NoQueries().
|
|
|
|
Handler(named(s3middleware.CreateBucketOperation, h.CreateBucketHandler))).
|
|
|
|
DefaultHandler(notSupportedHandler()))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-12-10 15:13:28 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// POST method handlers
|
|
|
|
bktRouter.Group(func(r chi.Router) {
|
|
|
|
r.Method(http.MethodPost, "/", NewHandlerFilter().
|
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.DeleteQuery).
|
|
|
|
Handler(named(s3middleware.DeleteMultipleObjectsOperation, h.DeleteMultipleObjectsHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
// todo consider add filter to match header for defaultHandler: hdrContentType, "multipart/form-data*"
|
2023-11-30 08:28:29 +00:00
|
|
|
DefaultHandler(named(s3middleware.PostObjectOperation, h.PostObject)))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-12-10 15:13:28 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// DELETE method handlers
|
|
|
|
bktRouter.Group(func(r chi.Router) {
|
|
|
|
r.Method(http.MethodDelete, "/", NewHandlerFilter().
|
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.CorsQuery).
|
|
|
|
Handler(named(s3middleware.DeleteBucketCorsOperation, h.DeleteBucketCorsHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.WebsiteQuery).
|
|
|
|
Handler(named(s3middleware.DeleteBucketWebsiteOperation, h.DeleteBucketWebsiteHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.TaggingQuery).
|
|
|
|
Handler(named(s3middleware.DeleteBucketTaggingOperation, h.DeleteBucketTaggingHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.PolicyQuery).
|
2023-12-08 07:44:13 +00:00
|
|
|
Handler(named(s3middleware.DeleteBucketPolicyOperation, h.DeleteBucketPolicyHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LifecycleQuery).
|
2024-08-12 11:22:56 +00:00
|
|
|
Handler(named(s3middleware.DeleteBucketLifecycleOperation, h.DeleteBucketLifecycleHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.EncryptionQuery).
|
|
|
|
Handler(named(s3middleware.DeleteBucketEncryptionOperation, h.DeleteBucketEncryptionHandler))).
|
2024-10-01 14:43:55 +00:00
|
|
|
Add(NewFilter().
|
|
|
|
NoQueries().
|
|
|
|
Handler(named(s3middleware.DeleteBucketOperation, h.DeleteBucketHandler))).
|
|
|
|
DefaultHandler(notSupportedHandler()))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-12-10 15:13:28 +00:00
|
|
|
|
2023-07-19 14:55:00 +00:00
|
|
|
attachErrorHandler(bktRouter)
|
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
return bktRouter
|
|
|
|
}
|
2020-12-10 15:13:28 +00:00
|
|
|
|
2024-07-31 06:45:46 +00:00
|
|
|
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 {
|
2023-07-05 14:05:45 +00:00
|
|
|
objRouter := chi.NewRouter()
|
|
|
|
|
2024-05-31 13:55:37 +00:00
|
|
|
objRouter.Options("/*", named(s3middleware.OptionsObjectOperation, h.Preflight))
|
|
|
|
|
2023-11-30 08:28:29 +00:00
|
|
|
objRouter.Head("/*", named(s3middleware.HeadObjectOperation, h.HeadObjectHandler))
|
2023-07-05 14:05:45 +00:00
|
|
|
|
2024-08-13 15:21:16 +00:00
|
|
|
objRouter.Patch("/*", named(s3middleware.PatchObjectOperation, h.PatchObjectHandler))
|
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// GET method handlers
|
|
|
|
objRouter.Group(func(r chi.Router) {
|
2023-07-19 12:25:11 +00:00
|
|
|
r.Method(http.MethodGet, "/*", NewHandlerFilter().
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.UploadIDQuery).
|
|
|
|
Handler(named(s3middleware.ListPartsOperation, h.ListPartsHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ACLQuery).
|
|
|
|
Handler(named(s3middleware.GetObjectACLOperation, h.GetObjectACLHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.TaggingQuery).
|
|
|
|
Handler(named(s3middleware.GetObjectTaggingOperation, h.GetObjectTaggingHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.RetentionQuery).
|
|
|
|
Handler(named(s3middleware.GetObjectRetentionOperation, h.GetObjectRetentionHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LegalHoldQuery).
|
|
|
|
Handler(named(s3middleware.GetObjectLegalHoldOperation, h.GetObjectLegalHoldHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.AttributesQuery).
|
|
|
|
Handler(named(s3middleware.GetObjectAttributesOperation, h.GetObjectAttributesHandler))).
|
|
|
|
DefaultHandler(named(s3middleware.GetObjectOperation, h.GetObjectHandler)))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-12-10 15:13:28 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// PUT method handlers
|
|
|
|
objRouter.Group(func(r chi.Router) {
|
2023-07-19 12:25:11 +00:00
|
|
|
r.Method(http.MethodPut, "/*", NewHandlerFilter().
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
|
|
|
Headers(AmzCopySource).
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.PartNumberQuery, s3middleware.UploadIDQuery).
|
|
|
|
Handler(named(s3middleware.UploadPartCopyOperation, h.UploadPartCopy))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.PartNumberQuery, s3middleware.UploadIDQuery).
|
|
|
|
Handler(named(s3middleware.UploadPartOperation, h.UploadPartHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.ACLQuery).
|
|
|
|
Handler(named(s3middleware.PutObjectACLOperation, h.PutObjectACLHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.TaggingQuery).
|
|
|
|
Handler(named(s3middleware.PutObjectTaggingOperation, h.PutObjectTaggingHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
|
|
|
Headers(AmzCopySource).
|
2023-11-30 08:28:29 +00:00
|
|
|
Handler(named(s3middleware.CopyObjectOperation, h.CopyObjectHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.RetentionQuery).
|
|
|
|
Handler(named(s3middleware.PutObjectRetentionOperation, h.PutObjectRetentionHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.LegalHoldQuery).
|
|
|
|
Handler(named(s3middleware.PutObjectLegalHoldOperation, h.PutObjectLegalHoldHandler))).
|
|
|
|
DefaultHandler(named(s3middleware.PutObjectOperation, h.PutObjectHandler)))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-12-10 15:13:28 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// POST method handlers
|
|
|
|
objRouter.Group(func(r chi.Router) {
|
2023-07-19 12:25:11 +00:00
|
|
|
r.Method(http.MethodPost, "/*", NewHandlerFilter().
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.UploadIDQuery).
|
|
|
|
Handler(named(s3middleware.CompleteMultipartUploadOperation, h.CompleteMultipartUploadHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.UploadsQuery).
|
|
|
|
Handler(named(s3middleware.CreateMultipartUploadOperation, h.CreateMultipartUploadHandler))).
|
|
|
|
DefaultHandler(named(s3middleware.SelectObjectContentOperation, h.SelectObjectContentHandler)))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-07-22 13:02:32 +00:00
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
// DELETE method handlers
|
|
|
|
objRouter.Group(func(r chi.Router) {
|
2023-07-19 12:25:11 +00:00
|
|
|
r.Method(http.MethodDelete, "/*", NewHandlerFilter().
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.UploadIDQuery).
|
|
|
|
Handler(named(s3middleware.AbortMultipartUploadOperation, h.AbortMultipartUploadHandler))).
|
2023-07-05 14:05:45 +00:00
|
|
|
Add(NewFilter().
|
2023-11-30 08:28:29 +00:00
|
|
|
Queries(s3middleware.TaggingQuery).
|
|
|
|
Handler(named(s3middleware.DeleteObjectTaggingOperation, h.DeleteObjectTaggingHandler))).
|
|
|
|
DefaultHandler(named(s3middleware.DeleteObjectOperation, h.DeleteObjectHandler)))
|
2023-07-05 14:05:45 +00:00
|
|
|
})
|
2020-07-22 13:02:32 +00:00
|
|
|
|
2023-07-19 14:55:00 +00:00
|
|
|
attachErrorHandler(objRouter)
|
|
|
|
|
2023-07-05 14:05:45 +00:00
|
|
|
return objRouter
|
2020-07-22 13:02:32 +00:00
|
|
|
}
|