spacewander commented on a change in pull request #3839:
URL: https://github.com/apache/apisix/pull/3839#discussion_r596545363



##########
File path: docs/en/latest/plugins/cors.md
##########
@@ -43,6 +43,7 @@ title: cors
 | 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  |

Review comment:
       "which origin is"

##########
File path: apisix/plugins/cors.lua
##########
@@ -151,16 +176,8 @@ local function set_cors_headers(conf, ctx)
     end
 end
 
-
-function _M.rewrite(conf, ctx)
-    if ctx.var.request_method == "OPTIONS" then
-        return 200
-    end
-end
-
-
-function _M.header_filter(conf, ctx)
-    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")

Review comment:
       Can we pass req_origin as an argument to avoid getting it repeatedly?

##########
File path: apisix/plugins/cors.lua
##########
@@ -179,8 +196,56 @@ function _M.header_filter(conf, ctx)
         end
     end
 
-    ctx.cors_allow_origins = allow_origins
-    set_cors_headers(conf, ctx)
+    return allow_origins
+end
+
+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

Review comment:
       Better to check if the configuration is empty in the schema, like 
https://github.com/apache/apisix/blob/c3e03bb44a93ffc904812bfcad7eba4f92897fd2/apisix/plugins/ip-restriction.lua#L37

##########
File path: apisix/plugins/cors.lua
##########
@@ -179,8 +196,56 @@ function _M.header_filter(conf, ctx)
         end
     end
 
-    ctx.cors_allow_origins = allow_origins
-    set_cors_headers(conf, ctx)
+    return allow_origins
+end
+
+local function process_with_allow_origins_by_regex(conf, ctx)
+    local allow_origins_by_regex = conf.allow_origins_by_regex or {}

Review comment:
       There is no need to create a temporary `{}` if 
conf.allow_origins_by_regex is nil.

##########
File path: t/plugin/cors.t
##########
@@ -757,4 +757,132 @@ GET /t
 --- response_body eval
 qr/failed to check the configuration of plugin cors err: you can not/
 --- no_error_log
+
+
+
+=== TEST 28: set route (regex specified)
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "plugins": {
+                        "cors": {
+                            "allow_origins": 
"http://sub.domain.com,http://sub2.domain.com";,
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "headr1,headr2",
+                            "expose_headers": "ex-headr1,ex-headr2",
+                            "max_age": 50,
+                            "allow_credential": true,
+                            "allow_origins_by_regex":[".*\\.test.com"]
+                        }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    },
+                    "uri": "/hello"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 29: regex specified
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://a.test.com
+resp-vary: Via
+--- response_body
+hello world
+--- response_headers
+Access-Control-Allow-Origin: http://a.test.com
+Vary: Via, Origin
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: headr1,headr2
+Access-Control-Expose-Headers: ex-headr1,ex-headr2
+Access-Control-Max-Age: 50
+Access-Control-Allow-Credentials: true
+--- no_error_log
+[error]
+
+
+
+=== TEST 30: set route (regex specified not match)

Review 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.

##########
File path: apisix/plugins/cors.lua
##########
@@ -121,19 +137,28 @@ function _M.check_schema(conf)
             return false, "you can not set '*' for other option when 
'allow_credential' is true"
         end
     end
+    if conf.allow_origins_by_regex then
+        for i, re_rule in ipairs(conf.allow_origins_by_regex) do
+            local ok, err = re_compile(re_rule, "j")
+            if not ok then
+                return false, err
+            end
+        end
+    end
 
     return true
 end
 
 
 local function set_cors_headers(conf, ctx)
     local allow_methods = conf.allow_methods
+    local allow_origins_by_regex = conf.allow_origins_by_regex or {}
     if allow_methods == "**" then
         allow_methods = "GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,CONNECT,TRACE"
     end
 
     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

Review comment:
       If the origin is matched by regex, it should not be `*` as this is only 
available in `allow_origins`.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to