這是一個ngx_http_module_t類型的靜態變量。這個變量實際上是提供一組回調函數指針,這些函數有在創建存儲配置信息的對象的函數,也有在創建前和創建后會調用的函數。這些函數都將被nginx在合適的時間進行調用。
[](http:// "點擊提交Issue,反饋你的意見...")
typedef struct {
ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
void *(*create_main_conf)(ngx_conf_t *cf);
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
void *(*create_srv_conf)(ngx_conf_t *cf);
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
void *(*create_loc_conf)(ngx_conf_t *cf);
char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;
<table class="docutils field-list" frame="void" rules="none" style="margin: 0px -0.5em; border: 0px; color: rgb(0, 0, 0); font-family: 'segoe UI', sans-serif; letter-spacing: -0.1599999964237213px; line-height: 24px; white-space: normal; background-color: rgb(255, 255, 255);"><colgroup><col class="field-name"/><col class="field-body"/></colgroup><tbody valign="top"><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">preconfiguration:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">在創建和讀取該模塊的配置信息之前被調用。</td></tr><tr class="field-even field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">postconfiguration:</th></tr><tr class="field-even field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">在創建和讀取該模塊的配置信息之后被調用。</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">create_main_conf:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">調用該函數創建本模塊位于http block的配置信息存儲結構。該函數成功的時候,返回創建的配置對象。失敗的話,返回NULL。</td></tr><tr class="field-even field"><th class="field-name" style="padding: 1px 8px 1px 5px; border: 0px !important;">init_main_conf:</th><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">調用該函數初始化本模塊位于http block的配置信息存儲結構。該函數成功的時候,返回NGX_CONF_OK。失敗的話,返回NGX_CONF_ERROR或錯誤字符串。</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">create_srv_conf:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;"/><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">調用該函數創建本模塊位于http server block的配置信息存儲結構,每個server block會創建一個。該函數成功的時候,返回創建的配置對象。失敗的話,返回NULL。</td></tr><tr class="field-even field"><th class="field-name" style="padding: 1px 8px 1px 5px; border: 0px !important;">merge_srv_conf:</th><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">因為有些配置指令既可以出現在http block,也可以出現在http server block中。那么遇到這種情況,每個server都會有自己存儲結構來存儲該server的配置,但是在這種情況下http block中的配置與server block中的配置信息發生沖突的時候,就需要調用此函數進行合并,該函數并非必須提供,當預計到絕對不會發生需要合并的情況的時候,就無需提供。當然為了安全起見還是建議提供。該函數執行成功的時候,返回NGX_CONF_OK。失敗的話,返回NGX_CONF_ERROR或錯誤字符串。</td></tr><tr class="field-odd field"><th class="field-name" colspan="2" style="padding: 1px 8px 1px 5px; border: 0px !important;">create_loc_conf:</th></tr><tr class="field-odd field"><td style="padding: 1px 8px 1px 5px; border: 0px !important;">?</td><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">調用該函數創建本模塊位于location block的配置信息存儲結構。每個在配置中指明的location創建一個。該函數執行成功,返回創建的配置對象。失敗的話,返回NULL。</td></tr><tr class="field-even field"><th class="field-name" style="padding: 1px 8px 1px 5px; border: 0px !important;">merge_loc_conf:</th><td class="field-body" style="padding: 1px 8px 1px 5px; border: 0px !important;">與merge_srv_conf類似,這個也是進行配置值合并的地方。該函數成功的時候,返回NGX_CONF_OK。失敗的話,返回NGX_CONF_ERROR或錯誤字符串。</td></tr></tbody></table>
Nginx里面的配置信息都是上下一層層的嵌套的,對于具體某個location的話,對于同一個配置,如果當前層次沒有定義,那么就使用上層的配置,否則使用當前層次的配置。
這些配置信息一般默認都應該設為一個未初始化的值,針對這個需求,Nginx定義了一系列的宏定義來代表各種配置所對應數據類型的未初始化值,如下:
#define NGX_CONF_UNSET ? ? ? -1
#define NGX_CONF_UNSET_UINT ?(ngx_uint_t) -1
#define NGX_CONF_UNSET_PTR ? (void *) -1
#define NGX_CONF_UNSET_SIZE ?(size_t) -1
#define NGX_CONF_UNSET_MSEC ?(ngx_msec_t) -1
又因為對于配置項的合并,邏輯都類似,也就是前面已經說過的,如果在本層次已經配置了,也就是配置項的值已經被讀取進來了(那么這些配置項的值就不會等于上面已經定義的那些UNSET的值),就使用本層次的值作為定義合并的結果,否則,使用上層的值,如果上層的值也是這些UNSET類的值,那就賦值為默認值,否則就使用上層的值作為合并的結果。對于這樣類似的操作,Nginx定義了一些宏操作來做這些事情,我們來看其中一個的定義。
#define ngx_conf_merge_uint_value(conf, prev, default) ? ? ? ? ? ? ? ? ? ? ? \
? ?if (conf == NGX_CONF_UNSET_UINT) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
? ? ? ?conf = (prev == NGX_CONF_UNSET_UINT) ? default : prev; ? ? ? ? ? ? ? \
? ?}
顯而易見,這個邏輯確實比較簡單,所以其它的宏定義也類似,我們就列具其中的一部分吧。
[](http:// "點擊提交Issue,反饋你的意見...")
ngx_conf_merge_valuengx_conf_merge_ptr_valuengx_conf_merge_uint_valuengx_conf_merge_msec_valuengx_conf_merge_sec_value
等等。
下面來看一下hello模塊的模塊上下文的定義,加深一下印象。
[](http:// "點擊提交Issue,反饋你的意見...")
static ngx_http_module_t ngx_http_hello_module_ctx = {
NULL, /* preconfiguration */
ngx_http_hello_init, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_http_hello_create_loc_conf, /* create location configuration */
NULL /* merge location configuration */
};
**注意:這里并沒有提供merge_loc_conf函數,因為我們這個模塊的配置指令已經確定只出現在NGX_HTTP_LOC_CONF中這一個層次上,不會發生需要合并的情況。**
- 上篇:nginx模塊開發篇
- nginx平臺初探
- 初探nginx架構
- nginx基礎概念
- connection
- request
- keepalive
- pipe
- lingering_close
- 基本數據結構
- ngx_str_t
- ngx_pool_t
- ngx_array_t
- ngx_hash_t
- ngx_hash_wildcard_t
- ngx_hash_combined_t
- ngx_hash_keys_arrays_t
- ngx_chain_t
- ngx_buf_t
- ngx_list_t
- ngx_queue_t
- nginx的配置系統
- 指令參數
- 指令上下文
- nginx的模塊化體系結構
- 模塊的分類
- nginx的請求處理
- handler模塊
- handler模塊簡介
- 模塊的基本結構
- 模塊配置結構
- 模塊配置指令
- 模塊上下文結構
- 模塊的定義
- handler模塊的基本結構
- handler模塊的掛載
- handler的編寫步驟
- 示例: hello handler 模塊
- handler模塊的編譯和使用
- 更多handler模塊示例分析
- http access module
- http static module
- http log module
- 過濾模塊
- 過濾模塊簡介
- 過濾模塊的分析
- upstream模塊
- upstream模塊
- upstream模塊接口
- memcached模塊分析
- 本節回顧
- 負載均衡模塊
- 配置
- 指令
- 鉤子
- 初始化配置
- 初始化請求
- peer.get和peer.free回調函數
- 本節回顧
- 其他模塊
- core模塊
- event模塊
- 模塊開發高級篇
- 變量
- 下篇:nginx原理解析篇
- nginx架構詳解
- nginx的源碼目錄結構
- nginx的configure原理
- 模塊編譯順序
- nginx基礎設施
- 內存池
- nginx的啟動階段
- 概述
- 共有流程
- 配置解析
- nginx的請求處理階段
- 接收請求流程
- http請求格式簡介
- 請求頭讀取
- 解析請求行
- 解析請求頭
- 請求體讀取
- 讀取請求體
- 丟棄請求體
- 多階段處理請求
- 多階段執行鏈
- POST_READ階段
- SERVER_REWRITE階段
- FIND_CONFIG階段
- REWRITE階段
- POST_REWRITE階段
- PREACCESS階段
- ACCESS階段
- POST_ACCESS階段
- TRY_FILES階段
- CONTENT階段
- LOG階段
- Nginx filter
- header filter分析
- body filter分析
- ngx_http_copy_filter_module分析
- ngx_http_write_filter_module分析
- subrequest原理解析
- https請求處理解析
- 附錄A 編碼風格
- 附錄B 常用API
- 附錄C 模塊編譯,調試與測試