diff --git a/cmd/api-router.go b/cmd/api-router.go index b3cc17af8..63164a06c 100644 --- a/cmd/api-router.go +++ b/cmd/api-router.go @@ -785,23 +785,21 @@ func corsHandler(handler http.Handler) http.Handler { } globalCors := cors.New(opts).Handler(handler) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("Origin") == "" { - handler.ServeHTTP(w, r) - return - } - if bucket, _ := request2BucketObjectName(r); bucket != "" && globalBucketMetadataSys != nil { - cfg, _, err := globalBucketMetadataSys.GetCorsConfig(bucket) - if err == nil && cfg != nil { - if applyBucketCors(w, r, cfg) { + if r.Header.Get("Origin") != "" { + if bucket, _ := request2BucketObjectName(r); bucket != "" && globalBucketMetadataSys != nil { + cfg, _, err := globalBucketMetadataSys.GetCorsConfig(bucket) + if err == nil && cfg != nil { + if applyBucketCors(w, r, cfg) { + return + } + handler.ServeHTTP(w, r) + return + } + if err != nil && !errors.Is(err, errConfigNotFound) { + internalLogOnceIf(r.Context(), err, "bucket-cors-metadata") + handler.ServeHTTP(w, r) return } - handler.ServeHTTP(w, r) - return - } - if err != nil && !errors.Is(err, errConfigNotFound) && r.Header.Get("Origin") != "" { - internalLogOnceIf(r.Context(), err, "bucket-cors-metadata") - handler.ServeHTTP(w, r) - return } } globalCors.ServeHTTP(w, r) diff --git a/cmd/bucket-cors-middleware_test.go b/cmd/bucket-cors-middleware_test.go index cd14978a7..f168e0f31 100644 --- a/cmd/bucket-cors-middleware_test.go +++ b/cmd/bucket-cors-middleware_test.go @@ -313,11 +313,32 @@ func testBucketCorsSkipsMetadataLookupWithoutOrigin(obj ObjectLayer, _ string, _ if rec.Code != http.StatusNoContent { t.Fatalf("status = %d, want %d", rec.Code, http.StatusNoContent) } + requireCorsOriginVary(t, rec.Header()) if got := counting.getObjectNInfoCalls.Load(); got != 0 { t.Fatalf("request without Origin performed %d bucket metadata reads", got) } } +func TestBucketCorsOriginlessPreflightShapeUsesGlobalHandler(t *testing.T) { + nextCalled := false + wrapped := corsHandler(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + nextCalled = true + w.WriteHeader(http.StatusTeapot) + })) + rec := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodOptions, getGetObjectURL("", "api", "v1/login"), nil) + req.Header.Set("Access-Control-Request-Method", http.MethodGet) + wrapped.ServeHTTP(rec, req) + + if rec.Code != http.StatusNoContent { + t.Fatalf("status = %d, want %d", rec.Code, http.StatusNoContent) + } + if nextCalled { + t.Fatal("originless preflight-shaped OPTIONS reached the application handler") + } + requireCorsOriginVary(t, rec.Header()) +} + func TestBucketCorsNoConfigUsesGlobalFallback(t *testing.T) { ExecObjectLayerAPITest(ExecObjectLayerAPITestArgs{ t: t,