zoukankan      html  css  js  c++  java
  • Nginx Http模块开发

    关于Nginx Http模块开发的文章非常少,只有Emiler的那篇关于Http模块的文章,但是那篇文章里面,并没有说到事件型的模块如何进行开发。而且文章里面提到的内容实在是让人有点意犹未尽。因此,对于Http事件型模块的开发进行了一些总结,与大家分享。但是,无论如何,要进行Nginx模块开发,最好的方法还是找到相似性较大的模块的代码进行参考,多试多看。

     
    通常,一个Http模块均是有以下的几个部分组成:
     
    1.模块配置结构体:(configure structure)
         负责存储配置项的内容,每一条配置项,均会生成一个配置结构体,可以方便模块进行配置的预处理,存储相应的结构休内容,大致结构如下:
     
    typedef struct {
    /**
         * your configuration struct members
         */
    } ngx_http_<your module>_conf_t;
     
    2.模块指令( Module Directives ) 
     
    static ngx_command_t ngx_<your module>_commands[] = {
          { ngx_string("test"),
    NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
    <your read conf function>,
    NGX_HTTP_LOC_CONF_OFFSET,
    0,
    NULL },
    ...
    ngx_null_command
    };
    结构体如下:
    struct ngx_command_t {
        ngx_str_t             name;           /* 配置中指令的文字 */
    ngx_uint_t type; /* 指明该指令可以使用的场合 */
    char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); /* 读取配置回调函数,通常对参数进行处理,并且写入到配置结构体中 */
        ngx_uint_t            conf;
    ngx_uint_t offset;
    void *post;
    };
    
    
    3.模块上下文(The Module Context)
    这个结构体主要定义了一系列的回调函数,在不同的时期进行回调
    typedef struct {
         ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
    ngx_int_t (*postconfiguration)(ngx_conf_t *cf);

    void *(*create_main_conf)(ngx_conf_t *cf);
    char *(*init_main_conf)(ngx_conf_t *cf, void *conf);

    void *(*create_srv_conf)(ngx_conf_t *cf);
    char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

    void *(*create_loc_conf)(ngx_conf_t *cf);
    char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
    } ngx_http_module_t;

    进行阶段handler的开发,则需要在postconfiguration的时期将handler插入相应的阶段。

     
    4.定义模块结构体
     
    ngx_module_t ngx_http_<module name>_module = {
          NGX_MODULE_V1, &ngx_http_<module name>_module_ctx, /* module context */
      ngx_http_<module name>_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 };
    完成这一步之后,基本上一个模块的基础已经形成。
     
     
    5.插入阶段回调函数
         为了在Http处理的阶段中加入相应的处理函数,需要在postconfigure的回调函数中进行相应的handler插入。
         以下是在http_access的模块中的代码:

    static ngx_int_t
    ngx_http_access_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_ACCESS_PHASE].handlers);
        if (h == NULL) {
            return NGX_ERROR;
        }

        *h = ngx_http_access_handler;

        return NGX_OK;
    }
     
    而ngx_http_access_handler就是在NGX_HTTP_ACCESS_PHASE中插入的handler。
     
    HTTP在处理的过程中,总共有如下若干个阶段:
     
    typedef enum {
        NGX_HTTP_POST_READ_PHASE = 0,

        NGX_HTTP_SERVER_REWRITE_PHASE,

        NGX_HTTP_FIND_CONFIG_PHASE,
        NGX_HTTP_REWRITE_PHASE,
        NGX_HTTP_POST_REWRITE_PHASE,

        NGX_HTTP_PREACCESS_PHASE,

        NGX_HTTP_ACCESS_PHASE,
        NGX_HTTP_POST_ACCESS_PHASE,

        NGX_HTTP_TRY_FILES_PHASE,
        NGX_HTTP_CONTENT_PHASE,

        NGX_HTTP_LOG_PHASE
    } ngx_http_phases;
     
    如果觉得phases不够用,可以在nginx的代码中进行加入自己的阶段。
     
    这种处理方法,可以在Nginx作为proxy转发之前,加入自己的handler进行一些处理,相当的实用。
     
    不同阶段的处理方法不同,具体的方法可以参考ngx_http_core_module.c中的相应checker函数。
  • 相关阅读:
    hdu1240 bfs 水题
    hdu 2102 BFS
    gym 101081E Polish Fortress 几何
    Gym 101081K Pope's work dp
    hdu 6188 贪心
    hdu 6186 水
    Codeforces Round #430 (Div. 2) A B 水 C dfs,思维 D trie,二进制
    hdu6152 拉姆齐定理
    hdu6165 缩点,dfs
    hdu6153 扩展KMP
  • 原文地址:https://www.cnblogs.com/lidabo/p/4177213.html
Copyright © 2011-2022 走看看