学习《apache源代码全景分析》之过滤器部分摘录
1.過濾器分為輸入過濾器和輸出過濾器,輸入過濾器用于修改從網(wǎng)絡(luò)讀取的數(shù)據(jù);而輸出過濾器則用于修改生成并寫入網(wǎng)絡(luò)的數(shù)據(jù)。
2.對比
? ?
? ?
3.輸入過濾器主要是對接收到的請求進行處理,它與我們正常思維一致的地方:
? ?(1) 客戶端和CORE_IN過濾器之間的數(shù)據(jù)流方向與輸出過濾器的數(shù)據(jù)方向相反。CORE向網(wǎng)絡(luò)寫入數(shù)據(jù),而CORE_IN則是從網(wǎng)絡(luò)讀取數(shù)據(jù)。
? ?(2) 數(shù)據(jù)響應(yīng)的方向也與我們想象的一致??蛻舳说臄?shù)據(jù)被CORE_IN讀取后依次經(jīng)過各個過濾器最終到達核心。
? ?唯一不同的是請求報文的方向。請求報文的讀取由“Request Processing”處發(fā)起,內(nèi)容生成器僅創(chuàng)建一個空的緩沖區(qū),然后將其傳遞到前一個過濾器,要求將其填滿。由于此時緩沖區(qū)中空無一物,因此它將繼續(xù)要求前一個過濾器填滿。這種過程直到CORE_IN過濾器位置為止。CORE_IN向網(wǎng)絡(luò)讀取數(shù)據(jù)后,填滿該緩沖區(qū),而后依次沿過濾器鏈表返回。各個過濾器依次處理。
4.對一個給定的HTTP請求,該請求在各個過濾器之間的傳遞過程如下圖:
??
5.在Apache中我們使用ap_filter_rec_t數(shù)據(jù)結(jié)構(gòu)來描述一個過濾器。
struct ap_filter_rec_t {const char *name; //過濾器名稱ap_filter_func filter_func; //過濾器對應(yīng)的回調(diào)函數(shù)ap_init_filter_func filter_init_func; //用于在過濾處理句柄被激活之前調(diào)用ap_filter_type ftype; //過濾器類型struct ap_filter_rec_t *next; //指向下一個過濾器結(jié)構(gòu)ap_filter_provider_t *provider; //2.2.6版本中提供provider概念int debug;unsigned int proto_flags; //標記當前過濾器使用的對應(yīng)的協(xié)議 };在Apache中,ap_filter_t是主要的對外展現(xiàn)的過濾器數(shù)據(jù)結(jié)構(gòu):
?
?過濾器結(jié)構(gòu)的最后一個成員是ctx,用來保存過濾器的上下文信息。
6.Apache中使用過濾器包括兩種:靜態(tài)過濾器使用和動態(tài)過濾器使用。
7.
?
8.filter_trie_node節(jié)點分配示意圖
? ?
9.過濾器注冊
? ?
? ?由于過濾器分為輸入和輸出過濾器兩種,因此最終結(jié)果江永兩棵過濾樹保存。分別是registered_input_filters和registered_output_filters表示,它們都是全局變量。
10.“face”過濾器注冊流程
? ??
? ? 實際真正的過濾器數(shù)據(jù)保存在“e”結(jié)點的frec結(jié)構(gòu)中。
11.“facd”及“fd”過濾器注冊后的結(jié)構(gòu)
? ??
12.最終的過濾器結(jié)構(gòu)
? ??
? ?所有的過濾器注冊完畢,形成一個典型的過濾器樹,如下圖:
? ? ??
13.每個請求都會關(guān)聯(lián)4個過濾器,兩個輸入過濾器和兩個輸出過濾器。
struct request_rec {......struct ap_filter_t *output_filters;struct ap_filter_t *input_filters;struct ap_filter_t *proto_output_filters;struct ap_filter_t *proto_input_filters;...... };? ?同時在連接記錄結(jié)構(gòu)conn_rec中也會看到下面的代碼:
struct conn_rec {......struct ap_filter_t *input_filters;struct ap_filter_t *output_filters;...... }? ?每個連接會關(guān)聯(lián)一個輸入過濾器和一個輸出過濾器。在請求創(chuàng)建的時候(ap_read_request函數(shù)中),請求的過濾器鏈表直接繼承連接過濾器鏈表。
? ? ?
14.任何一個過濾器,最終它都要插入到山中過濾器鏈表中的其中之一:內(nèi)容過濾器鏈表、協(xié)議過濾器鏈表、連接過濾器鏈表。
? ?(1) 內(nèi)容過濾器將被天際到內(nèi)容過濾器鏈表中,即outf = r_filters;
? ?(2) 協(xié)議過濾器將被添加到協(xié)議過濾器鏈表中,即outf=p_filters;
? ?(3) 內(nèi)容和協(xié)議之外的過濾器將被添加到連接過濾器鏈表中,即outf=c_filters.
15.ap_add_input_filter_handle()函數(shù)可以直接按照過濾器句柄進行添加。函數(shù)內(nèi)部僅僅是調(diào)用了add_any_filter而已。
16.當一個過濾器不再需要的時候,它就可以從請求或連接中被刪除。Apache中通過ap_remove_input_filter和ap_remove_output_filter函數(shù)實現(xiàn)移除的效果.
17.過濾器提供者
struct ap_filter_provider_t {/*How to match this provider to filter dispatch criterion */enum {STRING_MATCH,STRING_CONTAINS,REGEX_MATCH,INT_EQ,INT_LT,INT_LE,INT_GT,INT_GE,DEFINED} match_type;/* negation on match_type */int not;union {const char *string;ap_regex_t *regex;int number;} match;/* The filter that implements this provider */ap_filter_rec_t *frec;/* The next provider in the list */ap_filter_provider_t *next;/* Dispatch criteria for filter providers */enum {HANDLER,REQUEST_HEADERS,RESPONSE_HEADERS,SUBPROCESS_ENV,CONTENT_TYPE} dispatch;/* Match vluae for filter providers */const char *value; };18.過濾器束和請求提供者之間的關(guān)系如下圖:
? ?
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的学习《apache源代码全景分析》之过滤器部分摘录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习《apache源代码全景分析》之网络
- 下一篇: 学习《apache源代码全景分析》之存储