On Tue, Mar 20, 2012 at 2:10 PM, 刘太华 <
de...@gmail.com> wrote:
> 这样说来,
> 1、nginx在处理压缩的时候,会看后端response返回的header中是否有Content-Encoding:gzip?然后才来决定是否对此次response做压缩
是的。实现细节可以参见 nginx 1.0.12 源码树中 src/http/modules/ngx_http_gzip_filter_module.c 文件的第 250 行。相关的那段代码是
if (!conf->enable
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
|| ngx_http_test_content_type(r, &conf->types) == NULL
|| r->header_only)
{
return ngx_http_next_header_filter(r);
}
即当 Content-Encoding 响应头已经存在时,ngx_gzip 的响应头过滤器会直接跳过处理,转给下一个过滤器。
> 2、 或者ngx接到后端response,解压后再次做压缩,然后发送给客户端?
>
这样做开销太大,解压和再压缩没有实际意义,只是徒耗 CPU 计算资源 :)
> 如果是1的情况,那使用ngx_lua做一些capture的时候,能碰到获取到的response压缩过的,那么此时用lua对返回的body做逻辑的时候,应该会遇到解压缩的问题?
>
一般,让使用 ngx_proxy 访问后端 http 服务,同时在 ngx_lua 中使用 capture API 时,应该显式地控制是否启用 gzip(因为默认情况下,nginx 子请求会自动继承父请求的请求头). 例如在配置了 proxy_pass 的内部 location 中通过
proxy_set_header Accept-Encoding "";
显式地禁用后端的 gzip 压缩,或者通过
proxy_set_header Accept-Encoding "gzip";
显式地启用后端压缩。看你具体的应用场景了。如果让上游 http 服务自己进行 gzip 压缩的话,在 lua 里得到的数据自然就是 gzip 压缩以后的,所以需要使用 lua 世界里的 gzip 库来解压,例如 lua-zlib 库:
https://github.com/brimworks/lua-zlib
在 ngx_lua 模块的 github issue #12 "How to handle gziped capture?" 中对此问题亦有比较完整的讨论:
https://github.com/chaoslawful/lua-nginx-module/issues/12
Best regards,
-agentzh