feat: add allow_origins_by_regex to cors plugin#3839
Conversation
|
@batman-ezio Corresponding test cases are required to verify these changes. |
| | expose_headers | string | optional | "*" | | Which headers are allowed to set in response when access cross-origin resource. Multiple value use `,` to split. | | ||
| | max_age | integer | optional | 5 | | Maximum number of seconds the results can be cached.. Within this time range, the browser will reuse the last check result. `-1` means no cache. Please note that the maximum value is depended on browser, please refer to [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#Directives) for details. | | ||
| | allow_credential | boolean | optional | false | | Enable request include credential (such as Cookie etc.). According to CORS specification, if you set this option to `true`, you can not use '*' for other options. | | ||
| | allow_origins_by_regex | array | optional | nil | | Use regex expressions to match which origins is allowed to enable CORS, for example, [".*\.test.com"] can use to match all subdomain of test.com | |
|
|
||
| core.response.set_header("Access-Control-Allow-Origin", ctx.cors_allow_origins) | ||
| if ctx.cors_allow_origins ~= "*" then | ||
| if ctx.cors_allow_origins ~= "*" or next(allow_origins_by_regex) ~= nil then |
There was a problem hiding this comment.
If the origin is matched by regex, it should not be * as this is only available in allow_origins.
There was a problem hiding this comment.
this function set_cors_headers can call not only matched by regex,.
if it matched by allow_origins = '**' then it will go here and needs to add Vary Origin header
| local allow_origins = conf.allow_origins | ||
| local function process_with_allow_origins(conf, ctx) | ||
| local allow_origins = conf.allow_origins or {} | ||
| local req_origin = core.request.header(ctx, "Origin") |
There was a problem hiding this comment.
Can we pass req_origin as an argument to avoid getting it repeatedly?
|
|
||
| local function process_with_allow_origins_by_regex(conf, ctx) | ||
| local allow_origins_by_regex = conf.allow_origins_by_regex or {} | ||
| if next(allow_origins_by_regex) == nil then |
There was a problem hiding this comment.
Better to check if the configuration is empty in the schema, like
apisix/apisix/plugins/ip-restriction.lua
Line 37 in c3e03bb
| end | ||
|
|
||
| local function process_with_allow_origins_by_regex(conf, ctx) | ||
| local allow_origins_by_regex = conf.allow_origins_by_regex or {} |
There was a problem hiding this comment.
There is no need to create a temporary {} if conf.allow_origins_by_regex is nil.
|
|
||
|
|
||
|
|
||
| === TEST 30: set route (regex specified not match) |
There was a problem hiding this comment.
This configuration is a copy of TEST 28? We don't need it.
BTW, we need a test with two regexes configured so that we can test the regex concat.
There was a problem hiding this comment.
test cases added
|
|
||
| core.response.set_header("Access-Control-Allow-Origin", ctx.cors_allow_origins) | ||
| if ctx.cors_allow_origins ~= "*" then | ||
| if ctx.cors_allow_origins ~= "*" or conf.allow_origins_by_regex ~= nil then |
There was a problem hiding this comment.
I still don't understand why we need or conf.allow_origins_by_regex ~= nil.
If allow_origins_by_regex is given but not matched, it can't go into this function.
If allow_origins_by_regex is given but matched, the cors_allow_origins can't be * as * is just a mark used in allow_origins.
There was a problem hiding this comment.
if allow_origins_by_regex is matched, the cors_allow_origins will be the matched domain. not *
for example. it we use [".*.test.com"] and the request is from a.test.com
then the cors_allow_origins will set to a.test.com. not *
conf.allow_origins_by_regex ~= nil means we use regex to match many domains.
the Vary must set as Origin
f a request may contain a Access-Control-Allow-Origin with different values, then the CDN should always respond with Vary: Origin,
check
https://stackoverflow.com/questions/25329405/why-isnt-vary-origin-response-set-on-a-cors-miss
There was a problem hiding this comment.
Yes.
if allow_origins_by_regex is matched, the cors_allow_origins will be the matched domain. not *
So ctx.cors_allow_origins ~= "*" will be true.
Therefore there is no need to add an additional condition.
|
ping @tokers to review. |
What this PR does / why we need it:
Fix #3763
Pre-submission checklist: