diff --git a/.gitignore b/.gitignore index 18fd1e0..6f73efc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ release/ # VS Code .vscode/ +/gateway diff --git a/api/api.go b/api/api.go index cf7bc84..fa8479e 100644 --- a/api/api.go +++ b/api/api.go @@ -48,6 +48,12 @@ type API struct { config Config } +// BucketLocationGetter is an interface for getting bucket location. +// This is implemented by the gateway layer to fetch bucket region/location. +type BucketLocationGetter interface { + GetBucketLocation(ctx context.Context, bucketName string) (string, error) +} + // New constructs a new S3-compatible HTTP API. func New(objectAPI cmd.ObjectLayer, credsProvider awsig.CredentialsProvider[AuthData], config Config) *API { v2v4 := awsig.NewV2V4(credsProvider, awsig.V4Config{ diff --git a/api/buckethandlers.go b/api/buckethandlers.go index fff521b..4d9ccbf 100644 --- a/api/buckethandlers.go +++ b/api/buckethandlers.go @@ -302,9 +302,24 @@ func (api *API) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { return } - if _, err := api.objectAPI.GetBucketInfo(ctx, bucketName); err != nil { - writeErrorResponseHeadersOnly(w, cmd.ToAPIError(ctx, err)) - return + // TODO: Add GetBucketLocation to the object layer interface in storj/minio + // instead of using type assertion. This would allow us to make a single call + // instead of two separate calls (GetBucketInfo + GetBucketLocation). + if locationGetter, ok := api.objectAPI.(BucketLocationGetter); ok { + location, err := locationGetter.GetBucketLocation(ctx, bucketName) + if err != nil { + writeErrorResponseHeadersOnly(w, cmd.ToAPIError(ctx, err)) + return + } + if location != "" { + w.Header().Set(xhttp.AmzBucketRegion, location) + } + } else { + // Fallback to GetBucketInfo if GetBucketLocation is not available + if _, err := api.objectAPI.GetBucketInfo(ctx, bucketName); err != nil { + writeErrorResponseHeadersOnly(w, cmd.ToAPIError(ctx, err)) + return + } } writeSuccessResponseHeadersOnly(w) diff --git a/miniogw/gateway.go b/miniogw/gateway.go index cccc98a..bf7207d 100644 --- a/miniogw/gateway.go +++ b/miniogw/gateway.go @@ -346,6 +346,27 @@ func (layer *gatewayLayer) GetBucketInfo(ctx context.Context, bucketName string) }, nil } +// GetBucketLocation returns the location/region of a bucket. +func (layer *gatewayLayer) GetBucketLocation(ctx context.Context, bucketName string) (location string, err error) { + defer mon.Task()(&ctx)(&err) + + if err := ValidateBucket(ctx, bucketName); err != nil { + return "", minio.BucketNameInvalid{Bucket: bucketName} + } + + project, err := projectFromContext(ctx, bucketName, "") + if err != nil { + return "", err + } + + location, err = bucket.GetBucketLocation(ctx, project, bucketName) + if err != nil { + return "", ConvertError(err, bucketName, "") + } + + return location, nil +} + func (layer *gatewayLayer) ListBuckets(ctx context.Context) (items []minio.BucketInfo, err error) { defer mon.Task()(&ctx)(&err)