博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nginx入门之两种handler函数的挂载方式
阅读量:6802 次
发布时间:2019-06-26

本文共 2959 字,大约阅读时间需要 9 分钟。

请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

接着上次的文章,今天研究《深入理解Nginx模块开发与架构解析》一书中给出的mytest的例子,发现和 一书中的例子不甚相同,尤其是在handler函数的挂在方面。

函数的挂载分为两种方式:

一种方式就是按处理阶段挂载;另外一种挂载方式就是按需挂载。tengine.taobao.org 中使用的挂载方式是按处理阶段挂载,而深入理解一书中的挂载方式是按需求挂载。

首先看中的例子:

由我之前 一文,handler_init就是handler函数的挂载函数,该函数在上下文结构中的postconfiguration字段被调用,决定handler函数在哪里被挂载。

1 static ngx_http_module_t ngx_http_hello_module_ctx = { 2         NULL,                          /* preconfiguration */ 3 ngx_http_hello_init, /* postconfiguration */ 4 5 NULL, /* create main configuration */ 6 NULL, /* init main configuration */ 7 8 NULL, /* create server configuration */ 9 NULL, /* merge server configuration */ 10 11 ngx_http_hello_create_loc_conf, /* create location configuration */ 12 NUL

 

1 static ngx_int_t 2 ngx_http_hello_init(ngx_conf_t *cf) 3 { 4 ngx_http_handler_pt *h; 5 ngx_http_core_main_conf_t *cmcf; 6 7 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); //取得core_module的cf 8 9 h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); // 挂载函数到对应处理阶段 10 if (h == NULL) { 11 return NGX_ERROR; 12 } 13 14 *h = ngx_http_hello_handler; //将函数指针指向handler函数 15 16 return NGX_OK; 17 }

使用这种方式挂载的handler也被称为 content phase handlers

 

 

而在《深入理解Nginx模块开发与架构解析》一书中给出的mytest的例子中,则是按需求挂载:

以这种方式挂载的handler也被称为 content handler

当一个请求进来以后,nginx从NGX_HTTP_POST_READ_PHASE阶段开始依次执行每个阶段中所有handler。执行到 NGX_HTTP_CONTENT_PHASE阶段的时候,如果这个location有一个对应的content handler模块,那么就去执行这个content handler模块真正的处理函数。否则继续依次执行NGX_HTTP_CONTENT_PHASE阶段中所有content phase handlers,直到某个函数处理返回NGX_OK或者NGX_ERROR。

换句话说,当某个location处理到NGX_HTTP_CONTENT_PHASE阶段时,如果有content handler模块,那么NGX_HTTP_CONTENT_PHASE挂载的所有content phase handlers都不会被执行了。

但是使用这个方法挂载上去的handler有一个特点是必须在NGX_HTTP_CONTENT_PHASE阶段才能执行到。如果你想自己的handler在更早的阶段执行,那就不要使用这种挂载方式。

那么在什么情况会使用这种方式来挂载呢?一般情况下,某个模块对某个location进行了处理以后,发现符合自己处理的逻辑,而且也没有必要再调用NGX_HTTP_CONTENT_PHASE阶段的其它handler进行处理的时候,就动态挂载上这个handler。

mytest这个例子在配置结构中,直接调用了content handler函数,名为ngx_http_mytest,该函数直接实现了真正的handler函数的挂载执行:

1 static ngx_command_t ngx_http_mytest_commands[] = { 2     { 3 ngx_string("mytest"), 4 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS, 5 ngx_http_mytest, 6 NGX_HTTP_LOC_CONF_OFFSET, 7 0, 8 NULL 9 }, 10 ngx_null_command 11 };

content handler函数 ngx_http_mytest的定义如下:

1 static char *  2 ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3 { 4 ngx_http_core_loc_conf_t *clcf; 5 6 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); 7 8 clcf->handler = ngx_http_mytest_handler; 9 10 return NGX_CONF_OK; 11 }

定义十分简单,主要就是一个ngx_http_conf_get_module_loc_conf函数的调用,以及一个函数指针的赋值。函数指针的赋值实现了真正的handler函数的挂载。

那么,我们来看看被调用的ngx_http_conf_get_module_loc_con函数的定义:

#define ngx_http_conf_get_module_loc_conf(cf, module)                         \    ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index]

只是一个宏定义,主要作用是将之前存储起来的conf内容调出,赋值给clcf。

联系方式:rwhsysu@163.com。

个人理解,欢迎指正。

转载于:https://www.cnblogs.com/paulweihan/p/4664784.html

你可能感兴趣的文章
1.5站立会议之个人
查看>>
remote机制的AdditionalFields
查看>>
MySQL 常用内置函数与所有内置函数
查看>>
bzoj千题计划105:bzoj3503: [Cqoi2014]和谐矩阵(高斯消元法解异或方程组)
查看>>
Mybatis学习(4)输入映射、输出映射、动态sql
查看>>
java设计模式-策略模式
查看>>
iOS随笔记录
查看>>
objective-c面向对象
查看>>
Windows 7下Git SSH 创建Key【待解决?】
查看>>
阿里云服务器Linux CentOS安装配置(七)域名解析
查看>>
最长公共前缀---简单
查看>>
课程引言作业一
查看>>
like 大数据字段 查询慢
查看>>
JSON 数据格式
查看>>
Django----解决跨域
查看>>
SQL聚合函数
查看>>
Eclipse配色方案
查看>>
字符编码,文件处理
查看>>
Nginx配置文件解析
查看>>
Deep learning:二十六(Sparse coding简单理解)
查看>>