refactor: serve non-resident buckets with the global CORS policy

The pre-authentication CORS lookup stays resident-only, so client-supplied
path segments still cause no metadata I/O and no cache growth. The
fail-closed states for startup, load failures, and the internal namespace
are gone: CORS is a browser response policy rather than an authorization
boundary, and failing closed only denied browser clients CORS headers while
bucket metadata was still loading. A bucket whose stored CORS document does
not parse still gets no CORS headers. This removes the loadFailed bookkeeping
and the unused GetCorsConfig, HasAllowedOrigin, and generic Update path for
CORS; tests use the CORS-specific writer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PvgysXDmhPBBimCReYtA8q
Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-09-02 14:06:56 +08:00
parent 3b5de82f5a
commit 632eb4729a
6 changed files with 42 additions and 227 deletions
+5 -5
View File
@@ -85,7 +85,7 @@ func testPeerBucketCorsReplicationOrdering(_ ObjectLayer, _ string, bucket strin
if !meta.CorsConfigUpdatedAt.Equal(putAt) {
t.Fatalf("peer PUT timestamp = %v, want source time %v", meta.CorsConfigUpdatedAt, putAt)
}
cfg, cfgAt, err := globalBucketMetadataSys.GetCorsConfig(bucket)
cfg, cfgAt, err := globalBucketMetadataSys.GetResidentCorsConfig(bucket)
if err != nil {
t.Fatalf("peer PUT stored raw XML but no parsed config: %v", err)
}
@@ -165,10 +165,10 @@ func TestSiteReplicationMetaInfoPreservesCorsTombstone(t *testing.T) {
func testSiteReplicationMetaInfoPreservesCorsTombstone(obj ObjectLayer, _ string, bucket string, _ http.Handler, _ auth.Credentials, t *testing.T) {
ctx := t.Context()
if _, err := globalBucketMetadataSys.Update(ctx, bucket, bucketCorsConfig, []byte(testSiteReplicationCORSDoc)); err != nil {
if _, err := updateLocalBucketCORSMetadata(ctx, obj, bucket, []byte(testSiteReplicationCORSDoc)); err != nil {
t.Fatal(err)
}
deleteAt, err := globalBucketMetadataSys.Delete(ctx, bucket, bucketCorsConfig)
deleteAt, err := updateLocalBucketCORSMetadata(ctx, obj, bucket, nil)
if err != nil {
t.Fatal(err)
}
@@ -918,8 +918,8 @@ func testLegacyInvalidCorsMetadataCanBeDeleted(obj ObjectLayer, _ string, bucket
t.Fatalf("legacy CORS state = (%#v, %v), want fail-closed parse error", loaded.corsConfig, loaded.corsConfigErr)
}
globalBucketMetadataSys.Set(bucket, loaded)
if _, gotAt, err := globalBucketMetadataSys.GetCorsConfig(bucket); err == nil || !gotAt.Equal(legacyAt) {
t.Fatalf("GetCorsConfig = timestamp %v, error %v; want legacy timestamp and error", gotAt, err)
if _, gotAt, err := globalBucketMetadataSys.GetResidentCorsConfig(bucket); err == nil || !gotAt.Equal(legacyAt) {
t.Fatalf("GetResidentCorsConfig = timestamp %v, error %v; want legacy timestamp and error", gotAt, err)
}
if _, gotAt, err := globalBucketMetadataSys.GetCorsConfigXML(bucket); err == nil || !gotAt.Equal(legacyAt) {
t.Fatalf("GetCorsConfigXML = timestamp %v, error %v; want legacy timestamp and error", gotAt, err)