nginx 记录完整的 request 及 response
前言
在开发的过程中, 经常会有抓包的需求, 查看请求体和响应体. 使用 charles
等抓包工具会遇到一些麻烦, 如:
- localhost 请求无法捕获
- 有些工具配置代理比较麻烦, 如
docker
配置代理后需要重启 https
协议需要代理端配置证书进行解密, 比较麻烦
于是, 我就在想, 能否直接在服务端将所有的请求体和响应体打印出来, 不就完美解决这个问题了么?
一般来说, 通过nginx
代理请求, 所有的请求都过nginx
, nginx
自身也有https
的私钥, 会进行解密.
那么问题来了, 如何通过nginx
打印请求呢?
中间探索的过程就不提了, 直接上结果.
lua打印
这里直接使用openresty/openresty
镜像了, 当然如果直接使用nginx
编译lua
插件也是可以的.
在配置文件中添加如下lua
脚本以打印完整请求内容:
# 将请求信息暂存, 放到最后一起打印
access_by_lua_block {
ngx.req.read_body()
local req_body = ngx.req.get_body_data()
local req_uri = ngx.var.request_uri
if req_body and #req_body > 1024 * 1024 then
req_body = "Request too large"
end
if not req_body then
req_body = "No request body"
end
local headers = ngx.req.get_headers()
local header_str = ""
for k, v in pairs(headers) do
header_str = header_str .. string.format("%s: %s\n", k, v)
end
ngx.ctx.req_info = {
uri = req_uri,
body = req_body,
headers = header_str
}
}
body_filter_by_lua_block {
local resp_body = ngx.arg[1]
local req_info = ngx.ctx.req_info or {}
local req_uri = req_info.uri or "Unknown URI"
local req_body = req_info.body or "Unknown Request Body"
local req_headers = req_info.headers or "Unknown Headers"
local resp_headers = ngx.resp.get_headers()
local resp_header_str = ""
for k, v in pairs(resp_headers) do
resp_header_str = resp_header_str .. string.format("%s: %s\n", k, v)
end
ngx.log(ngx.ERR, string.format(
"Request URI: %s\nRequest Headers:\n%sRequest Body: %s\nResponse Headers:\n%sResponse Body: %s",
req_uri,
req_headers,
req_body,
resp_header_str,
resp_body or "No response body"
))
}
这段逻辑在location
中.
完整内容可参考: https://github.com/hujingnb/docker_composer/tree/master/openresty
简单记录一下, 以方便后续获取请求使用