mirror of
https://gitee.com/iresty/apisix.git
synced 2024-12-05 05:27:35 +08:00
feat[batch-request]: cp all header to every request (#1697)
This commit is contained in:
parent
cd98a2bec8
commit
3010e04d47
@ -14,12 +14,15 @@
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
--
|
||||
local core = require("apisix.core")
|
||||
local http = require("resty.http")
|
||||
local ngx = ngx
|
||||
local io_open = io.open
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local core = require("apisix.core")
|
||||
local http = require("resty.http")
|
||||
local ngx = ngx
|
||||
local io_open = io.open
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local str_find = string.find
|
||||
local str_lower = string.lower
|
||||
|
||||
|
||||
local plugin_name = "batch-requests"
|
||||
|
||||
@ -112,22 +115,42 @@ local function check_input(data)
|
||||
end
|
||||
end
|
||||
|
||||
local function lowercase_key_or_init(obj)
|
||||
if not obj then
|
||||
return {}
|
||||
end
|
||||
|
||||
local function set_common_header(data)
|
||||
local ck = core.request.header(nil, "Cookie")
|
||||
local lowercase_key_obj = {}
|
||||
for k, v in pairs(obj) do
|
||||
lowercase_key_obj[str_lower(k)] = v
|
||||
end
|
||||
|
||||
return lowercase_key_obj
|
||||
end
|
||||
|
||||
local function ensure_header_lowercase(data)
|
||||
data.headers = lowercase_key_or_init(data.headers)
|
||||
|
||||
for i,req in ipairs(data.pipeline) do
|
||||
if not req.headers then
|
||||
req.headers = {}
|
||||
req.headers = lowercase_key_or_init(req.headers)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function set_common_header(data)
|
||||
local outer_headers = core.request.headers(nil)
|
||||
for i,req in ipairs(data.pipeline) do
|
||||
for k, v in pairs(data.headers) do
|
||||
if not req.headers[k] then
|
||||
req.headers[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
if ck then
|
||||
req.headers["Cookie"] = ck
|
||||
end
|
||||
|
||||
if data.headers then
|
||||
for k, v in pairs(data.headers) do
|
||||
if not req.headers[k] then
|
||||
if outer_headers then
|
||||
for k, v in pairs(outer_headers) do
|
||||
local is_content_header = str_find(k, "content-", 1, true) == 1
|
||||
-- skip header start with "content-"
|
||||
if not req.headers[k] and not is_content_header then
|
||||
req.headers[k] = v
|
||||
end
|
||||
end
|
||||
@ -202,8 +225,10 @@ local function batch_requests()
|
||||
core.response.exit(500, {error_msg = "connect to apisix failed: " .. err})
|
||||
end
|
||||
|
||||
ensure_header_lowercase(data)
|
||||
set_common_header(data)
|
||||
set_common_query(data)
|
||||
|
||||
local responses, err = httpc:request_pipeline(data.pipeline)
|
||||
if not responses then
|
||||
core.response.exit(400, {error_msg = "request failed: " .. err})
|
||||
|
@ -32,6 +32,10 @@
|
||||
|
||||
`batch-requests` 插件可以一次接受多个请求并以 [http pipeline](https://en.wikipedia.org/wiki/HTTP_pipelining) 的方式在网关发起多个http请求,合并结果后再返回客户端,这在客户端需要访问多个接口时可以显著地提升请求性能。
|
||||
|
||||
> **提示**
|
||||
>
|
||||
> 外层的 Http 请求头会自动设置到每一个独立请求中,如果独立请求中出现相同键值的请求头,那么只有独立请求的请求头会生效。
|
||||
|
||||
## 属性
|
||||
|
||||
无
|
||||
|
@ -32,6 +32,10 @@
|
||||
|
||||
`batch-requests` can accept mutiple request and send them from `apisix` via [http pipeline](https://en.wikipedia.org/wiki/HTTP_pipelining),and return a aggregated response to client,this can significantly improve performance when the client needs to access multiple APIs.
|
||||
|
||||
> **Tips**
|
||||
>
|
||||
> The HTTP headers for the outer batch request, except for the Content- headers such as Content-Type, apply to every request in the batch. If you specify a given HTTP header in both the outer request and an individual call, then the individual call header's value overrides the outer batch request header's value. The headers for an individual call apply only to that call.
|
||||
|
||||
## Attributes
|
||||
|
||||
None
|
||||
@ -41,7 +45,7 @@ None
|
||||
Default enbaled
|
||||
|
||||
## Batch Api Request/Response
|
||||
The plugin will create a api in `apisix` to handle your aggregation request.
|
||||
The plugin will create a api in `apisix` to handle your batch request.
|
||||
|
||||
### Batch Api Request:
|
||||
|
||||
|
@ -40,7 +40,8 @@ __DATA__
|
||||
},
|
||||
"headers": {
|
||||
"Base-Header": "base",
|
||||
"Conflict-Header": "header_value"
|
||||
"ConflictHeader": "header_value",
|
||||
"OuterConflict": "common_value"
|
||||
},
|
||||
"pipeline":[
|
||||
{
|
||||
@ -48,7 +49,7 @@ __DATA__
|
||||
"headers": {
|
||||
"Header1": "hello",
|
||||
"Header2": "world",
|
||||
"Conflict-Header": "b-header-value"
|
||||
"ConflictHeader": "b-header-value"
|
||||
}
|
||||
},{
|
||||
"path": "/c",
|
||||
@ -71,7 +72,8 @@ __DATA__
|
||||
"X-Res": "B",
|
||||
"X-Header1": "hello",
|
||||
"X-Header2": "world",
|
||||
"X-Conflict-Header": "b-header-value"
|
||||
"X-Conflict-Header": "b-header-value",
|
||||
"X-OuterConflict": "common_value"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -95,8 +97,11 @@ __DATA__
|
||||
"X-Query-Conflict": "d_value"
|
||||
}
|
||||
}
|
||||
]]=]
|
||||
)
|
||||
]]=],
|
||||
{
|
||||
ConflictHeader = "outer_header",
|
||||
OuterConflict = "outer_confliect"
|
||||
})
|
||||
|
||||
ngx.status = code
|
||||
ngx.say(body)
|
||||
@ -110,7 +115,8 @@ __DATA__
|
||||
ngx.header["Base-Query"] = ngx.var.arg_base
|
||||
ngx.header["X-Header1"] = ngx.req.get_headers()["Header1"]
|
||||
ngx.header["X-Header2"] = ngx.req.get_headers()["Header2"]
|
||||
ngx.header["X-Conflict-Header"] = ngx.req.get_headers()["Conflict-Header"]
|
||||
ngx.header["X-Conflict-Header"] = ngx.req.get_headers()["ConflictHeader"]
|
||||
ngx.header["X-OuterConflict"] = ngx.req.get_headers()["OuterConflict"]
|
||||
ngx.header["X-Res"] = "B"
|
||||
ngx.print("B")
|
||||
}
|
||||
@ -687,7 +693,7 @@ passed
|
||||
|
||||
|
||||
|
||||
=== TEST 15: copy cookie to every request
|
||||
=== TEST 15: copy all header to every request except Contenct-
|
||||
--- config
|
||||
client_body_in_file_only on;
|
||||
location = /aggregate {
|
||||
@ -697,7 +703,7 @@ passed
|
||||
local code, body = t('/apisix/batch-requests',
|
||||
ngx.HTTP_POST,
|
||||
[=[{
|
||||
"timeout": 100,
|
||||
"timeout": 1000,
|
||||
"pipeline":[
|
||||
{
|
||||
"path": "/b",
|
||||
@ -716,24 +722,28 @@ passed
|
||||
{
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"X-Cookie": "request-cookies-b"
|
||||
"X-Cookie": "request-cookies-b",
|
||||
"X-HeaderB": "request-header-b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"status": 201,
|
||||
"headers": {
|
||||
"X-Cookie": "request-cookies-c"
|
||||
"X-Cookie": "request-cookies-c",
|
||||
"X-HeaderC": "request-header-c"
|
||||
}
|
||||
},
|
||||
{
|
||||
"status": 202,
|
||||
"headers": {
|
||||
"X-Cookie": "request-cookies-d"
|
||||
"X-Cookie": "request-cookies-d",
|
||||
"X-HeaderD": "request-header-d"
|
||||
}
|
||||
}
|
||||
]]=],
|
||||
{
|
||||
Cookie = "request-cookies"
|
||||
Cookie = "request-cookies",
|
||||
OuterHeader = "request-header"
|
||||
})
|
||||
|
||||
ngx.status = code
|
||||
@ -745,18 +755,21 @@ passed
|
||||
content_by_lua_block {
|
||||
ngx.status = 200
|
||||
ngx.header["X-Cookie"] = ngx.req.get_headers()["Cookie"] .. "-b"
|
||||
ngx.header["X-HeaderB"] = ngx.req.get_headers()["OuterHeader"] .. "-b"
|
||||
}
|
||||
}
|
||||
location = /c {
|
||||
content_by_lua_block {
|
||||
ngx.status = 201
|
||||
ngx.header["X-Cookie"] = ngx.req.get_headers()["Cookie"] .. "-c"
|
||||
ngx.header["X-HeaderC"] = ngx.req.get_headers()["OuterHeader"] .. "-c"
|
||||
}
|
||||
}
|
||||
location = /d {
|
||||
content_by_lua_block {
|
||||
ngx.status = 202
|
||||
ngx.header["X-Cookie"] = ngx.req.get_headers()["Cookie"] .. "-d"
|
||||
ngx.header["X-HeaderD"] = ngx.req.get_headers()["OuterHeader"] .. "-d"
|
||||
}
|
||||
}
|
||||
--- request
|
||||
|
Loading…
Reference in New Issue
Block a user