This is an automated email from the ASF dual-hosted git repository.

leslie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c9e34acb fix(cors): consider using `allow_origins_by_regex` only when 
it is not `nil` (#9028)
6c9e34acb is described below

commit 6c9e34acb611ae8c4e22d198a299eaea2a7fa20d
Author: Chen <[email protected]>
AuthorDate: Fri Mar 24 16:28:02 2023 +0800

    fix(cors): consider using `allow_origins_by_regex` only when it is not 
`nil` (#9028)
---
 apisix/plugins/cors.lua        | 13 +++----
 docs/en/latest/plugins/cors.md |  2 +-
 docs/zh/latest/plugins/cors.md |  2 +-
 t/plugin/cors2.t               | 85 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 92 insertions(+), 10 deletions(-)

diff --git a/apisix/plugins/cors.lua b/apisix/plugins/cors.lua
index 8e2a468aa..4f0bfa5d3 100644
--- a/apisix/plugins/cors.lua
+++ b/apisix/plugins/cors.lua
@@ -237,10 +237,6 @@ local function process_with_allow_origins(allow_origins, 
ctx, req_origin,
 end
 
 local function process_with_allow_origins_by_regex(conf, ctx, req_origin)
-    if conf.allow_origins_by_regex == nil then
-        return
-    end
-
     if not conf.allow_origins_by_regex_rules_concat then
         local allow_origins_by_regex_rules = {}
         for i, re_rule in ipairs(conf.allow_origins_by_regex) do
@@ -293,13 +289,14 @@ end
 
 function _M.header_filter(conf, ctx)
     local req_origin =  ctx.original_request_origin
-    -- Try allow_origins first, if mismatched, try allow_origins_by_regex.
+    -- If allow_origins_by_regex is not nil, should be matched to it only
     local allow_origins
-    allow_origins = process_with_allow_origins(conf.allow_origins, ctx, 
req_origin)
-    if not match_origins(req_origin, allow_origins) then
+    if conf.allow_origins_by_regex == nil then
+        allow_origins = process_with_allow_origins(conf.allow_origins, ctx, 
req_origin)
+    else
         allow_origins = process_with_allow_origins_by_regex(conf, ctx, 
req_origin)
     end
-    if not allow_origins then
+    if not match_origins(req_origin, allow_origins) then
         allow_origins = process_with_allow_origins_by_metadata(
                 conf.allow_origins_by_metadata, ctx, req_origin
         )
diff --git a/docs/en/latest/plugins/cors.md b/docs/en/latest/plugins/cors.md
index a1ddb2556..fc1e3e326 100644
--- a/docs/en/latest/plugins/cors.md
+++ b/docs/en/latest/plugins/cors.md
@@ -40,7 +40,7 @@ The `cors` Plugins lets you enable 
[CORS](https://developer.mozilla.org/en-US/do
 | expose_headers            | string  | False    | "*"     | Headers in the 
response allowed when accessing a cross-origin resource. Use `,` to add 
multiple headers. If `allow_credential` is set to `false`, you can enable CORS 
for all response headers by using `*`. If `allow_credential` is set to `true`, 
you can forcefully allow CORS on all response headers by using `**` but it will 
pose some security issues.                                    |
 | max_age                   | integer | False    | 5       | Maximum time in 
seconds the result is cached. If the time is within this limit, the browser 
will check the cached result. Set to `-1` to disable caching. Note that the 
maximum value is browser dependent. See 
[Access-Control-Max-Age](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#Directives)
 for more details.                                            |
 | allow_credential          | boolean | False    | false   | When set to 
`true`, allows requests to include credentials like cookies. According to CORS 
specification, if you set this to `true`, you cannot use '*' to allow all for 
the other attributes.                                                           
                                                                                
                                                          |
-| allow_origins_by_regex    | array   | False    | nil     | Regex to match 
with origin for enabling CORS. For example, `[".*\.test.com"]` can match all 
subdomain of `test.com`.                                                        
                                                                                
                                                                                
                                                       |
+| allow_origins_by_regex    | array   | False    | nil     | Regex to match 
with origin for enabling CORS. For example, `[".*\.test.com"]` can match all 
subdomain of `test.com`. When set to specified range, only domains in this 
range will be allowed, no matter what `allow_origins` is.                       
                                                                                
                                                            |
 | allow_origins_by_metadata | array   | False    | nil     | Origins to enable 
CORS referenced from `allow_origins` set in the Plugin metadata. For example, 
if `"allow_origins": {"EXAMPLE": "https://example.com"}` is set in the Plugin 
metadata, then `["EXAMPLE"]` can be used to allow CORS on the origin 
`https://example.com`.                                                          
                                                                |
 
 :::info IMPORTANT
diff --git a/docs/zh/latest/plugins/cors.md b/docs/zh/latest/plugins/cors.md
index 054c00a1b..01c979156 100644
--- a/docs/zh/latest/plugins/cors.md
+++ b/docs/zh/latest/plugins/cors.md
@@ -40,7 +40,7 @@ description: 本文介绍了 Apache APISIX cors 插件的基本信息及使用
 | expose_headers   | string  | 否   | "*"    | 允许跨域访问时响应方携带哪些非 `CORS 规范` 以外的 
Header。如果你有多个 Header,请使用 `,` 分割。当 `allow_credential` 为 `false` 时,可以使用 `*` 
来表示允许任意 Header 。你也可以在启用了 `allow_credential` 后使用 `**` 强制允许任意 
Header,但请注意这样存在安全隐患。 |
 | max_age          | integer | 否   | 5      | 浏览器缓存 CORS 
结果的最大时间,单位为秒。在这个时间范围内,浏览器会复用上一次的检查结果,`-1` 表示不缓存。请注意各个浏览器允许的最大时间不同,详情请参考 
[Access-Control-Max-Age - 
MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#directives)。
 |
 | allow_credential | boolean | 否   | false  | 是否允许跨域访问的请求方携带凭据(如 Cookie 等)。根据 
CORS 规范,如果设置该选项为 `true`,那么将不能在其他属性中使用 `*`。 |
-| allow_origins_by_regex | array | 否   | nil  | 使用正则表达式数组来匹配允许跨域访问的 Origin,如 
`[".*\.test.com"]` 可以匹配任何 `test.com` 的子域名 `*`。 |
+| allow_origins_by_regex | array | 否   | nil  | 使用正则表达式数组来匹配允许跨域访问的 Origin,如 
`[".*\.test.com"]` 可以匹配任何 `test.com` 的子域名 `*`。如果 `allow_origins_by_regex` 
属性已经指定,则会忽略 `allow_origins` 属性。 |
 | allow_origins_by_metadata | array | 否    | nil   | 通过引用插件元数据的 
`allow_origins` 配置允许跨域访问的 Origin。比如当插件元数据为 `"allow_origins": {"EXAMPLE": 
"https://example.com"}` 时,配置 `["EXAMPLE"]` 将允许 Origin `https://example.com` 
的访问。  |
 
 :::info IMPORTANT
diff --git a/t/plugin/cors2.t b/t/plugin/cors2.t
index 67f6d6baa..1bc223bd3 100644
--- a/t/plugin/cors2.t
+++ b/t/plugin/cors2.t
@@ -89,3 +89,88 @@ __DATA__
     }
 --- response_body
 done
+
+
+
+=== TEST 2: set route ( regex specified and allow_origins is default value )
+--- 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": "*",
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "allow_origins_by_regex":[".*\\.domain.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
+
+
+
+=== TEST 3: regex specified not match
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://sub.test.com
+resp-vary: Via
+--- response_headers
+Access-Control-Allow-Origin:
+Access-Control-Allow-Methods:
+Access-Control-Allow-Headers:
+Access-Control-Expose-Headers:
+Access-Control-Max-Age:
+Access-Control-Allow-Credentials:
+
+
+
+=== TEST 4: regex no origin specified
+--- request
+GET /hello HTTP/1.1
+--- response_headers
+Access-Control-Allow-Origin:
+Access-Control-Allow-Methods:
+Access-Control-Allow-Headers:
+Access-Control-Expose-Headers:
+Access-Control-Max-Age:
+Access-Control-Allow-Credentials:
+
+
+
+=== TEST 5: regex specified match
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://sub.domain.com
+resp-vary: Via
+--- response_headers
+Access-Control-Allow-Origin: http://sub.domain.com
+Vary: Via
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10

Reply via email to