nginx获取返回内容的md5值
最近接到一个需求,需要返回请求内容的md5,为此专门调研了下实现内容md5值的方法
1、使用专门的第三方模块
2、使用支持lua的nginx实现
第一种方法需要重新编译nginx,因为这么这个第三方模块平时很少用。第二种方法github上找的解决方案使用ngx.location.capture方法但没有写具体的实现过程。第一种方案想都不用想拉,那么只剩下第二种方案,最近正在学习lua正好练练手,那么是不是只用 body_filter_by_lua_file就可以实现了!!!!!结果不行,具体看下面这张图因为返回内容是分块传输的,并且header头内容当时已经发送给客户端。所以看来是需要ngx.location.capture方法,毕竟这个方法在返回给客户端信息的时候可以接收到完整响应体。
实现思路:新建一个location,将原有请求转发到新的location(新location需要截取掉url,具体为什么见具体实现方法),在原有location中请求返回的时候算出响应体的md5值,并且增加到header中
现在演示下具体实现方法:
1、部署测试环境
新起一个http server,并且将其加到配置文件中
#nohup python -m SimpleHTTPServer 127.0.0.1:8008 &
在配置文件中新增一个loction,并验证测试
location /images {
proxy_pass http://127.0.0.1:8008;
}
测试URL:curl -svo /dev/null "https://www.centosdoc.com/image/20181216/1544934870690012.png" 访问正常
2、新增location,并在原location中设置转发,增加header头
新增location
location /testimage/ {
proxy_pass http://127.0.0.1:8008/;
}
原location中设置转发到新location中
location /image {
content_by_lua_block {
local res = ngx.location.capture("/testimage")
local headers = ngx.header
local log = ngx.log
local ERR = ngx.ERR
if res then
local contentmd5 = ngx.md5(res.body)
log(ERR, contentmd5)
#headers["Content-hash"] = contentmd5
ngx.ctx.md5 = contentmd5
end
}
header_filter_by_lua_block {
local headers = ngx.header
headers["Content-hash"] = ngx.ctx.md5
}
#proxy_pass http://127.0.0.1:8008;
}
3、测试并验证结果
# curl -svo /dev/null "https://www.centosdoc.com/image/20181216/1544934870690012.png"
* About to connect() to www.centosdoc.com port 443 (#0)
* Trying 47.93.228.41…
* Connected to www.centosdoc.com (47.93.228.41) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: CN=www.centosdoc.com
* start date: Sep 07 00:00:00 2018 GMT
* expire date: Oct 07 12:00:00 2019 GMT
* common name: www.centosdoc.com
* issuer: CN=TrustAsia TLS RSA CA,OU=Domain Validated SSL,O="TrustAsia Technologies, Inc.",C=CN
> GET /image/20181216/1544934870690012.png HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.centosdoc.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: openresty
< Date: Sun, 22 Sep 2019 09:15:38 GMT
< Content-Type: image/png
< Transfer-Encoding: chunked
< Connection: keep-alive
< Content-hash: d41d8cd98f00b204e9800998ecf8427e
<
{ [data not shown]
* Connection #0 to host www.centosdoc.com left intact
4、注意事项
-
新location 要截取URL,直接方向代理到后端根,是为了原location转发到新location后 文件路径保持一致
-
在content_by_lua_block中设置头不生效,只能将md5值转递到header_filter_by_lua_block
-
增加md5头肯定对性能有影响,避免全局设置