phase_handler的处理流程

1.nginx把请求的处理过程分为11个阶段
typedef enum {
NGX_HTTP_POST_READ_PHASE = 0, /* 读取请求 */

NGX_HTTP_SERVER_REWRITE_PHASE,   /* server级别的rewrite */  

NGX_HTTP_FIND_CONFIG_PHASE,      /* 根据uri查找location */  
NGX_HTTP_REWRITE_PHASE,          /* localtion级别的rewrite */  
NGX_HTTP_POST_REWRITE_PHASE,     /* server、location级别的rewrite都是在这个phase进行收尾工作的 */  

NGX_HTTP_PREACCESS_PHASE,        /* 粗粒度的access */  

NGX_HTTP_ACCESS_PHASE,           /* 细粒度的access,比如权限验证、存取控制 */  
NGX_HTTP_POST_ACCESS_PHASE,      /* 根据上述两个phase得到access code进行操作 */  

NGX_HTTP_TRY_FILES_PHASE,        /* 实现try_files指令 */  
NGX_HTTP_CONTENT_PHASE,          /* 生成http响应 */  

NGX_HTTP_LOG_PHASE               /* log模块 */  

} ngx_http_phases;
这些阶段都是按照顺序往下执行,只有在rewrite以后才会跳转到ngx_http_find_config_phase阶段进行处理
11个中只有7个可以加入用户自己定制的handler,
2.三个主要的数据结构
1》typedef struct {
/**
* 所有phase handler的数组。
*/
ngx_http_phase_handler_t *handlers;

/** 
 * server rewrite阶段的handler在ngx_http_core_main_conf_t->phase_engine.handlers数组中的下标 
 */  
ngx_uint_t                 server_rewrite_index;  

/** 
 * rewrite阶段的handler在ngx_http_core_main_conf_t->phase_engine.handlers数组中的下标 
 */  
ngx_uint_t                 location_rewrite_index;  

} ngx_http_phase_engine_t;
2》struct ngx_http_phase_handler_s {
/* 执行校验,并调用handler函数,同一个phase的handler的checker相同 */
ngx_http_phase_handler_pt checker;
/* handler函数指针 */
ngx_http_handler_pt handler;
/*
* 指向下一个phase的第一个handler在ngx_http_core_main_conf_t->phase_engine.handlers数组中的下标
*
*/
ngx_uint_t next;
};
3.初始化:
1》 先调用ngx_http_init_phases为ngx_http_core_main_conf_t->phases分配空间
2》而后调用http module的postconfiguration回调函数,每个http模块都会有该函数,在该函数中实现phase_handler的注册,模块根据自己的特点把自己的handler添加到11个阶段对应得数组中
3》而后再调用ngx_http_init_phase_handlers初始化ngx_http_core_main_conf_t->phase_engine
ngx_http_init_phase_handlers的实现:
在该函数的实现中,首先是根据ngx_http_core_main_conf_t结构体中的phases数组以及对应得rewrite阶段确定Phases_handler中handlers数组的大小,这里会给他分配存储空间,然后依次遍历每一个阶段,初始化每一个阶段的checker和next字段
调用完成以后phase handler的初始化就完成了。handler的调用是在checker中进行的
4.phase handler的调用:
在ngx_http_core_run_phases是用来跑一边phase handler的
void
ngx_http_core_run_phases(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_phase_handler_t *ph;
ngx_http_core_main_conf_t *cmcf;

cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);  

ph = cmcf->phase_engine.handlers;  

/* 遍历phase上注册的所有handler,这里是以r->phase_handler为索引组成的链表 */  
while (ph[r->phase_handler].checker) {  

    rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);  

    /* 如果一个checker返回ok,则后面的handler不会被调用 */  
    if (rc == NGX_OK) {  
        return;  
    }  
}  

}
//注意他是在checker的内部改变phase_handler的值得
4.phase handler的checker方法:
handler的返回值决定了checker的返回值,而checker的返回值决定了是否执行下一个handler
返回ngx_ok:本phase处理完,可以继续执行下一个phase的handler,checker返回ngx_again
返回ngx_declined,handler由于某种原因执行失败,但不影响本phase其他handler的执行,所以继续执行本阶段的其他handler,返回ngx_again
返回ngx_again或者ngx_done,表示请求处理完毕,checker返回ngx_ok
返回ngx_error,终结请求,释放资源
5.主要的一个checker方法ngx_http_core_content_phase
这个阶段有一个比较特殊的content_handler,如果location阶段设置了handler,那么他就是content_handler,如果有content_handler的话,那么就只执行该一个Handler,而不去执行其他的
如果没有content_handler的话,那么就去执行对应得handler,且只有该handler返回ngx_declined的时候才去往下执行,否则就返回ngx_ok.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值