1. 程式人生 > >nginx模組開發簡要說明

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

由於通常都會需要修改http 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在記憶體裡。需要結合具體情況來選擇。