fix: CORS wildcard subdomain matching cache race condition (#7736)
test: add HTTPS test cases for CORS wildcard subdomain matching This adds comprehensive test coverage for HTTPS subdomain wildcard matching in TestMatchesOrigin: - https exact match - https no match - https wildcard subdomain match - https wildcard subdomain no match (base domain) - https wildcard subdomain no match (different domain) - protocol mismatch tests (http pattern vs https origin and vice versa) The matchWildcard function was already working correctly - this just adds test coverage for the HTTPS cases that were previously untested. Note: The cache invalidation is already handled synchronously by setBucketMetadata() which is called via: - UpdateBucketCORS -> UpdateBucketMetadata -> setBucketMetadata - ClearBucketCORS -> UpdateBucketMetadata -> setBucketMetadata Added clarifying comments to document this call chain.
This commit is contained in:
@@ -263,6 +263,49 @@ func TestMatchesOrigin(t *testing.T) {
|
||||
origin: "http://other.com",
|
||||
want: true,
|
||||
},
|
||||
// HTTPS test cases
|
||||
{
|
||||
name: "https exact match",
|
||||
allowedOrigins: []string{"https://example.com"},
|
||||
origin: "https://example.com",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "https no match",
|
||||
allowedOrigins: []string{"https://example.com"},
|
||||
origin: "https://other.com",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "https wildcard subdomain match",
|
||||
allowedOrigins: []string{"https://*.example.com"},
|
||||
origin: "https://api.example.com",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "https wildcard subdomain no match - base domain",
|
||||
allowedOrigins: []string{"https://*.example.com"},
|
||||
origin: "https://example.com",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "https wildcard subdomain no match - different domain",
|
||||
allowedOrigins: []string{"https://*.example.com"},
|
||||
origin: "https://api.other.com",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "protocol mismatch - http pattern https origin",
|
||||
allowedOrigins: []string{"http://*.example.com"},
|
||||
origin: "https://api.example.com",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "protocol mismatch - https pattern http origin",
|
||||
allowedOrigins: []string{"https://*.example.com"},
|
||||
origin: "http://api.example.com",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@@ -480,7 +523,7 @@ func TestApplyHeaders(t *testing.T) {
|
||||
"Access-Control-Allow-Headers": "Content-Type",
|
||||
"Access-Control-Expose-Headers": "ETag",
|
||||
"Access-Control-Max-Age": "3600",
|
||||
"Vary": "Origin",
|
||||
"Vary": "Origin",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -494,7 +537,7 @@ func TestApplyHeaders(t *testing.T) {
|
||||
"Access-Control-Allow-Origin": "http://example.com",
|
||||
"Access-Control-Allow-Methods": "GET",
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
"Vary": "Origin",
|
||||
"Vary": "Origin",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -218,13 +218,14 @@ func (s3a *S3ApiServer) getEncryptionConfiguration(bucket string) (*s3_pb.Encryp
|
||||
// updateEncryptionConfiguration updates the encryption configuration for a bucket
|
||||
func (s3a *S3ApiServer) updateEncryptionConfiguration(bucket string, encryptionConfig *s3_pb.EncryptionConfiguration) s3err.ErrorCode {
|
||||
// Update using structured API
|
||||
// Note: UpdateBucketEncryption -> UpdateBucketMetadata -> setBucketMetadata
|
||||
// already invalidates the cache synchronously after successful update
|
||||
err := s3a.UpdateBucketEncryption(bucket, encryptionConfig)
|
||||
if err != nil {
|
||||
glog.Errorf("updateEncryptionConfiguration: failed to update encryption config for bucket %s: %v", bucket, err)
|
||||
return s3err.ErrInternalError
|
||||
}
|
||||
|
||||
// Cache will be updated automatically via metadata subscription
|
||||
return s3err.ErrNone
|
||||
}
|
||||
|
||||
@@ -242,13 +243,14 @@ func (s3a *S3ApiServer) removeEncryptionConfiguration(bucket string) s3err.Error
|
||||
}
|
||||
|
||||
// Update using structured API
|
||||
// Note: ClearBucketEncryption -> UpdateBucketMetadata -> setBucketMetadata
|
||||
// already invalidates the cache synchronously after successful update
|
||||
err = s3a.ClearBucketEncryption(bucket)
|
||||
if err != nil {
|
||||
glog.Errorf("removeEncryptionConfiguration: failed to remove encryption config for bucket %s: %v", bucket, err)
|
||||
return s3err.ErrInternalError
|
||||
}
|
||||
|
||||
// Cache will be updated automatically via metadata subscription
|
||||
return s3err.ErrNone
|
||||
}
|
||||
|
||||
|
||||
@@ -612,26 +612,28 @@ func (s3a *S3ApiServer) getCORSConfiguration(bucket string) (*cors.CORSConfigura
|
||||
// updateCORSConfiguration updates the CORS configuration for a bucket
|
||||
func (s3a *S3ApiServer) updateCORSConfiguration(bucket string, corsConfig *cors.CORSConfiguration) s3err.ErrorCode {
|
||||
// Update using structured API
|
||||
// Note: UpdateBucketCORS -> UpdateBucketMetadata -> setBucketMetadata
|
||||
// already invalidates the cache synchronously after successful update
|
||||
err := s3a.UpdateBucketCORS(bucket, corsConfig)
|
||||
if err != nil {
|
||||
glog.Errorf("updateCORSConfiguration: failed to update CORS config for bucket %s: %v", bucket, err)
|
||||
return s3err.ErrInternalError
|
||||
}
|
||||
|
||||
// Cache will be updated automatically via metadata subscription
|
||||
return s3err.ErrNone
|
||||
}
|
||||
|
||||
// removeCORSConfiguration removes the CORS configuration for a bucket
|
||||
func (s3a *S3ApiServer) removeCORSConfiguration(bucket string) s3err.ErrorCode {
|
||||
// Update using structured API
|
||||
// Note: ClearBucketCORS -> UpdateBucketMetadata -> setBucketMetadata
|
||||
// already invalidates the cache synchronously after successful update
|
||||
err := s3a.ClearBucketCORS(bucket)
|
||||
if err != nil {
|
||||
glog.Errorf("removeCORSConfiguration: failed to remove CORS config for bucket %s: %v", bucket, err)
|
||||
return s3err.ErrInternalError
|
||||
}
|
||||
|
||||
// Cache will be updated automatically via metadata subscription
|
||||
return s3err.ErrNone
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user