@ -393,6 +393,9 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) {
apiRouter . Methods ( http . MethodGet ) . Path ( "/status" ) . HandlerFunc ( s3a . StatusHandler )
apiRouter . Methods ( http . MethodGet ) . Path ( "/status" ) . HandlerFunc ( s3a . StatusHandler )
apiRouter . Methods ( http . MethodGet ) . Path ( "/healthz" ) . HandlerFunc ( s3a . StatusHandler )
apiRouter . Methods ( http . MethodGet ) . Path ( "/healthz" ) . HandlerFunc ( s3a . StatusHandler )
// Object path pattern with (?s) flag to match newlines in object keys
const objectPath = "/{object:(?s).+}"
var routers [ ] * mux . Router
var routers [ ] * mux . Router
if s3a . option . DomainName != "" {
if s3a . option . DomainName != "" {
domainNames := strings . Split ( s3a . option . DomainName , "," )
domainNames := strings . Split ( s3a . option . DomainName , "," )
@ -431,63 +434,63 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) {
// objects with query
// objects with query
// CopyObjectPart
// CopyObjectPart
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HeadersRegexp ( "X-Amz-Copy-Source" , ` .*?(\/|%2F).*? ` ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . CopyObjectPartHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "partNumber" , "{partNumber:[0-9]+}" , "uploadId" , "{uploadId:.*}" )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HeadersRegexp ( "X-Amz-Copy-Source" , ` .*?(\/|%2F).*? ` ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . CopyObjectPartHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "partNumber" , "{partNumber:[0-9]+}" , "uploadId" , "{uploadId:.*}" )
// PutObjectPart
// PutObjectPart
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectPartHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "partNumber" , "{partNumber:[0-9]+}" , "uploadId" , "{uploadId:.*}" )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectPartHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "partNumber" , "{partNumber:[0-9]+}" , "uploadId" , "{uploadId:.*}" )
// CompleteMultipartUpload
// CompleteMultipartUpload
bucket . Methods ( http . MethodPost ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . CompleteMultipartUploadHandler , ACTION_WRITE ) ) , "POST" ) ) . Queries ( "uploadId" , "{uploadId:.*}" )
bucket . Methods ( http . MethodPost ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . CompleteMultipartUploadHandler , ACTION_WRITE ) ) , "POST" ) ) . Queries ( "uploadId" , "{uploadId:.*}" )
// NewMultipartUpload
// NewMultipartUpload
bucket . Methods ( http . MethodPost ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . NewMultipartUploadHandler , ACTION_WRITE ) ) , "POST" ) ) . Queries ( "uploads" , "" )
bucket . Methods ( http . MethodPost ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . NewMultipartUploadHandler , ACTION_WRITE ) ) , "POST" ) ) . Queries ( "uploads" , "" )
// AbortMultipartUpload
// AbortMultipartUpload
bucket . Methods ( http . MethodDelete ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . AbortMultipartUploadHandler , ACTION_WRITE ) ) , "DELETE" ) ) . Queries ( "uploadId" , "{uploadId:.*}" )
bucket . Methods ( http . MethodDelete ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . AbortMultipartUploadHandler , ACTION_WRITE ) ) , "DELETE" ) ) . Queries ( "uploadId" , "{uploadId:.*}" )
// ListObjectParts
// ListObjectParts
bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . ListObjectPartsHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "uploadId" , "{uploadId:.*}" )
bucket . Methods ( http . MethodGet ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . ListObjectPartsHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "uploadId" , "{uploadId:.*}" )
// ListMultipartUploads
// ListMultipartUploads
bucket . Methods ( http . MethodGet ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . ListMultipartUploadsHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "uploads" , "" )
bucket . Methods ( http . MethodGet ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . ListMultipartUploadsHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "uploads" , "" )
// GetObjectTagging
// GetObjectTagging
bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectTaggingHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "tagging" , "" )
bucket . Methods ( http . MethodGet ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectTaggingHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "tagging" , "" )
// PutObjectTagging
// PutObjectTagging
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectTaggingHandler , ACTION_TAGGING ) ) , "PUT" ) ) . Queries ( "tagging" , "" )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectTaggingHandler , ACTION_TAGGING ) ) , "PUT" ) ) . Queries ( "tagging" , "" )
// DeleteObjectTagging
// DeleteObjectTagging
bucket . Methods ( http . MethodDelete ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . DeleteObjectTaggingHandler , ACTION_TAGGING ) ) , "DELETE" ) ) . Queries ( "tagging" , "" )
bucket . Methods ( http . MethodDelete ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . DeleteObjectTaggingHandler , ACTION_TAGGING ) ) , "DELETE" ) ) . Queries ( "tagging" , "" )
// PutObjectACL
// PutObjectACL
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectAclHandler , ACTION_WRITE_ACP ) ) , "PUT" ) ) . Queries ( "acl" , "" )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectAclHandler , ACTION_WRITE_ACP ) ) , "PUT" ) ) . Queries ( "acl" , "" )
// PutObjectRetention
// PutObjectRetention
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectRetentionHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "retention" , "" )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectRetentionHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "retention" , "" )
// PutObjectLegalHold
// PutObjectLegalHold
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectLegalHoldHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "legal-hold" , "" )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectLegalHoldHandler , ACTION_WRITE ) ) , "PUT" ) ) . Queries ( "legal-hold" , "" )
// GetObjectACL
// GetObjectACL
bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectAclHandler , ACTION_READ_ACP ) ) , "GET" ) ) . Queries ( "acl" , "" )
bucket . Methods ( http . MethodGet ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectAclHandler , ACTION_READ_ACP ) ) , "GET" ) ) . Queries ( "acl" , "" )
// GetObjectRetention
// GetObjectRetention
bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectRetentionHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "retention" , "" )
bucket . Methods ( http . MethodGet ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectRetentionHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "retention" , "" )
// GetObjectLegalHold
// GetObjectLegalHold
bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectLegalHoldHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "legal-hold" , "" )
bucket . Methods ( http . MethodGet ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . GetObjectLegalHoldHandler , ACTION_READ ) ) , "GET" ) ) . Queries ( "legal-hold" , "" )
// objects with query
// objects with query
// raw objects
// raw objects
// HeadObject
// HeadObject
bucket . Methods ( http . MethodHead ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . AuthWithPublicRead ( func ( w http . ResponseWriter , r * http . Request ) {
bucket . Methods ( http . MethodHead ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . AuthWithPublicRead ( func ( w http . ResponseWriter , r * http . Request ) {
limitedHandler , _ := s3a . cb . Limit ( s3a . HeadObjectHandler , ACTION_READ )
limitedHandler , _ := s3a . cb . Limit ( s3a . HeadObjectHandler , ACTION_READ )
limitedHandler ( w , r )
limitedHandler ( w , r )
} , ACTION_READ ) , "GET" ) )
} , ACTION_READ ) , "GET" ) )
// GetObject, but directory listing is not supported
// GetObject, but directory listing is not supported
bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . AuthWithPublicRead ( func ( w http . ResponseWriter , r * http . Request ) {
bucket . Methods ( http . MethodGet ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . AuthWithPublicRead ( func ( w http . ResponseWriter , r * http . Request ) {
limitedHandler , _ := s3a . cb . Limit ( s3a . GetObjectHandler , ACTION_READ )
limitedHandler , _ := s3a . cb . Limit ( s3a . GetObjectHandler , ACTION_READ )
limitedHandler ( w , r )
limitedHandler ( w , r )
} , ACTION_READ ) , "GET" ) )
} , ACTION_READ ) , "GET" ) )
// CopyObject
// CopyObject
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HeadersRegexp ( "X-Amz-Copy-Source" , ".*?(\\/|%2F).*?" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . CopyObjectHandler , ACTION_WRITE ) ) , "COPY" ) )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HeadersRegexp ( "X-Amz-Copy-Source" , ".*?(\\/|%2F).*?" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . CopyObjectHandler , ACTION_WRITE ) ) , "COPY" ) )
// PutObject
// PutObject
bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectHandler , ACTION_WRITE ) ) , "PUT" ) )
bucket . Methods ( http . MethodPut ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . PutObjectHandler , ACTION_WRITE ) ) , "PUT" ) )
// DeleteObject
// DeleteObject
bucket . Methods ( http . MethodDelete ) . Path ( "/{object:.+}" ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . DeleteObjectHandler , ACTION_WRITE ) ) , "DELETE" ) )
bucket . Methods ( http . MethodDelete ) . Path ( objectPath ) . HandlerFunc ( track ( s3a . iam . Auth ( s3a . cb . Limit ( s3a . DeleteObjectHandler , ACTION_WRITE ) ) , "DELETE" ) )
// raw objects
// raw objects