nginx开发

http://www.oschina.net/question/12_4180


配置解析

配置设定函数一般用来将配置文件中的参数传递给程序,并保存在配置结构体中。设定函数有三个入参: 

   1. 指向结构体 ngx_conf_t 的指针, 这个结构体里包含需要传递给指令的参数
   2. 指向结构体 ngx_command_t 的指针
   3. 指向模块自定义配置结构体的指针 


 设定函数会在遇到指令时执行,Nginx提供了多个函数用来保存特定类型的数据,这些函数包含有: 

    * ngx_conf_set_flag_slot: 将 "on" or "off" 转换成 1 or 0
    * ngx_conf_set_str_slot: 将字符串保存为 ngx_str_t
    * ngx_conf_set_num_slot: 解析一个数字并保存为int
    * ngx_conf_set_size_slot: 解析一个数据大小(如:"8k", "1m") 并保存为size_t 

    当然还有其他的,在core/ngx_conf_file.h中很容易查到。如果你觉得现有这些内置的函数还不能满足你,当然也可以传入自己的函数引用。 


模块上下文
    静态的ngx_http_module_t结构体,包含一大坨函数引用,用来创建和合并三段配置  (main,server,location),命名方式一般是:ngx_http_<module name>_module_ctx.  这些函数引用依次是: 

preconfiguration:

 在创建和读取该模块的配置信息之前被调用。

postconfiguration:

 在创建和读取该模块的配置信息之后被调用。

create_main_conf:

 调用该函数创建本模块位于http block的配置信息存储结构。该函数成功的时候,返回创建的配置对象。失败的话,返回NULL。

init_main_conf:调用该函数初始化本模块位于http block的配置信息存储结构。该函数成功的时候,返回NGX_CONF_OK。失败的话,返回NGX_CONF_ERROR或错误字符串。

create_srv_conf:

 调用该函数创建本模块位于http server block的配置信息存储结构,每个server block会创建一个。该函数成功的时候,返回创建的配置对象。失败的话,返回NULL。

merge_srv_conf:因为有些配置指令即可以出现在http block,也可以出现在http server block中。那么遇到这种情况,每个server都会有自己存储结构来存储该server的配置,但是在这种情况下当在http block中的配置与server block中的配置信息冲突的时候,就需要调用此函数进行合并,该函数并非必须提供,当预计到绝对不会发生需要合并的情况的时候,就无需提供。当然为了安全期间还是建议提供。该函数成功的时候,返回NGX_CONF_OK。失败的话,返回NGX_CONF_ERROR或错误字符串。

create_loc_conf:

 调用该函数创建本模块位于location block的配置信息存储结构。每个在配置中指明的location创建一个。该函数成功的时候,返回创建的配置对象。失败的话,返回NULL。

merge_loc_conf:与merge_srv_conf类似,这个也是进行配置值合并的地方。该函数成功的时候,返回NGX_CONF_OK。失败的话,返回NGX_CONF_ERROR或错误字符串。



    函数的入参各不相同,取决于他们具体要做的事情。  

    绝大多数的 handler只使用最后两个: 一个用来为特定location配置来分配内存,(叫做 ngx_http_<module  name>_create_loc_conf), 另一个用来设定默认值以及合并继承过来的配置值(叫做 ngx_http_<module  name >_merge_loc_conf)。合并函数同时还会检查配置的有效性,如果有错误,则server的启动将被挂起。


Handlers

一个handler处理的结果通常有三种情况。处理成功,处理失败(处理的时候发生了错误)或者是拒绝去处理。在拒绝处理的情况下,这个location的处理就会由默认的handler来进行处理。

 Handler一般做4件事:获取location配置;生成合适的响应;发送响应头;发送响应体。Handler有一个参数,即请求结构体。


获取location配置

这部分只需要调用 ngx_http_get_module_loc_conf,传入当前请求的结构体和模块定义即可。下面是我的circle gif handler的相关部分: 

static ngx_int_t
ngx_http_circle_gif_handler(ngx_http_request_t *r)
{
    ngx_http_circle_gif_loc_conf_t  *circle_gif_config;
    circle_gif_config = ngx_http_get_module_loc_conf(r, ngx_http_circle_gif_module);
    ...

    现在我们就可以访问之前在合并函数中设置的所有变量了。 


生成响应

发送响应体

    现在模块已经生成了一个响应,并存放在了内存中。接下来它需要将这个响应分配给一个特定的缓冲区,然后把这个缓冲区加入到链表,然后调用链表中“发送响应体”的函数。 

    链表在这里起什么作用呢?Nginx 中,handler模块(其实filter模块也是)生成响应到buffer中是同时完成的;链表中的每个元素都有指向下一个元素的指针,如果是NULL 则说明链表到头了。简单起见,我们假设只有一个buffer。 


Handler的装载

Handler的装载通过往模块启用了的指令的回调函数中添加代码来完成。

    Handler的装载通过往模块启用了的指令的回调函数中添加代码来完成。比如,我的circle gif 中ngx_command_t是这样的: 

    { ngx_string("circle_gif"),

      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,

      ngx_http_circle_gif,

      0,

      0,

      NULL }


    回调函数是里面的第三个元素,在这个例子中就是那个ngx_http_circle_gif。回调函数的参数是由指令结构体(ngx_conf_t, 包含用户配置的参数),相应的ngx_command_t结构体以及一个指向模块自定义配置结构体的指针组成的。我的circle gif模块中,这些函数是这样子的: 


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;

}

    这里可以分为两步:首先,得到当前location的“core”结构体,再分配给它一个handler。



http://wiki.nginx.org/3rdPartyModules

http://code.google.com/p/emillers-guide-to-nginx-module-chn/wiki/NginxModuleDevGuide_CHN

http://www.evanmiller.org/nginx-modules-guide.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值