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

monkeydluffy 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 b40264f44 feat(cors): support for the Timing-Allow-Origin header 
(#9365)
b40264f44 is described below

commit b40264f44e6d3d2d895e3ff981d251102e5d95a1
Author: skimdz86 <[email protected]>
AuthorDate: Tue Dec 5 18:05:33 2023 +0100

    feat(cors): support for the Timing-Allow-Origin header (#9365)
---
 apisix/plugins/cors.lua        | 102 ++++++-
 docs/en/latest/plugins/cors.md |  20 ++
 t/plugin/cors4.t               | 641 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 748 insertions(+), 15 deletions(-)

diff --git a/apisix/plugins/cors.lua b/apisix/plugins/cors.lua
index f4a59ce5e..94f54683e 100644
--- a/apisix/plugins/cors.lua
+++ b/apisix/plugins/cors.lua
@@ -25,6 +25,8 @@ local re_find = ngx.re.find
 local ipairs = ipairs
 local origins_pattern = [[^(\*|\*\*|null|\w+://[^,]+(,\w+://[^,]+)*)$]]
 
+local TYPE_ACCESS_CONTROL_ALLOW_ORIGIN = "ACAO"
+local TYPE_TIMING_ALLOW_ORIGIN = "TAO"
 
 local lrucache = core.lrucache.new({
     type = "plugin",
@@ -119,6 +121,28 @@ local schema = {
             minItems = 1,
             uniqueItems = true,
         },
+        timing_allow_origins = {
+            description =
+                "you can use '*' to allow all origins which can view timing 
information " ..
+                "when no credentials," ..
+                "'**' to allow forcefully (it will bring some security risks, 
be careful)," ..
+                "multiple origin use ',' to split. default: nil",
+            type = "string",
+            pattern = origins_pattern
+        },
+        timing_allow_origins_by_regex = {
+            type = "array",
+            description =
+                "you can use regex to allow specific origins which can view 
timing information," ..
+                "for example use [.*\\.test.com] to allow a.test.com and 
b.test.com",
+            items = {
+                type = "string",
+                minLength = 1,
+                maxLength = 4096,
+            },
+            minItems = 1,
+            uniqueItems = true,
+        },
     }
 }
 
@@ -166,7 +190,8 @@ function _M.check_schema(conf, schema_type)
     end
     if conf.allow_credential then
         if conf.allow_origins == "*" or conf.allow_methods == "*" or
-            conf.allow_headers == "*" or conf.expose_headers == "*" then
+            conf.allow_headers == "*" or conf.expose_headers == "*" or
+            conf.timing_allow_origins == "*" then
             return false, "you can not set '*' for other option when 
'allow_credential' is true"
         end
     end
@@ -179,6 +204,15 @@ function _M.check_schema(conf, schema_type)
         end
     end
 
+    if conf.timing_allow_origins_by_regex then
+        for i, re_rule in ipairs(conf.timing_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
 
@@ -204,7 +238,14 @@ local function set_cors_headers(conf, ctx)
     end
 end
 
-local function process_with_allow_origins(allow_origins, ctx, req_origin,
+local function set_timing_headers(conf, ctx)
+    if ctx.timing_allow_origin then
+        core.response.set_header("Timing-Allow-Origin", 
ctx.timing_allow_origin)
+    end
+end
+
+
+local function process_with_allow_origins(allow_origin_type, allow_origins, 
ctx, req_origin,
                                           cache_key, cache_version)
     if allow_origins == "**" then
         allow_origins = req_origin or '*'
@@ -217,7 +258,7 @@ local function process_with_allow_origins(allow_origins, 
ctx, req_origin,
         )
     else
         multiple_origin, err = core.lrucache.plugin_ctx(
-                lrucache, ctx, nil, create_multiple_origin_cache, allow_origins
+                lrucache, ctx, allow_origin_type, 
create_multiple_origin_cache, allow_origins
         )
     end
 
@@ -236,18 +277,23 @@ local function process_with_allow_origins(allow_origins, 
ctx, req_origin,
     return allow_origins
 end
 
-local function process_with_allow_origins_by_regex(conf, ctx, req_origin)
-    if not conf.allow_origins_by_regex_rules_concat then
+local function process_with_allow_origins_by_regex(allow_origin_type,
+                                                   allow_origins_by_regex, 
conf, ctx, req_origin)
+
+    local allow_origins_by_regex_rules_concat_conf_key =
+            "allow_origins_by_regex_rules_concat_" .. allow_origin_type
+
+    if not conf[allow_origins_by_regex_rules_concat_conf_key] then
         local allow_origins_by_regex_rules = {}
-        for i, re_rule in ipairs(conf.allow_origins_by_regex) do
+        for i, re_rule in ipairs(allow_origins_by_regex) do
             allow_origins_by_regex_rules[i] = re_rule
         end
-        conf.allow_origins_by_regex_rules_concat = core.table.concat(
+        conf[allow_origins_by_regex_rules_concat_conf_key] = core.table.concat(
             allow_origins_by_regex_rules, "|")
     end
 
-    -- core.log.warn("regex: ", conf.allow_origins_by_regex_rules_concat, "\n 
")
-    local matched = re_find(req_origin, 
conf.allow_origins_by_regex_rules_concat, "jo")
+    -- core.log.warn("regex: ", 
conf[allow_origins_by_regex_rules_concat_conf_key], "\n ")
+    local matched = re_find(req_origin, 
conf[allow_origins_by_regex_rules_concat_conf_key], "jo")
     if matched then
         return req_origin
     end
@@ -258,7 +304,9 @@ local function match_origins(req_origin, allow_origins)
     return req_origin == allow_origins or allow_origins == '*'
 end
 
-local function 
process_with_allow_origins_by_metadata(allow_origins_by_metadata, ctx, 
req_origin)
+local function process_with_allow_origins_by_metadata(allow_origin_type, 
allow_origins_by_metadata,
+                                                      ctx, req_origin)
+
     if allow_origins_by_metadata == nil then
         return
     end
@@ -268,8 +316,10 @@ local function 
process_with_allow_origins_by_metadata(allow_origins_by_metadata,
         local allow_origins_map = metadata.value.allow_origins
         for _, key in ipairs(allow_origins_by_metadata) do
             local allow_origins_conf = allow_origins_map[key]
-            local allow_origins = 
process_with_allow_origins(allow_origins_conf, ctx, req_origin,
-                    plugin_name .. "#" .. key, metadata.modifiedIndex)
+            local allow_origins = process_with_allow_origins(
+                allow_origin_type, allow_origins_conf, ctx, req_origin,
+                plugin_name .. "#" .. key, metadata.modifiedIndex
+            )
             if match_origins(req_origin, allow_origins) then
                 return req_origin
             end
@@ -292,13 +342,18 @@ function _M.header_filter(conf, ctx)
     -- If allow_origins_by_regex is not nil, should be matched to it only
     local allow_origins
     if conf.allow_origins_by_regex == nil then
-        allow_origins = process_with_allow_origins(conf.allow_origins, ctx, 
req_origin)
+        allow_origins = process_with_allow_origins(
+            TYPE_ACCESS_CONTROL_ALLOW_ORIGIN, conf.allow_origins, ctx, 
req_origin
+        )
     else
-        allow_origins = process_with_allow_origins_by_regex(conf, ctx, 
req_origin)
+        allow_origins = process_with_allow_origins_by_regex(
+            TYPE_ACCESS_CONTROL_ALLOW_ORIGIN, conf.allow_origins_by_regex,
+            conf, ctx, req_origin
+        )
     end
     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
+            TYPE_ACCESS_CONTROL_ALLOW_ORIGIN, conf.allow_origins_by_metadata, 
ctx, req_origin
         )
     end
     if conf.allow_origins ~= "*" then
@@ -308,6 +363,23 @@ function _M.header_filter(conf, ctx)
         ctx.cors_allow_origins = allow_origins
         set_cors_headers(conf, ctx)
     end
+
+    local timing_allow_origins
+    if conf.timing_allow_origins_by_regex == nil and conf.timing_allow_origins 
then
+        timing_allow_origins = process_with_allow_origins(
+            TYPE_TIMING_ALLOW_ORIGIN, conf.timing_allow_origins, ctx, 
req_origin
+        )
+    elseif conf.timing_allow_origins_by_regex then
+        timing_allow_origins = process_with_allow_origins_by_regex(
+            TYPE_TIMING_ALLOW_ORIGIN, conf.timing_allow_origins_by_regex,
+            conf, ctx, req_origin
+        )
+    end
+    if timing_allow_origins and match_origins(req_origin, 
timing_allow_origins) then
+        ctx.timing_allow_origin = timing_allow_origins
+        set_timing_headers(conf, ctx)
+    end
+
 end
 
 return _M
diff --git a/docs/en/latest/plugins/cors.md b/docs/en/latest/plugins/cors.md
index dad827965..cf8d28064 100644
--- a/docs/en/latest/plugins/cors.md
+++ b/docs/en/latest/plugins/cors.md
@@ -32,6 +32,8 @@ The `cors` Plugins lets you enable 
[CORS](https://developer.mozilla.org/en-US/do
 
 ## Attributes
 
+### CORS attributes
+
 | Name                      | Type    | Required | Default | Description       
                                                                                
                                                                                
                                                                                
                                                                                
                                                 |
 
|---------------------------|---------|----------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | allow_origins             | string  | False    | "*"     | Origins to allow 
CORS. Use the `scheme://host:port` format. For example, 
`https://somedomain.com:8081`. If you have multiple origins, use a `,` to list 
them. If `allow_credential` is set to `false`, you can enable CORS for all 
origins by using `*`. If `allow_credential` is set to `true`, you can 
forcefully allow CORS on all origins by using `**` but it will pose some 
security issues. |
@@ -50,6 +52,24 @@ The `cors` Plugins lets you enable 
[CORS](https://developer.mozilla.org/en-US/do
 
 :::
 
+### Resource Timing attributes
+
+| Name                      | Type    | Required | Default | Description       
                                                                                
                                                                                
                                                                                
                                                                                
                                                 |
+|---------------------------|---------|----------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| timing_allow_origins             | string  | False    | nil     | Origin to 
allow to access the resource timing information. See 
[Timing-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin).
 Use the `scheme://host:port` format. For example, 
`https://somedomain.com:8081`. If you have multiple origins, use a `,` to list 
them. |
+| timing_allow_origins_by_regex    | array   | False    | nil     | Regex to 
match with origin for enabling access to the resource timing information. 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 
`timing_allow_origins` is. |
+
+:::note
+
+The Timing-Allow-Origin header is defined in the Resource Timing API, but it 
is related to the CORS concept.
+
+Suppose you have 2 domains, `domain-A.com` and `domain-B.com`.
+You are on a page on `domain-A.com`, you have an XHR call to a resource on 
`domain-B.com` and you need its timing information.
+You can allow the browser to show this timing information only if you have 
cross-origin permissions on `domain-B.com`.
+So, you have to set the CORS headers first, then access the `domain-B.com` 
URL, and if you set 
[Timing-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin),
 the browser will show the requested timing information.
+
+:::
+
 ## Metadata
 
 | Name          | Type   | Required | Description                              
                                                                                
                                                                               |
diff --git a/t/plugin/cors4.t b/t/plugin/cors4.t
new file mode 100644
index 000000000..c1a9947ad
--- /dev/null
+++ b/t/plugin/cors4.t
@@ -0,0 +1,641 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+log_level("info");
+
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if (!$block->request) {
+        $block->set_value("request", "GET /t");
+    }
+
+    if (!$block->no_error_log && !$block->error_log) {
+        $block->set_value("no_error_log", "[error]\n[alert]");
+    }
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: validate timing_allow_origins
+--- config
+    location /t {
+        content_by_lua_block {
+            local plugin = require("apisix.plugins.cors")
+            local function validate(val)
+                local conf = {}
+                conf.timing_allow_origins = val
+                return plugin.check_schema(conf)
+            end
+
+            local good = {
+                "*",
+                "**",
+                "null",
+                "http://y.com.uk";,
+                "https://x.com";,
+                "https://x.com,http://y.com.uk";,
+                "https://x.com,http://y.com.uk,http://c.tv";,
+                "https://x.com,http://y.com.uk:12000,http://c.tv";,
+            }
+            for _, g in ipairs(good) do
+                local ok, err = validate(g)
+                if not ok then
+                    ngx.say("failed to validate ", g, ", ", err)
+                end
+            end
+
+            local bad = {
+                "",
+                "*a",
+                "*,http://y.com";,
+                "nulll",
+                "http//y.com.uk",
+                "x.com",
+                "https://x.com,y.com.uk";,
+                "https://x.com,*,https://y.com.uk";,
+                "https://x.com,http://y.com.uk,http:c.tv";,
+            }
+            for _, b in ipairs(bad) do
+                local ok, err = validate(b)
+                if ok then
+                    ngx.say("failed to reject ", b)
+                end
+            end
+
+            ngx.say("done")
+        }
+    }
+--- response_body
+done
+
+
+
+=== TEST 2: set route ( allow_origins default, timing_allow_origins 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": "*",
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins": "http://sub.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: origin matching
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://sub.domain.com
+--- response_headers
+Access-Control-Allow-Origin: *
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin: http://sub.domain.com
+
+
+
+=== TEST 4: origin not matching timing_allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://other.domain.com
+--- response_headers
+Access-Control-Allow-Origin: *
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin:
+
+
+
+=== TEST 5: set route ( allow_origins same as timing_allow_origins )
+--- 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";,
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins": "http://sub.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 6: origin matching
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://sub.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://sub.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin: http://sub.domain.com
+
+
+
+=== TEST 7: origin not matching
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://other.domain.com
+--- 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:
+Timing-Allow-Origin:
+
+
+
+=== TEST 8: set route ( allow_origins differs from timing_allow_origins )
+--- 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://one.domain.com";,
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins": "http://another.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 9: origin matching allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://one.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://one.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin:
+
+
+
+=== TEST 10: origin matching timing_allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://another.domain.com
+--- 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:
+Timing-Allow-Origin: http://another.domain.com
+
+
+
+=== TEST 11: origin not matching
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://notexistent.domain.com
+--- 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:
+Timing-Allow-Origin:
+
+
+
+=== TEST 12: set route ( allow_origins superset of timing_allow_origins )
+--- 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://one.domain.com,http://two.domain.com";,
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins": "http://one.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 13: origin matching allow_origins and timing_allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://one.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://one.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin: http://one.domain.com
+
+
+
+=== TEST 14: origin matching only allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://two.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://two.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin:
+
+
+
+=== TEST 15: origin not matching
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://notexistent.domain.com
+--- 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:
+Timing-Allow-Origin:
+
+
+
+=== TEST 16: set route ( allow_origins and timing_allow_origins are two 
different sets with intersection )
+--- 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://one.domain.com,http://two.domain.com";,
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins": 
"http://one.domain.com,http://three.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 17: origin matching allow_origins and timing_allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://one.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://one.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin: http://one.domain.com
+
+
+
+=== TEST 18: origin matching only allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://two.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://two.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Access-Control-Allow-Credentials:
+Timing-Allow-Origin:
+
+
+
+=== TEST 19: origin matching only timing_allow_origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://three.domain.com
+--- 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:
+Timing-Allow-Origin: http://three.domain.com
+
+
+
+=== TEST 20: origin not matching
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://notexistent.domain.com
+--- 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:
+Timing-Allow-Origin:
+
+
+
+=== TEST 21: set route ( allow_origins and timing_allow_origins specified with 
regex )
+--- 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_by_regex": 
["http://.*?\\.domain\\.com";],
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins_by_regex": 
["http://.*?\\.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 22: regex specified match
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://sub.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://sub.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Timing-Allow-Origin: http://sub.domain.com
+
+
+
+=== TEST 23: regex no match
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://other.newdomain.com
+--- response_headers
+Access-Control-Allow-Origin:
+Access-Control-Allow-Methods:
+Access-Control-Allow-Headers:
+Access-Control-Expose-Headers:
+Access-Control-Max-Age:
+Timing-Allow-Origin:
+
+
+
+=== TEST 24: set route ( allow_origins and timing_allow_origins specified with 
different regex )
+--- 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_by_regex": 
["http://.*?\\.domain\\.com";],
+                            "allow_methods": "GET,POST",
+                            "allow_headers": "request-h",
+                            "expose_headers": "expose-h",
+                            "max_age": 10,
+                            "timing_allow_origins_by_regex": 
["http://test.*?\\.domain\\.com";],
+                            "timing_allow_origins": 
"http://nonexistent.newdomain.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 25: regex specified match, test priority of regex over list of origins
+--- request
+GET /hello HTTP/1.1
+--- more_headers
+Origin: http://testurl.domain.com
+--- response_headers
+Access-Control-Allow-Origin: http://testurl.domain.com
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: request-h
+Access-Control-Expose-Headers: expose-h
+Access-Control-Max-Age: 10
+Timing-Allow-Origin: http://testurl.domain.com

Reply via email to