这段时间正在学习nginx源码,看到一贴子的提问 (帖子:http://www.oschina.net/question/2711991_2165566?p=1#AnchorAnswer1114315),决定试试能不能搞定。
这个帖子的主要问题是,自己写的第三方模块,不能使用gzip压缩,nginx自带模块使用正常。
对nginx 熟悉的大牛,估计一眼就能看出问题所在,对于我这种小菜,比对了helloworld模块跟status模块,也没看出问题所在,只能用绝招跟踪两个模块的源码。
nginx是多个work进程,为了方便调试,把修改nginx.conf配置文件,只启用1个work进程。
现在是status模块可以gzip, helloword模块不能gzip, 说明gzip模块的配置是正确,初步怀疑是helloword模块中的某些参数配置不正确,导致没有调用到gzip。
查看ngx_http_gzip_filter_module.c代码,ngx_http_gzip_header_filter()函数为此模块的handle函数。
ps -ef|grep nginx 查看nginx进程号,
32259 为nginx工作进程号。
gdb attach 32259 启动gdb 附加到此进程
b ngx_http_gzip_header_filter 打断点,到此函数,
使用curl给nginx 发信息,
curl -I -H"accept-encoding:gzip" "http://127.0.0.1/hello_world"
gdb 能断到此函数,说明能进入gzip模块。
然后单步运行,发现在这句(return ngx_http_next_header_filter(r);)返回了,并没有继续执行。
之后使用curl -I -H"accept-encoding:gzip" "http://127.0.0.1/nginx-status" 发送,并没有在此位置退出,说明是上面判断条件成立,使helloword模块返回了。
单步跟踪之后是ngx_http_test_content_type(r, &conf->types) == NULL条件成立,于是根据此函数进去,发现没有进入for循环,p len 为0, 顾发现content_type_len 没有设置。
在helloworld模块中,添加:r->headers_out.content_type_len = sizeof("text/plain") - 1;
由于要使用压缩,在helloworld 模块,不能指定content_length, 删掉 r->headers_out.content_length_n = content_length;
重新编译源码,测试发送:
此处应有掌声 -_-
————————————————————————————————————————
由于水平有限,文章中有错误在所难免,请大家包含并指教,谢谢!