nginx模块开发说明
如何开始写一个模块
参见:http://www.evanmiller.org/nginx-modules-guide.html
比较特别的有两点:
1,需要手工写一个config文件,告诉nginx如何编译你的模块
2,需要把你的模块编译进去:./configure --prefix=`pwd`/output --add-module=`pwd`/mymod
概述
所谓写nginx的module,基本上就是写handler或者filter。
handler主要是用来生成内容的,也会干点其他杂事。
filter主要是用来修改内容的。
关于handler的说明
参见:ngx_http_core_module.c
所谓handler就是在特定的phase会进行调用的回调函数。
handler的初始化在ngx_http_init_phase_handlers
handler的调用在ngx_http_core_run_phases,这个函数最初会在ngx_http_handler进行调用。
模块可以通过h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers)的方式把自己的回调函数加入到handler链表里面去。
关于http filter的说明
ngx_http_header_filter_module.c是最初的ngx_http_top_header_filter,通常会在next_header_filter的最后进行调用。它会有条件的设置content-length等字段,并调用ngx_http_write_filter()进行发送。
ngx_http_write_filter_module.c是一个特别的module,负责进行实际的发送。这个模块是最初的ngx_http_top_body_filter,通常会在next_header_filter和next_body_filter的最后进行调用。
注意:一旦调用了next_filter,就可能会一路next_filter到write_filter_module,然后如果满足了发送条件就会进行实际的数据发送;一旦数据发送,则http headers就不能再修改了。
如何读取request的各个字段做处理
可以参见:ngx_http_request_s里面的headers_in
可以搜索:r->headers_in
直接读取里面的各个字段就可以了,比如r->headers_in.cookies是cookie列表。
如何修改response header
类似的,response header位于r->headers_out,直接修改就ok了。
但是注意,修改response header必须在调用ngx_next_http_header_filter之前。
因为一旦next filter了就可能数据已经发出去了,已经发出去了的数据是没法修改的。
如何修改response body
1,用ngx_http_clear_content_length()清除content-length,然后立刻调用next_header_filter,从而使得数据以trunked的方式发送。参见:ngx_http_gzip_filter_module.c
2,在header filter里面不调next_header_filter,而是等body都处理完之后,设置了r->headers_out.content_length,再调next_header_filter。参见:ngx_http_image_filter_module.c
这两种方式各有优缺点:前者会把response变成trunked的,后者需要把response都hold在内存里。需要结合具体情况来选择。