[#225] Support wildcard in allowed origins and headers
Some checks failed
/ DCO (pull_request) Successful in 53s
/ OCI image (pull_request) Successful in 1m46s
/ Vulncheck (pull_request) Successful in 1m47s
/ Builds (pull_request) Successful in 1m46s
/ Lint (pull_request) Successful in 4m9s
/ Tests (pull_request) Successful in 1m26s
/ Integration tests (pull_request) Successful in 6m39s
/ Vulncheck (push) Failing after 58s
/ Builds (push) Successful in 1m18s
/ OCI image (push) Successful in 1m27s
/ Lint (push) Successful in 2m19s
/ Tests (push) Successful in 1m14s
/ Integration tests (push) Successful in 7m35s

Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
Marina Biryukova 2025-04-07 16:50:48 +03:00
parent cb72d11515
commit 273459e090
2 changed files with 510 additions and 9 deletions

View file

@ -5,6 +5,8 @@ import (
"encoding/xml"
"errors"
"fmt"
"regexp"
"slices"
"sort"
"strconv"
"strings"
@ -78,7 +80,7 @@ func (h *Handler) Preflight(req *fasthttp.RequestCtx) {
for _, rule := range corsConfig.CORSRules {
for _, o := range rule.AllowedOrigins {
if o == string(origin) || o == wildcard {
if o == string(origin) || o == wildcard || (strings.Contains(o, "*") && match(o, string(origin))) {
for _, m := range rule.AllowedMethods {
if m == string(method) {
if !checkSubslice(rule.AllowedHeaders, headers) {
@ -117,6 +119,11 @@ func (h *Handler) SetCORSHeaders(req *fasthttp.RequestCtx) {
return
}
method := req.Request.Header.Peek(fasthttp.HeaderAccessControlRequestMethod)
if len(method) == 0 {
method = req.Method()
}
ctx = qostagging.ContextWithIOTag(ctx, internalIOTag)
cidParam, _ := req.UserValue("cid").(string)
reqLog := h.reqLogger(ctx)
@ -141,9 +148,9 @@ func (h *Handler) SetCORSHeaders(req *fasthttp.RequestCtx) {
for _, rule := range corsConfig.CORSRules {
for _, o := range rule.AllowedOrigins {
if o == string(origin) {
if o == string(origin) || (strings.Contains(o, "*") && len(o) > 1 && match(o, string(origin))) {
for _, m := range rule.AllowedMethods {
if m == string(req.Method()) {
if m == string(method) {
req.Response.Header.Set(fasthttp.HeaderAccessControlAllowOrigin, string(origin))
req.Response.Header.Set(fasthttp.HeaderAccessControlAllowMethods, strings.Join(rule.AllowedMethods, ", "))
req.Response.Header.Set(fasthttp.HeaderAccessControlAllowCredentials, "true")
@ -154,7 +161,7 @@ func (h *Handler) SetCORSHeaders(req *fasthttp.RequestCtx) {
}
if o == wildcard {
for _, m := range rule.AllowedMethods {
if m == string(req.Method()) {
if m == string(method) {
if withCredentials {
req.Response.Header.Set(fasthttp.HeaderAccessControlAllowOrigin, string(origin))
req.Response.Header.Set(fasthttp.HeaderAccessControlAllowCredentials, "true")
@ -318,12 +325,9 @@ func setCORSHeadersFromRule(c *fasthttp.RequestCtx, cors *data.CORSRule) {
}
func checkSubslice(slice []string, subSlice []string) bool {
if sliceContains(slice, wildcard) {
if slices.Contains(slice, wildcard) {
return true
}
if len(subSlice) > len(slice) {
return false
}
for _, r := range subSlice {
if !sliceContains(slice, r) {
return false
@ -334,9 +338,16 @@ func checkSubslice(slice []string, subSlice []string) bool {
func sliceContains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
if s == str || (strings.Contains(s, "*") && match(s, str)) {
return true
}
}
return false
}
func match(tmpl, str string) bool {
regexpStr := "^" + regexp.QuoteMeta(tmpl) + "$"
regexpStr = regexpStr[:strings.Index(regexpStr, "*")-1] + "." + regexpStr[strings.Index(regexpStr, "*"):]
reg := regexp.MustCompile(regexpStr)
return reg.Match([]byte(str))
}