ITPub博客

首页 > > > content handler

content handler

作者:longmanma 时间:2019-12-13 17:58:10 0 删除 编辑

一般情况下,我们自定义的模块,大多数是挂载在NGX_HTTP_CONTENT_PHASE阶段的。挂载的动作一般是在模块上下文调用的postconfiguration函数中。

注意:有几个阶段是特例,它不调用挂载地任何的handler,也就是你就不用挂载到这几个阶段了:

NGX_HTTP_FIND_CONFIG_PHASE

NGX_HTTP_POST_ACCESS_PHASE

NGX_HTTP_POST_REWRITE_PHASE

NGX_HTTP_TRY_FILES_PHASE

所以其实真正是有7个phase你可以去挂载handler。

挂载的代码如下(摘自hello module):

static ngx_int_t

ngx_http_hello_init(ngx_conf_t *cf)

{

ngx_http_handler_pt *h;

ngx_http_core_main_conf_t *cmcf;

cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);

if (h == NULL) {

return NGX_ERROR;

}

*h = ngx_http_hello_handler;

return NGX_OK;

}

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

按需挂载

以这种方式挂载的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。

下面来看一下使用这种挂载方式的具体例子(摘自Emiller’s Guide To Nginx Module Development)。

static char *

ngx_http_circle_gif(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 = ngx_http_circle_gif_handler;

return NGX_CONF_OK;

}

handler的编写步骤

好,到了这里,让我们稍微整理一下思路,回顾一下实现一个handler的步骤:

编写模块基本结构。包括模块的定义,模块上下文结构,模块的配置结构等。

实现handler的挂载函数。根据模块的需求选择正确的挂载方式。

编写handler处理函数。模块的功能主要通过这个函数来完成。

看起来不是那么难,对吧?还是那句老话,世上无难事,只怕有心人! 现在我们来完整的分析前面提到的hello handler module示例的功能和代码。

示例: hello handler 模块

在前面已经看到了这个hello handler module的部分重要的结构。该模块提供了2个配置指令,仅可以出现在location指令的作用域中。这两个指令是hello_string, 该指令接受一个参数来设置显示的字符串。如果没有跟参数,那么就使用默认的字符串作为响应字符串。

另一个指令是hello_counter,如果设置为on,则会在响应的字符串后面追加Visited Times:的字样,以统计请求的次数。

这里有两点注意一下:

对于flag类型的配置指令,当值为off的时候,使用ngx_conf_set_flag_slot函数,会转化为0,为on,则转化为非0。

另外一个是,我提供了merge_loc_conf函数,但是却没有设置到模块的上下文定义中。这样有一个缺点,就是如果一个指令没有出现在配置文件中的时候,配置信息中的值,将永远会保持在create_loc_conf中的初始化的值。那如果,在类似create_loc_conf这样的函数中,对创建出来的配置信息的值,没有设置为合理的值的话,后面用户又没有配置,就会出现问题。

下面来完整的给出ngx_http_hello_module模块的完整代码。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2730/viewspace-3153958/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: joda日期格式转换
请登录后发表评论 登录
全部评论

注册时间:2019-12-18

  • 博文量
    492
  • 访问量
    11988