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在記憶體裡。需要結合具體情況來選擇。