mirror of
https://github.com/pgsty/minio.git
synced 2026-09-26 04:45:59 +03:00
fix: complete bucket CORS protocol validation
Integrate the strict B3 XML, validation, checksum, wildcard, MaxAge, and Origin-null response contract with the C-prime site-replication register from #75. Preserve fail-closed metadata behavior and rejected-preflight cache variation while keeping legacy-invalid development metadata readable and repairable through a valid CORS PUT or DELETE. Add combined parser, handler, browser-response, namespace, replication, restart, and legacy-repair regressions, and update the internal design contract. Refs #75 Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -20,6 +20,7 @@ package cmd
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
@@ -750,6 +751,65 @@ func TestPeerBucketCorsCreatedAtFloor(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestLegacyInvalidCorsMetadataCanBeDeleted(t *testing.T) {
|
||||
ExecObjectLayerAPITest(ExecObjectLayerAPITestArgs{
|
||||
t: t,
|
||||
objAPITest: testLegacyInvalidCorsMetadataCanBeDeleted,
|
||||
endpoints: []string{"GetBucketCors"},
|
||||
})
|
||||
}
|
||||
|
||||
func testLegacyInvalidCorsMetadataCanBeDeleted(obj ObjectLayer, _ string, bucket string, _ http.Handler, _ auth.Credentials, t *testing.T) {
|
||||
ctx := t.Context()
|
||||
meta, err := readBucketMetadata(ctx, obj, bucket)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
legacyAt := meta.Created.Add(time.Second)
|
||||
meta.CorsConfigXML = []byte(`<CORSConfiguration><CORSRule><AllowedOrigin>https://app.example.com</AllowedOrigin><AllowedMethod>get</AllowedMethod></CORSRule></CORSConfiguration>`)
|
||||
meta.CorsConfigUpdatedAt = legacyAt
|
||||
|
||||
data := make([]byte, 4, meta.Msgsize()+4)
|
||||
binary.LittleEndian.PutUint16(data[0:2], bucketMetadataFormat)
|
||||
binary.LittleEndian.PutUint16(data[2:4], bucketMetadataVersion)
|
||||
data, err = meta.MarshalMsg(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = saveConfig(ctx, obj, pathJoin(bucketMetaPrefix, bucket, bucketMetadataFile), data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
globalBucketMetadataSys.Remove(bucket)
|
||||
loaded, err := globalBucketMetadataSys.GetConfigFromDisk(ctx, bucket)
|
||||
if err != nil {
|
||||
t.Fatalf("strict load made all bucket metadata unavailable: %v", err)
|
||||
}
|
||||
if loaded.corsConfigErr == nil || loaded.corsConfig != nil {
|
||||
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.GetCorsConfigXML(bucket); err == nil || !gotAt.Equal(legacyAt) {
|
||||
t.Fatalf("GetCorsConfigXML = timestamp %v, error %v; want legacy timestamp and error", gotAt, err)
|
||||
}
|
||||
|
||||
deleteAt, err := updateLocalBucketCORSMetadata(ctx, obj, bucket, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("DELETE could not repair legacy invalid CORS: %v", err)
|
||||
}
|
||||
globalBucketMetadataSys.Remove(bucket)
|
||||
repaired, err := globalBucketMetadataSys.GetConfigFromDisk(ctx, bucket)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if repaired.corsConfigErr != nil || repaired.corsConfig != nil || len(repaired.CorsConfigXML) != 0 || !repaired.CorsConfigUpdatedAt.Equal(deleteAt) {
|
||||
t.Fatalf("repaired CORS state = (%q, %#v, %v, %v), want tombstone at %v", repaired.CorsConfigXML, repaired.corsConfig, repaired.corsConfigErr, repaired.CorsConfigUpdatedAt, deleteAt)
|
||||
}
|
||||
}
|
||||
|
||||
func testPeerBucketCorsCreatedAtFloor(_ ObjectLayer, _ string, bucket string, _ http.Handler, _ auth.Credentials, t *testing.T) {
|
||||
ctx := t.Context()
|
||||
meta, err := globalBucketMetadataSys.Get(bucket)
|
||||
|
||||
Reference in New Issue
Block a user