diff --git a/weed/s3api/cors/middleware.go b/weed/s3api/cors/middleware.go index fca3f97e4..7aa40e84f 100644 --- a/weed/s3api/cors/middleware.go +++ b/weed/s3api/cors/middleware.go @@ -43,15 +43,15 @@ func (m *Middleware) getCORSConfig(bucket string) (*CORSConfiguration, bool) { switch errCode { case s3err.ErrNone: - // Found a config, use it if config != nil { + // Found a bucket-specific config, use it. return config, true } - // ErrNone with nil config means no bucket-level config, fall through to fallback + // No bucket config, proceed to fallback. case s3err.ErrNoSuchCORSConfiguration: - // Explicitly no CORS config, fall through to fallback + // No bucket config, proceed to fallback. default: - // Real error (access denied, network failure, etc.) - do not fall back + // Any other error means we should not proceed. return nil, false } diff --git a/weed/s3api/s3api_bucket_cors_handlers.go b/weed/s3api/s3api_bucket_cors_handlers.go index 6ab9693eb..c45f86014 100644 --- a/weed/s3api/s3api_bucket_cors_handlers.go +++ b/weed/s3api/s3api_bucket_cors_handlers.go @@ -10,6 +10,19 @@ import ( "github.com/seaweedfs/seaweedfs/weed/s3api/s3err" ) +// Default CORS configuration for global fallback +var ( + defaultFallbackAllowedMethods = []string{"GET", "PUT", "POST", "DELETE", "HEAD"} + defaultFallbackExposeHeaders = []string{ + "ETag", + "Content-Length", + "Content-Type", + "Last-Modified", + "x-amz-request-id", + "x-amz-version-id", + } +) + // S3BucketChecker implements cors.BucketChecker interface type S3BucketChecker struct { server *S3ApiServer @@ -45,24 +58,13 @@ func (s3a *S3ApiServer) createFallbackCORSConfig() *cors.CORSConfiguration { return nil } - // Default methods and headers for the fallback configuration - fallbackAllowedMethods := []string{"GET", "PUT", "POST", "DELETE", "HEAD"} - fallbackExposeHeaders := []string{ - "ETag", - "Content-Length", - "Content-Type", - "Last-Modified", - "x-amz-request-id", - "x-amz-version-id", - } - // Create a permissive CORS rule based on global allowed origins // This matches the behavior of handleCORSOriginValidation rule := cors.CORSRule{ AllowedOrigins: s3a.option.AllowedOrigins, - AllowedMethods: fallbackAllowedMethods, + AllowedMethods: defaultFallbackAllowedMethods, AllowedHeaders: []string{"*"}, - ExposeHeaders: fallbackExposeHeaders, + ExposeHeaders: defaultFallbackExposeHeaders, MaxAgeSeconds: nil, // No max age by default }