




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、手把手教你開發(fā)Nginx模塊前面的哪些話關(guān)于Nginx模塊開發(fā)的博客資料,網(wǎng)上很多,很多。但是,每篇博客都只提要點,無法"step by step"照著做,對于初次接觸Nginx開發(fā)的同學(xué),只能像只盲目的螞蟻瞎燥急!該篇文章沒有太多技術(shù)深度,只是一步一步說明白Nginx模塊的開發(fā)過程。開發(fā)環(huán)境搭建工欲善其事,必先利其器。個人推薦Eclipse CDT 作為IDE,原因很簡單,代碼提示與補全功能很全,完勝Codeblock這類.相信與否,試過就知道。在ubuntu下搭建開發(fā)環(huán)境:安裝GCC編譯器apt-get install build-essential安裝pcre/ope
2、nssl/zlib開發(fā)庫apt-get install libpcre3-devapt-get install libssl-devapt-get install libzip-dev必需安裝nginx核心模塊依賴的pcre,openssl,zilib開發(fā)庫安裝JRE/Eclipse CDTapt-get install openjdk-8-jrewget http:/ftp.yz.yamagata-u.ac.jp/pub/eclipse/technology/epp/downloads/release/neon/R/eclipse-cpp-neon-R-linux-gtk-x86_64.ta
3、r.gz && tzr -xzvf eclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz下載nginx源碼wget /download/nginx-1.10.1.tar.gz && tar -xzvf nginx-1.10.1.tar.gz配置CDT Build Environment添加變量,值Nginx src下各模塊路徑,用冒號分隔,例如:/root/Workspace/nginx-1.10.1/src/core:/root/Workspace/nginx-1.10.1/src/event:/r
4、oot/Workspace/nginx-1.10.1/src/http:/root/Workspace/nginx-1.10.1/src/mail:/root/Workspace/nginx-1.10.1/src/stream:/root/Workspace/nginx-1.10.1/src/os/unix 添加環(huán)境變量,創(chuàng)建C項目時自動作為-I選項imageimageNginx模塊編譯流程Nginx使用configure腳本分析環(huán)境,自動生成objs結(jié)果。哪么configure如何編譯第三方模塊?答案是-add-module指定第三方模塊目錄,并將目錄存為$ngx_addon_dir環(huán)境變量
5、。執(zhí)行$ngx_addon_dir/config腳本,讀取模塊配置。在config中的環(huán)境變量分為2種:小寫的本地環(huán)境變量,大寫的全局環(huán)境變量。例如:ngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_moudle.c"CORE_LIBS="$CORE_LIBS -lpcre"HTTP_
6、MODULES中的ngx_http_mytest_module就是NGX_ADDON_SRCS中源碼(如果有多個,都要寫上)ngx_http_mytest_module.c中定義的ngx_module_t類型的全局變量。可見,第三方模塊的入口點就是ngx_module_t類型全局變量,該變量又關(guān)聯(lián)ngx_http_module_t類型static變量,與ngx_command_t類型static數(shù)組。在ngx_http_module_t中定義上下文配置nginx.conf解析的回調(diào)方法。在ngx_command_t中定義配置項處理的set回調(diào)方法。Nginx的全部操作都是異步的。在上述的方法中
7、根據(jù)需要又會使用其他handler方法。以上可以看成Nginx第三方模塊的起式。Upstream例子源碼configngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"源代碼#include <ngx_config.h>#include <ngx_core.h>#in
8、clude <ngx_http.h>#include <ngx_stream.h>typedef struct ngx_http_upstream_conf_t upstream; mytest_conf_t;typedef struct ngx_http_status_t status; ngx_str_t backendServer; mytest_ctx_t;static void *mytest_create_loc_conf(ngx_conf_t *cf);static char *mytest_merge_loc_conf(ngx_conf_t *cf, v
9、oid *parent, void *child);static ngx_int_t mytest_upstream_create_request(ngx_http_request_t *r);static ngx_int_t mytest_upstream_process_status_line(ngx_http_request_t *r);static ngx_int_t mytest_upstream_process_header(ngx_http_request_t *r);static void mytest_upstream_finalize_request(ngx_http_re
10、quest_t *r, ngx_int_t rc);static ngx_int_t mytest_handler(ngx_http_request_t *r);static char *mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static ngx_http_module_t mytest_ctx = NULL, NULL, NULL, NULL, NULL, NULL, mytest_create_loc_conf, mytest_merge_loc_conf;static ngx_command_t mytest_com
11、mands = ngx_string("mytest"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, mytest, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL , ngx_null_command;ngx_module_t ngx_http_mytest_module = NGX_MODULE_V1, &mytest_ctx, mytest_commands, NGX_HTTP_MODUL
12、E, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NGX_MODULE_V1_PADDING;static ngx_str_t mytest_upstream_hide_headers = ngx_string("Date"), ngx_string("Server"), ngx_string("X-Pad"), ngx_string("X-Accel-Expires"), ngx_string("X-Accel-Redirect"), ngx_strin
13、g("X-Accel-Limit-Rate"), ngx_string("X-Accel-Buffering"), ngx_string("X-Accel-Charset"), ngx_null_string;static void *mytest_create_loc_conf(ngx_conf_t *cf) mytest_conf_t *mycf; mycf = (mytest_conf_t *)ngx_pcalloc(cf->pool, sizeof(mytest_conf_t); if(mycf = NULL) retu
14、rn NULL; mycf->upstream.connect_timeout = 60000; mycf->upstream.send_timeout = 60000; mycf->upstream.read_timeout = 60000; mycf->upstream.store_access = 0600; mycf->upstream.buffering = 0; mycf->upstream.bufs.num = 8; mycf->upstream.bufs.size = ngx_pagesize; mycf->upstream.bu
15、ffer_size = ngx_pagesize; mycf->upstream.busy_buffers_size = 2 * ngx_pagesize; mycf->upstream.temp_file_write_size = 2 * ngx_pagesize; mycf->upstream.max_temp_file_size = 1024 * 1024 *1024; mycf->upstream.hide_headers = NGX_CONF_UNSET_PTR; mycf->upstream.pass_headers = NGX_CONF_UNSET_
16、PTR; return mycf;static char *mytest_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) mytest_conf_t *prev = (mytest_conf_t *)parent; mytest_conf_t *conf = (mytest_conf_t *)child; ngx_hash_init_t hash; hash.max_size = 100; hash.bucket_size = 1024; = "proxy_headers_hash" i
17、f(ngx_http_upstream_hide_headers_hash(cf,&conf->upstream, &prev->upstream,mytest_upstream_hide_headers,&hash)!=NGX_OK) return NGX_CONF_ERROR; return NGX_CONF_OK;static ngx_int_t mytest_upstream_create_request(ngx_http_request_t *r) static ngx_str_t backendQueryLine = ngx_string(&qu
18、ot;GET /search?q=%V HTTP/1.1rnHost: .hkrnConnection: closernrn"); ngx_int_t queryLineLen = backendQueryLine.len + r->args.len - 2; ngx_buf_t *b = ngx_create_temp_buf(r->pool, queryLineLen); if(b = NULL) return NGX_ERROR; b->last = b->pos + queryLineLen; ngx_snprintf(b->pos, query
19、LineLen, (char *)backendQueryLine.data, &r->args); r->upstream->request_bufs = ngx_alloc_chain_link(r->pool); if(r->upstream->request_bufs = NULL) return NGX_ERROR; r->upstream->request_bufs->buf = b; r->upstream->request_bufs->next = NULL; r->upstream->
20、request_sent = 0; r->upstream->header_sent = 0; r->header_hash = 1; return NGX_OK;static ngx_int_t mytest_upstream_process_status_line(ngx_http_request_t *r) size_t len; ngx_int_t rc; ngx_http_upstream_t *u; mytest_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module); if(ctx = NU
21、LL) return NGX_ERROR; u = r->upstream; rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status); if(rc = NGX_AGAIN) return rc; if(rc = NGX_ERROR) ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent to valid HTTP/1.0 header"); r->http_version = NGX
22、_HTTP_VERSION_9; u->state->status = NGX_HTTP_OK; return NGX_OK; if(u->state) u->state->status = ctx->status.code; u->headers_in.status_n = ctx->status.code; len = ctx->status.end - ctx->status.start; u->headers_in.status_line.len = len; u->headers_in.status_line.d
23、ata = ngx_pcalloc(r->pool, len); if(u->headers_in.status_line.data = NULL) return NGX_ERROR; ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len); u->process_header = mytest_upstream_process_header; return mytest_upstream_process_header(r);static ngx_int_t mytest_upstrea
24、m_process_header(ngx_http_request_t *r) ngx_int_t rc; ngx_table_elt_t *h; ngx_http_upstream_header_t *hh; ngx_http_upstream_main_conf_t *umcf; umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); for(;) rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1); if(rc = NGX_
25、OK) h = ngx_list_push(&r->upstream->headers_in.headers); if(h = NULL) return NGX_ERROR; h->hash = r->header_hash; h->key.len = r->header_name_end - r->header_name_start; h->value.len = r->header_end - r->header_start; h->key.data = ngx_pcalloc(r->pool, h->k
26、ey.len + 1 + h->value.len + 1 + h->key.len); if(h->key.data = NULL) return NGX_ERROR; h->value.data = h->key.data + h->key.len + 1; h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1; ngx_memcpy(h->key.data, r->header_name_start, h->key.len); h-&g
27、t;key.datah->key.len='0' ngx_memcpy(h->value.data, r->header_start, h->value.len); h->value.datah->value.len = '0' if(h->key.len = r->lowcase_index) ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); else ngx_strlow(h->lowcase_key, h->ke
28、y.data, h->key.len); hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); if(hh && hh->handler(r, h, hh->offset)!=NGX_OK) return NGX_ERROR; continue; if(rc = NGX_HTTP_PARSE_HEADER_DONE) if(r->upstream->headers_in.server = NULL) h = n
29、gx_list_push(&r->upstream->headers_in.headers); if(h = NULL) return NGX_ERROR; h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); ngx_str_set(&h->key, "Server"); ngx_str_null(&h-&
30、gt;value); h->lowcase_key = (u_char *)"server" if(r->upstream->headers_in.date = NULL) h = ngx_list_push(&r->upstream->headers_in.headers); if(h = NULL) return NGX_ERROR; h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); ngx_s
31、tr_set(&h->key, "Date"); ngx_str_null(&h->value); h->lowcase_key = (u_char *)"date" return NGX_OK; if(rc = NGX_AGAIN) return NGX_AGAIN; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent invalid header"); return NGX_HTTP_UPSTREAM_FT_
32、INVALID_HEADER; static void mytest_upstream_finalize_request(ngx_http_request_t *r, ngx_int_t rc) ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "mytest_upstream_finalize_request");static char *mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_core_loc_conf_t *clcf
33、; clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module); clcf->handler = mytest_handler; return NGX_CONF_OK;static ngx_int_t mytest_handler(ngx_http_request_t *r) mytest_ctx_t *myctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module); if(myctx = NULL) myctx = ngx_pcalloc(r->pool,
34、 sizeof(mytest_ctx_t); if(myctx = NULL) return NGX_ERROR; ngx_http_set_ctx(r, myctx, ngx_http_mytest_module); if(ngx_http_upstream_create(r)!=NGX_OK) ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_upstream_create() failed"); return NGX_ERROR; mytest_conf_t *mycf = (mytes
35、t_conf_t *)ngx_http_get_module_loc_conf(r, ngx_http_mytest_module); ngx_http_upstream_t *u = r->upstream; u->conf = &mycf->upstream; u->buffering = mycf->upstream.buffering; u->resolved = (ngx_http_upstream_resolved_t *) ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved
36、_t); if(u->resolved = NULL) ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_pcalloc resolved error. %s", strerror(errno); return NGX_ERROR; static struct sockaddr_in backendSockAddr; struct hostent *pHost = gethostbyname(char *)".hk"); if(pHost = NULL) ngx_log_err
37、or(NGX_LOG_ERR, r->connection->log, 0, "gethostbyname fail. %s", strerror(errno); return NGX_ERROR; backendSockAddr.sin_family = AF_INET; backendSockAddr.sin_port = htons(in_port_t)80); char *pDmsIP = inet_ntoa(*(struct in_addr *)(pHost->h_addr_list0); backendSockAddr.sin_addr.s_a
38、ddr = inet_addr(pDmsIP); myctx->backendServer.data = (u_char *)pDmsIP; myctx->backendServer.len = strlen(pDmsIP); u->resolved->sockaddr = (struct sockaddr *)&backendSockAddr; u->resolved->port = htons(in_port_t)80); u->resolved->socklen = sizeof(struct sockaddr_in); u->
39、;resolved->naddrs = 1; u->create_request = mytest_upstream_create_request; u->process_header = mytest_upstream_process_status_line; u->finalize_request = mytest_upstream_finalize_request; r->main->count+; ngx_http_upstream_init(r); return NGX_DONE;注意:Nginx深入解析的demo少了這句:“u->resol
40、ved->port = htons(in_port_t)80);”,否則報錯“2016/09/09 11:24:18 error 28352#0: *1 no port in upstream "", client: , server: localhost, request: "GET /mytest?q=test HTTP/1.1", host: "localhost"”編譯腳本./configure -prefix=/usr/local/nginx -add-module=/root/Workspace/n
41、ginx-modules/ngx_http_mytest_module -with-debugsudo makesudo make install安裝后即可到/usr/local/nginx下配置nginx.conf進行測試。Subrequest例子源碼configngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_m
42、odule.c"源代碼#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>typedef struct ngx_str_t stock6; mytest_ctx_t;static ngx_int_t mytest_subrequest_post_handler(ngx_http_request_t *r, void *data, ngx_int_t rc);static void mytest_post_handler(ngx_http_request_t *r);sta
43、tic ngx_int_t mytest_handler(ngx_http_request_t *r);static char *mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static ngx_http_module_t mytest_conf = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL;static ngx_command_t mytest_commands = ngx_string("mytest"), NGX_HTTP_MAIN_CONF | NG
44、X_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS, mytest, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL , ngx_null_command;ngx_module_t ngx_http_mytest_module = NGX_MODULE_V1, &mytest_conf, mytest_commands, NGX_HTTP_MODULE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NGX_MODULE_V1_PADDING;static ngx_int_
45、t mytest_subrequest_post_handler(ngx_http_request_t *r, void *data, ngx_int_t rc) ngx_http_request_t *pr = r->parent; mytest_ctx_t *myctx = ngx_http_get_module_ctx(pr, ngx_http_mytest_module); pr->headers_out.status = r->headers_out.status; if (r->headers_out.status = NGX_HTTP_OK) int fl
46、ag = 0; ngx_buf_t *pRecvBuf = &r->upstream->buffer; for (; pRecvBuf->pos != pRecvBuf->last; pRecvBuf->pos+) if (*pRecvBuf->pos = ',' | *pRecvBuf->pos = '"') if (flag > 0) myctx->stockflag - 1.len = pRecvBuf->pos - myctx->stockflag - 1.data; f
47、lag+; myctx->stockflag - 1.data = pRecvBuf->pos + 1; if (flag > 6) break; pr->write_event_handler = mytest_post_handler; return NGX_OK;static void mytest_post_handler(ngx_http_request_t *r) if(r->headers_out.status != NGX_HTTP_OK) ngx_http_finalize_request(r,r->headers_out.status);
48、 return; mytest_ctx_t *myctx = ngx_http_get_module_ctx(r,ngx_http_mytest_module); ngx_str_t output_format = ngx_string("stock%V,Today current price:%V, volumn:%V"); int bodylen = output_format.len + myctx->stock0.len + myctx->stock1.len + myctx->stock4.len - 6; r->headers_out.c
49、ontent_length_n = bodylen; ngx_buf_t *b = ngx_create_temp_buf(r->pool, bodylen); ngx_snprintf(b->pos,bodylen,(char *)output_format.data, &myctx->stock0, &myctx->stock1, &myctx->stock4); b->last = b->pos + bodylen; b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; static ngx_str_t type = ngx_string(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 貨物運輸代理授權(quán)委托合同
- VR技術(shù)在教育培訓(xùn)行業(yè)的創(chuàng)新應(yīng)用
- 客戶往來商務(wù)信函管理規(guī)范
- 《歷史經(jīng)典著作〈紅樓夢〉閱讀教學(xué)設(shè)計》
- 產(chǎn)品采購及供應(yīng)協(xié)議規(guī)范內(nèi)容
- 高考語文復(fù)習(xí):文言文專題訓(xùn)練《莊子》
- 人才培訓(xùn)與招聘服務(wù)協(xié)議
- 中小學(xué)必讀經(jīng)典書目征文
- 古詩詞中情感與意象的探討
- 海洋工程裝備技術(shù)專業(yè)人才培養(yǎng)方案(高職)
- 天然氣培訓(xùn)課件
- 浙江杭州余杭區(qū)余杭街道招考聘用編外人員16人(必考題)模擬卷及答案
- 腹腔穿刺術(shù)(僅供參考)課件
- 教學(xué)課件:《新能源材料技術(shù)》朱繼平
- 人教版部編七年級下冊語文必背古詩文言文
- 2022年七年級初一數(shù)學(xué)希望杯競賽模擬真題含答案27屆
- 自動駕駛數(shù)據(jù)安全白皮書
- 工期定額-民用建筑
- 2020新版?zhèn)€人征信報告模板
- 云南省實驗教材信息技術(shù)三年級第一冊第13課PPT課件
評論
0/150
提交評論