mirror of
https://github.com/pgsty/minio.git
synced 2026-09-05 18:16:16 +03:00
fix: address CORS final-review findings (multi-rule preflight, raw GET, e2e test)
Signed-off-by: h5vx <h5v@protonmail.com>
This commit is contained in:
@@ -148,3 +148,23 @@ func (c *Config) MatchRule(origin, method string) (*Rule, bool) {
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// MatchPreflight returns the first rule whose origin and method match and
|
||||
// whose AllowedHeaders permit every header in reqHeaders. Unlike MatchRule,
|
||||
// this keeps evaluating subsequent rules until one fully satisfies the
|
||||
// preflight request, since an earlier origin/method match with a more
|
||||
// restrictive header list must not shadow a later, more permissive rule.
|
||||
func (c *Config) MatchPreflight(origin, method string, reqHeaders []string) (rule *Rule, allowedHeaders []string, ok bool) {
|
||||
for i := range c.CORSRules {
|
||||
r := &c.CORSRules[i]
|
||||
if !r.HasAllowedOrigin(origin) || !r.HasAllowedMethod(method) {
|
||||
continue
|
||||
}
|
||||
allowed, headersOK := r.FilterAllowedHeaders(reqHeaders)
|
||||
if !headersOK {
|
||||
continue
|
||||
}
|
||||
return r, allowed, true
|
||||
}
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
@@ -89,3 +89,40 @@ func TestMatching(t *testing.T) {
|
||||
t.Fatal("did not expect authorization to be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchPreflightFallsThroughToLaterRule(t *testing.T) {
|
||||
// Rule A matches origin+method but only allows a restrictive header set.
|
||||
// Rule B, listed after A, matches the same origin+method and allows any
|
||||
// header. A preflight requesting a header only B permits must not be
|
||||
// rejected just because A was tried first.
|
||||
const doc = `<CORSConfiguration>
|
||||
<CORSRule>
|
||||
<ID>A-restrictive</ID>
|
||||
<AllowedOrigin>https://app.example.com</AllowedOrigin>
|
||||
<AllowedMethod>GET</AllowedMethod>
|
||||
<AllowedHeader>x-amz-date</AllowedHeader>
|
||||
</CORSRule>
|
||||
<CORSRule>
|
||||
<ID>B-permissive</ID>
|
||||
<AllowedOrigin>https://app.example.com</AllowedOrigin>
|
||||
<AllowedMethod>GET</AllowedMethod>
|
||||
<AllowedHeader>*</AllowedHeader>
|
||||
</CORSRule>
|
||||
</CORSConfiguration>`
|
||||
|
||||
c, err := ParseBucketCorsConfig(strings.NewReader(doc))
|
||||
if err != nil {
|
||||
t.Fatalf("parse failed: %v", err)
|
||||
}
|
||||
|
||||
rule, allowed, ok := c.MatchPreflight("https://app.example.com", "GET", []string{"x-custom-header"})
|
||||
if !ok {
|
||||
t.Fatal("expected MatchPreflight to succeed via the later, permissive rule")
|
||||
}
|
||||
if rule.ID != "B-permissive" {
|
||||
t.Fatalf("expected rule B-permissive to be selected, got %q", rule.ID)
|
||||
}
|
||||
if len(allowed) != 1 || allowed[0] != "x-custom-header" {
|
||||
t.Fatalf("unexpected allowed headers: %v", allowed)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user