设为首页 收藏本站
查看: 411|回复: 0

[经验分享] nginx 模块组成

[复制链接]

尚未签到

发表于 2016-12-24 06:40:29 | 显示全部楼层 |阅读模式
编写模块,需要实现下面5个部分

  • 定义 ngx_module_t 模块结构体
  • 定义commands
  • 定义cxn
  • 实现commands里对应的实现函数
  • 实现handler函数 (command实现函数依赖handler函数)  (这个才是真正干活的)

说明各个函数部分的意义

commands
eg:

static ngx_command_t  ngx_echo_commands[] = {
{
ngx_string("echo"),  //指令名称
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, //指令适合出现位置 和 参数个数设置
ngx_echo_readconf,            //指令的回调函数.这个函数通常来替换核心模块的配置,指定自己的handler
NGX_HTTP_LOC_CONF_OFFSET,    //将数据保存在loc conf部分
offsetof(ngx_echo_loc_conf_t, ecdata), //接收的参数保存在结构体位置
NULL  //一般为空
},
ngx_null_command  //command结束标识
};

nginx提供了几个默认的转换函数:
ngx_conf_set_flag_slot:把“on”和“off”转成1和0
ngx_conf_set_str_slot:把字符串格式化为以ngx_str_t类型
ngx_conf_set_num_slot:解析数字并转换为一个整型
ngx_conf_set_size_slot:解析表示大小的值(“8k”,“1m”等)并格式化成size_t格式

commands实现函数 (command的回调函数)


  • 这个函数一般是将配置文件中相关指令的参数转化成需要的格式并存入配置结构体
  • 这个函数还将修改了核心模块配置(也就是这个location的配置),将其handler替换为我们编写的handler。这样就屏蔽了此location的默认handler,使用ngx_http_echo_handler产生HTTP响应。


static char *                                                           
ngx_http_circle_gif(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)     
{/*{{{*/                                                               
ngx_http_core_loc_conf_t  *clcf;                                    
ngx_http_circle_gif_loc_conf_t *cglcf = conf;                       
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_circle_gif_handler;                                                                                                
cglcf->enable = 1;                                                  
return NGX_CONF_OK;                                                
}/*}}}*/                                                               

context
这个机构主要是定义各个hook函数

static ngx_http_module_t  ngx_echo_module_ctx = {
NULL,           /* preconfiguration 读入配置前调用*/      ??? 全局配置读取前?
NULL,           /* postconfiguration 读入配置后调用*/     ??? 全局配置读取后?
NULL,          /* create main configuration 创建全局部分配置时调用*/
NULL,          /* init main configuration 初始化全局部分配置时调用*/
NULL,          /* create server configuration 创建虚拟主机部分时调用*/
NULL,          /* merge server configuration 与全局部分配置合并时调用*/
ngx_echo_create_loc_conf,  /* create location configuration  创建位置部分的配置时调用*/
ngx_echo_merge_loc_conf   /* merge location configuration    与主机部分配置合并时调用*/
};


create_loc_conf用于初始化一个配置结构体,如为配置结构体分配内存等工作;
merge_loc_conf用于将其父block的配置信息合并到此结构体中,也就是实现配置的继承。

handler
该函数的职责:

  • 读入模块配置
  • 处理功能业务
  • 产生HTTP header
  • 产生HTTP body

handler会接收一个ngx_http_request_t指针类型的参数,这个参数指向一个ngx_http_request_t结构体,此结构体存储了这次HTTP请求的一些信息

static ngx_int_t ngx_echo_handler(ngx_http_request_t *r)                                         
{                                                                                                
ngx_int_t     rc;                                                                           
ngx_buf_t    *b;                                                                             
ngx_chain_t   out;                                                                           
ngx_echo_loc_conf_t  *cglcf;                                                                 
cglcf = ngx_http_get_module_loc_conf(r, ngx_module_echo);                                    
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {                                          
return NGX_HTTP_NOT_ALLOWED;                                                            
}                                                                                            
if (r->headers_in.if_modified_since) {                                                      
return NGX_HTTP_NOT_MODIFIED;                                                            
}                                                                                            
r->headers_out.content_type.len = sizeof("text/html") - 1;                                   
r->headers_out.content_type.data = (u_char *) "text/html";                                   
r->headers_out.status = NGX_HTTP_OK;                                                         
r->headers_out.content_length_n = cglcf->ecdata.len;                                         
if (r->method == NGX_HTTP_HEAD) {                                                            
rc = ngx_http_send_header(r);                                                            
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {                                 
return rc;                                                                           
}                                                                                       
}
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));                                                
if (b == NULL) {                                                                             
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer.");
return NGX_HTTP_INTERNAL_SERVER_ERROR;                                                   
}
out.buf = b;  
out.next = NULL;                                                                             
b->pos = cglcf->ecdata.data;                                                                 
b->last = cglcf->ecdata.data+(cglcf->ecdata.len);                                            
b->memory = 1;                                                                              
b->last_buf = 1;                                                                             
rc = ngx_http_send_header(r);                                                               
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {                                      
return rc;                                                                              
}                                                                                            
return ngx_http_output_filter(r, &out);                                                      
}                                                                                                

  ngx-module_t
组合Nginx Module

ngx_module_t  ngx_http_circle_gif_module = {               
NGX_MODULE_V1,                                          
&ngx_http_circle_gif_module_ctx, /* module context */   
ngx_http_circle_gif_commands,   /* module directives */
NGX_HTTP_MODULE,               /* module type */        
NULL,                                     /* init master */        
NULL,                                    /* init module */        
NULL,                                   /* init process */      
NULL,                          /* init thread */        
NULL,                          /* exit thread */        
NULL,                          /* exit process */      
NULL,                          /* exit master */        
NGX_MODULE_V1_PADDING                                   
};

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-318479-1-1.html 上篇帖子: (总结)Nginx配置文件nginx.conf中文详解 下篇帖子: nginx location说明
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表