实现第一个自定义nginx模块

下面的过程详细记录了如何实现第一个自定义的nginx模块,对nginx入门者包括我很有参考价值,特记录如下。

前提
假定以root身份已经在CentOS 6.8 x86上

创建第三方子模块所在目录
mkdir -p /usr/local/src/nginx_modules_demo/ngx_http_mytest_module
在里面放入如下文件,内容参见文章末尾
ngx_http_mytest_module.c
config

关闭nginx
/usr/local/nginx/sbin/nginx -s quit
ps auxf | grep nginx

源码编译生成第三方模块
./configure --with-http_ssl_module \
--with-pcre=/usr/local/src/pcre-8.40 \
--with-zlib=/usr/local/src/zlib-1.2.11 \
--with-openssl=/usr/local/src/openssl-1.1.0e \
--add-module=/usr/local/src/nginx_modules_demo/ngx_http_mytest_module
注意之后直接配置第三方模块,原有已经变化
 
make
make install

修改nginx配置文件,添加指定location块
vim /usr/local/nginx/config/nginx.config
在nginx.config中添加
location /test{  
   mytest;
}

开启nginx
/usr/local/nginx/sbin/nginx

从浏览器中访问
地址栏中输入
http://localhost/test

如何看到如下结果,说明该第三方模块ngx_http_mytest_module

ngx_http_mytest_module.c文件内容
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>    static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r);    static char *    ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);  //定义模块配置文件的处理
static ngx_command_t ngx_http_mytest_commands[] = {    {  //配置项名称  ngx_string("mytest"),   //配置项类型,即定义他可以出现的位置   NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,    //处理配置项参数的函数,函数在下面定义   ngx_http_mytest,    //在配置文件中的偏移量  NGX_HTTP_LOC_CONF_OFFSET,  //预设的解析方法配置项    0,    //配置项读取后的处理方法  NULL    },    //command数组要以ngx_null_command结束  //#define ngx_null_command {ngx_null_string,0,NULL,0,0,NULL}  ngx_null_command    };    //mytest模块上下文,都为NULL即是说在http框架初始化时没有什么要做    static ngx_http_module_t ngx_http_mytest_module_ctx = {NULL,  //preconfiguration  NULL,  //postconfiguration  NULL,  //create main configuration  NULL,  //init main configuration  NULL,  //create server configuration  NULL,  //merge server configuration  NULL,  //create location configuration  NULL  //merge location configuration  };    //对自己mytest模块的定义,在编译时加入到全局的ngx_modules数组中,这样在Nginx初始化时会调用模块的所有初始化方法,(上面的ngx_http_module_t类型的ngx_http_mytest_module_ctx)  ngx_module_t ngx_http_mytest_module = {    NGX_MODULE_V1, //由Nginx定义的宏来初始化前七个成员   &ngx_http_mytest_module_ctx,  //模块的上下文结构体,指向特定模块的公共方法  ngx_http_mytest_commands,  //处理配置项的结构体数组  NGX_HTTP_MODULE,  //模块类型  //Nginx在启动停止过程中七个执行点的函数指针  NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NGX_MODULE_V1_PADDING  //由Nginx定义的宏定义剩下的8个保留字段  };    //配置项对应的回调函数,当配置项中出现mytest配置项时将调用这个函数    static char *  ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)    {   //ckcf并不是指特定的location块内的数据结构,他可以是mian、srv、loc级别的配置项  //每个http{},sever{},location{}都有一个ngx_http_core_loc_conf_t类型的数据结构  ngx_http_core_loc_conf_t *clcf;    //找到mytest配置项所在的配置块  clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);    //http框架在处理用户请求进行到NGX_HTTP_CONTENT_PHASE阶段是,如果请求的主机名,URI与配置项所在的配置块相匹配时,就调用  //clcf中的handle方法处理这个请求  //NGX_HTTP_CONTENT_PHASE用于处理http请求内容的阶段,这是大部分http模块通常介入的阶段  clcf->handler = ngx_http_mytest_handler;    return NGX_CONF_OK;    }    //实际完成处理的回调函数    static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r)    {    //请求方法  if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) {    return NGX_HTTP_NOT_ALLOWED;    }    //不处理请求的包体,直接丢弃。但这一步也是不可省略的,他是接受包体的一种方法,只不过是简单的丢弃,  //如果不接受,客户端可能会再次试图发送包体,而服务器不接受就会造成客户端发送超时  ngx_int_t rc = ngx_http_discard_request_body(r);    if (rc != NGX_OK) {    return rc;    }    //构造响应头部  ngx_str_t type = ngx_string("text/plain");    ngx_str_t response = ngx_string("hello world ! \n\rthis is my first Nginx module test ! ");    r->headers_out.status = NGX_HTTP_OK;    r->headers_out.content_length_n = response.len;    r->headers_out.content_type = type;    //发送http头部,其中也包括响应行  rc = ngx_http_send_header(r);    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {    return rc;    }    ngx_buf_t *b;    //根据请求中传来的内存池对象,创建内存buf  b = ngx_create_temp_buf(r->pool, response.len);    if (b == NULL) {    return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    //有效内容从pos位置开始,复制respon的内容  ngx_memcpy(b->pos, response.data, response.len);    //有效内容到last结束  b->last = b->pos + response.len;    //因为ngx_buf_t可以由ngx_chain_t链表链起来,last_buf可以标记这是最后一块待处理的缓冲区,简化处理  b->last_buf = 1;    //将内存buf用链表链起来,作为ngx_http_output_filter的跌入个参数  ngx_chain_t out;    out.buf = b;    //标记这是最后一个ngx_chain_t  out.next = NULL;    return ngx_http_output_filter(r, &out);    }  

config文件的内容

#仅在configure执行时使用,一般设置为模块名称
ngx_addon_name=ngx_http_mytest_module
#HTTP_MODULES保存所有的模块名称,在重设HTTP_MODULES时不能直接覆盖,而是先取得以前的HTTP_MODULES,在加上自己的模块
HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"
#指定新增源代码文件
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"

参考文献

[1].http://blog.csdn.net/hustraiet/article/details/11519375

实现第一个自定义nginx模块相关推荐

  1. 推荐我的新书《深入理解Nginx:模块开发与架构解析》

    http://www.china-pub.com/STATIC/zt_mb/zt_huodong_2013_3.asp?filename=2013_jsj_nginx_20130401 目录 < ...

  2. Nginx模块开发入门

    前言 Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前100万的网站中,Nginx的占有率为6.8%.与Apache相比,Nginx在高并 ...

  3. 深入理解Nginx 模块开发与架构解析-陶辉 读书笔记

    前言 1. nginx是一个优秀的事件驱动框架,nginx非常适合开发在传输层以TCP对外提供服务的服务器程序.基于nginx框架开发程序有5个优势: * nginx将网络.磁盘及定时器等异步事件的驱 ...

  4. Nginx 模块开发

    Nginx 模块概述 Nginx 模块有三种角色: 处理请求并产生输出的 Handler 模块: 处理由 Handler 产生的输出的 Filter(滤波器)模块: 当出现多个后台服务器时,Load- ...

  5. Nginx 模块开发高级篇

    Nginx 模块开发高级篇 变量 综述 在Nginx中同一个请求需要在模块之间数据的传递或者说在配置文件里面使用模块动态的数据一般来说都是使用变量,比如在HTTP模块中导出了host/remote_a ...

  6. ELK学习--将自定义nginx日志写入es中并通过kibana展示为例

    今天只是记录总体思路,具体细节不展开,毕竟东西太多 学习目的 业务发展越来越庞大,服务器越来越多 各种访问日志.应用日志.错误日志量越来越多,导致运维人员无法很好的去管理日志 开发人员排查问题,需要到 ...

  7. Nginx模块开发:模块结构的源码阅读以及过滤器(Filter)模块的实现

    Nginx模块开发:模块结构的源码阅读以及过滤器(Filter)模块的实现 一.Nignx中的模块是什么? 二.模块的基本结构 `ngx_module_s` `ngx_command_s` `ngx_ ...

  8. linux rpm找不到命令_linux环境下 python环境import找不到自定义的模块

    linux环境下 python环境import找不到自定义的模块 问题现象: Linux环境中自定义的模块swport,import swport 出错.swport模块在/root/sw/目录下. ...

  9. 解决编译nginx模块与rpm包安装的nginx不兼容问题

    环境:centos  nginx-10.0.1 现象: 自己开发一个nginx模块,放到rpm包安装的nginx服务器上启动服务时报错如下: 30490#0: module "/usr/li ...

最新文章

  1. asp.net mvc发送邮件
  2. YOLOX:高性能目标检测的最新实践 | 报告详解
  3. 人工智能恶意使用报告:预测、预防和缓解
  4. ORM是什么?如何理解ORM
  5. python的装饰器、迭代器、yield_python装饰器,迭代器,生成器,协程
  6. vue的v-model绑定对象属性时,更新不及时,不能修改
  7. 2021计算机一级新增知识点,2021年计算机一级知识点.doc
  8. 一行行地读取输入行,将把最长的行打印出来
  9. 华为和新华三OSPF单区域配置
  10. chrome webstore
  11. 喜庆本博客成为CSDN博客专家
  12. 自考马克思主义原理基本概述【03709】必做选择题
  13. pdf工具类 (pd4ml)
  14. GPS定位(四)-经纬度格式转换-(互转 度转度分秒 度分秒转度……)
  15. 14----统计字符数
  16. Mac 中composer的安装
  17. 实现strStr()函数(C++)
  18. android陀螺仪惯导手机gps,推荐基于陀螺仪惯性导航的智能停车定位导航解决方案...
  19. java古诗_古诗自动生成程序JAVA
  20. 谷歌开源的跨平台UI开发框架Flutter

热门文章

  1. golang 同一个包中函数互相调用报错 undefined 以及在 VSCode 中配置右键执行整个包文件
  2. Python学习笔记第五周
  3. JSON http://www.cnblogs.com/haippy/archive/2012/05/20/2509329.html
  4. JVM系列(之ClassLoader)
  5. Google Chrome(谷歌浏览器) 发布下载
  6. java记事本环境变量_java环境变量配置以及用记事本写程序
  7. ci框架 mysql_CodeIgniter (CI)框架中的数据库查询汇总
  8. oracle本地验证,Oracle 本地验证和密码文件
  9. java web开发周志_javaweb学习笔记及周报告
  10. 属于窄带噪声的是热噪声_时钟201系列: 非相位噪声的情况 (第一篇)