diff --git a/apisix/plugins/cors.lua b/apisix/plugins/cors.lua index 9fe91c94dd58..5d827d213663 100644 --- a/apisix/plugins/cors.lua +++ b/apisix/plugins/cors.lua @@ -64,7 +64,7 @@ local schema = { allow_credential = { type = "boolean", default = false - }, + } } } @@ -75,6 +75,7 @@ local _M = { schema = schema, } + local function create_mutiple_origin_cache(conf) if not str_find(conf.allow_origins, ",", 1, true) then return nil @@ -99,6 +100,7 @@ local function create_mutiple_origin_cache(conf) return origin_cache end + function _M.check_schema(conf) local ok, err = core.schema.check(schema, conf) if not ok then @@ -108,23 +110,32 @@ function _M.check_schema(conf) return true end + local function set_cors_headers(conf, ctx) local allow_methods = conf.allow_methods if allow_methods == "**" then allow_methods = "GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,CONNECT,TRACE" end - ngx.header["Access-Control-Allow-Origin"] = ctx.cors_allow_origins - ngx.header["Access-Control-Allow-Methods"] = allow_methods - ngx.header["Access-Control-Allow-Headers"] = conf.allow_headers - ngx.header["Access-Control-Max-Age"] = conf.max_age + core.response.set_header("Access-Control-Allow-Origin", ctx.cors_allow_origins) + core.response.set_header("Access-Control-Allow-Methods", allow_methods) + core.response.set_header("Access-Control-Allow-Headers", conf.allow_headers) + core.response.set_header("Access-Control-Max-Age", conf.max_age) + core.response.set_header("Access-Control-Expose-Headers", conf.expose_headers) if conf.allow_credential then - ngx.header["Access-Control-Allow-Credentials"] = true + core.response.set_header("Access-Control-Allow-Credentials", true) end - ngx.header["Access-Control-Expose-Headers"] = conf.expose_headers 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 req_origin = core.request.header(ctx, "Origin") if allow_origins == "**" then @@ -146,10 +157,6 @@ function _M.rewrite(conf, ctx) ctx.cors_allow_origins = allow_origins set_cors_headers(conf, ctx) - - if ctx.var.request_method == "OPTIONS" then - return 200 - end end return _M diff --git a/t/lib/server.lua b/t/lib/server.lua index dfbead610566..864a8e2778d5 100644 --- a/t/lib/server.lua +++ b/t/lib/server.lua @@ -250,5 +250,14 @@ function _M.go() return _M[action]() end +function _M.headers() + local args = ngx.req.get_uri_args() + for name, val in pairs(args) do + ngx.header[name] = nil + ngx.header[name] = val + end + + ngx.say("/headers") +end return _M diff --git a/t/plugin/cors.t b/t/plugin/cors.t index 364ae909df41..bc477054385f 100644 --- a/t/plugin/cors.t +++ b/t/plugin/cors.t @@ -491,3 +491,129 @@ Access-Control-Max-Age: 5 Access-Control-Allow-Credentials: --- no_error_log [error] + + + +=== TEST 17: set route(overwrite upstream) +--- 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": "**", + "allow_headers": "*", + "expose_headers": "*", + "allow_credential": true + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/headers" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 18: overwrite upstream +--- request +GET /headers?Access-Control-Allow-Origin=https://sub.domain.com HTTP/1.1 +--- more_headers +Origin: https://sub.domain.com +--- response_body +/headers +--- response_headers +Access-Control-Allow-Origin: https://sub.domain.com +--- no_error_log +[error] + + + +=== TEST 19: overwrite upstream(Access-Control-Allow-Methods) +--- request +GET /headers?Access-Control-Allow-Methods=methods HTTP/1.1 +--- more_headers +Origin: https://sub.domain.com +--- response_body +/headers +--- response_headers +Access-Control-Allow-Methods: GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,CONNECT,TRACE +--- no_error_log +[error] + + + +=== TEST 20: overwrite upstream(Access-Control-Allow-Headers) +--- request +GET /headers?Access-Control-Allow-Headers=a-headers HTTP/1.1 +--- more_headers +Origin: https://sub.domain.com +--- response_body +/headers +--- response_headers +Access-Control-Allow-Headers: * +--- no_error_log +[error] + + + +=== TEST 21: overwrite upstream(Access-Control-Expose-Headers) +--- request +GET /headers?Access-Control-Expose-Headers=e-headers HTTP/1.1 +--- more_headers +Origin: https://sub.domain.com +--- response_body +/headers +--- response_headers +Access-Control-Expose-Headers: * +--- no_error_log +[error] + + + +=== TEST 22: overwrite upstream(Access-Control-Max-Age) +--- request +GET /headers?Access-Control-Max-Age=10 HTTP/1.1 +--- more_headers +Origin: https://sub.domain.com +--- response_body +/headers +--- response_headers +Access-Control-Max-Age: 5 +--- no_error_log +[error] + + + +=== TEST 23: not overwrite upstream(Access-Control-Allow-Credentials) +--- request +GET /headers?Access-Control-Allow-Credentials=false HTTP/1.1 +--- more_headers +Origin: https://sub.domain.com +--- response_body +/headers +--- response_headers +Access-Control-Allow-Credentials: true +--- no_error_log +[error]