版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、手把手教你开发Nginx模块前面的哪些话关于Nginx模块开发的博客资料,网上很多,很多。但是,每篇博客都只提要点,无法step by step照着做,对于初次接触Nginx开发的同学,只能像只盲目的蚂蚁瞎燥急!该篇文章没有太多技术深度,只是一步一步说明白Nginx模块的开发过程。开发环境搭建工欲善其事,必先利其器。个人推荐Eclipse CDT 作为IDE,原因很简单,代码提示与补全功能很全,完胜Codeblock这类.相信与否,试过就知道。在ubuntu下搭建开发环境:安装GCC编译器apt-get install build-essential安装pcre/openssl/zlib开发库
2、apt-get install libpcre3-devapt-get install libssl-devapt-get install libzip-dev必需安装nginx核心模块依赖的pcre,openssl,zilib开发库安装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.tar.gz & tzr -
3、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:/root/Workspace/nginx-1.10.1/src
4、/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 添加环境变量,创建C项目时自动作为-I选项imageimageNginx模块编译流程Nginx使用configure脚本分析环境,自动生成objs结果。哪么configure如何编译第三方模块?答案是-add-module指定第三方模块目录,并将目录存为$ngx_addon_dir环境变量。执行$ngx_addon_dir/config脚本,读取模
5、块配置。在config中的环境变量分为2种:小写的本地环境变量,大写的全局环境变量。例如: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.cCORE_LIBS=$CORE_LIBS -lpcreHTTP_MODULES中的ngx_http_mytest_module就是NGX_ADDON_SRCS中源码(如果有多个,都要写上)ngx_
6、http_mytest_module.c中定义的ngx_module_t类型的全局变量。可见,第三方模块的入口点就是ngx_module_t类型全局变量,该变量又关联ngx_http_module_t类型static变量,与ngx_command_t类型static数组。在ngx_http_module_t中定义上下文配置nginx.conf解析的回调方法。在ngx_command_t中定义配置项处理的set回调方法。Nginx的全部操作都是异步的。在上述的方法中根据需要又会使用其他handler方法。以上可以看成Nginx第三方模块的起式。Upstream例子源码configngx_addo
7、n_name=ngx_http_mytest_moduleHTTP_MODULES=$HTTP_MODULES ngx_http_mytest_moduleNGX_ADDON_SRCS=$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c源代码#include #include #include #include typedef struct ngx_http_upstream_conf_t upstream; mytest_conf_t;typedef struct ngx_http_status_t status; ngx_str_
8、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, void *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
9、_t *r);static ngx_int_t mytest_upstream_process_header(ngx_http_request_t *r);static void mytest_upstream_finalize_request(ngx_http_request_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_m
10、odule_t mytest_ctx = NULL, NULL, NULL, NULL, NULL, NULL, mytest_create_loc_conf, mytest_merge_loc_conf;static ngx_command_t mytest_commands = 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, NUL
11、L , ngx_null_command;ngx_module_t ngx_http_mytest_module = NGX_MODULE_V1, &mytest_ctx, mytest_commands, NGX_HTTP_MODULE, 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
12、(X-Accel-Expires), ngx_string(X-Accel-Redirect), ngx_string(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
13、(mycf = NULL) return 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.buffer_size = ng
14、x_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_PTR; return mycf;static char *myte
15、st_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; if(ngx_http_upstream_hide_headers_hash(cf,&con
16、f-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(GET /search?q=%V HTTP/1.1rnHost: .hkrnConnection: closernrn); ngx_in
17、t_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, queryLineLen, (char *)backendQueryLine.data, &r-args); r-upstream-request_bufs = ngx_alloc_chain_link(
18、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-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) si
19、ze_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 = NULL) 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_
20、ERR, r-connection-log, 0, upstream sent to valid HTTP/1.0 header); r-http_version = NGX_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_lin
21、e.len = len; u-headers_in.status_line.data = 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_i
22、nt_t mytest_upstream_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
23、 = NGX_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-key.len + 1 + h-value.len + 1 + h-key.len); if(h-k
24、ey.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-key.datah-key.len=0; ngx_memcpy(h-value.data, r-header_start, h-value.len); h-value.datah-value.len = 0
25、; 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-key.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
26、 = NGX_HTTP_PARSE_HEADER_DONE) if(r-upstream-headers_in.server = NULL) h = ngx_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-value); h-lowcase_key = (
27、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_str_set(&h-key, Date); ngx_str_null(&h-value); h-lowcase_key = (u_char *)date; return NGX_OK; if(rc = NGX_AG
28、AIN) return NGX_AGAIN; ngx_log_error(NGX_LOG_ERR, r-connection-log, 0, upstream sent invalid header); return NGX_HTTP_UPSTREAM_FT_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_finali
29、ze_request);static char *mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_core_loc_conf_t *clcf; 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 *my
30、ctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module); if(myctx = NULL) myctx = ngx_pcalloc(r-pool, 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,
31、ngx_http_upstream_create() failed); return NGX_ERROR; mytest_conf_t *mycf = (mytest_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
32、_pcalloc(r-pool, sizeof(ngx_http_upstream_resolved_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 = NUL
33、L) ngx_log_error(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_addr = inet
34、_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-resolved-naddrs = 1; u-create_request = mytest_up
35、stream_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-resolved-port = htons(in_port_t)80);”,否则报错“2016/09/09 11:24:18 error 28352#0: *1 no
36、 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/nginx-modules/ngx_http_mytest_module -with-debugsudo makesudo make install安装后即可到/usr/local/nginx下配置nginx.conf进行测试。Subre
37、quest例子源码configngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES=$HTTP_MODULES ngx_http_mytest_moduleNGX_ADDON_SRCS=$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c源代码#include #include #include typedef struct ngx_str_t stock6; mytest_ctx_t;static ngx_int_t mytest_subrequest_post_handler(ngx_h
38、ttp_request_t *r, void *data, ngx_int_t rc);static void mytest_post_handler(ngx_http_request_t *r);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_conf = NULL, NULL, NULL, NULL, NULL, NULL, NUL
39、L, NULL;static ngx_command_t mytest_commands = ngx_string(mytest), NGX_HTTP_MAIN_CONF | NGX_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_M
40、ODULE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NGX_MODULE_V1_PADDING;static ngx_int_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
41、= r-headers_out.status; if (r-headers_out.status = NGX_HTTP_OK) int flag = 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; flag+;
42、 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); return; mytest_ctx_t *myctx =
43、 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.content_length_n = bodylen; ngx_buf_t *b = ngx_create_temp_
44、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(text/plain; charset=GBK); r-headers_out.content_type = type; r-hea
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度宾馆酒店客房租赁及收益分成及品牌授权合同2篇
- 二零二五年房产租赁押金返还与住房按揭贷款保全合同3篇
- 二零二五年环保产业投资合作合同范本集2篇
- 二零二五年度绿色建筑安装工程合同范本2篇
- 二零二五版教育局教师幼儿园劳动合同履行评估标准3篇
- 二零二五年度板材行业风险管理与保险合同2篇
- 展会参展商信息收集合同(2篇)
- 2025年度浙江房产市场风险防范7月1日实施合同3篇
- 二零二五版工业项目总承包监理服务合同范本3篇
- 二零二五版混凝土工程数字化管理与优化合同3篇
- 2025年西藏拉萨市柳梧新区城市投资建设发展集团有限公司招聘笔试参考题库附带答案详解
- 2025年部编版一年级语文上册期末复习计划
- 2024年新高考II卷数学高考试卷(原卷+答案)
- 储罐维护检修施工方案
- 地理2024-2025学年人教版七年级上册地理知识点
- 2024 消化内科专业 药物临床试验GCP管理制度操作规程设计规范应急预案
- 2024-2030年中国电子邮箱行业市场运营模式及投资前景预测报告
- 基础设施零星维修 投标方案(技术方案)
- 人力资源 -人效评估指导手册
- 大疆80分钟在线测评题
- 2024届广东省广州市高三上学期调研测试英语试题及答案
评论
0/150
提交评论