phase_handler的处理流程

来源:互联网 发布:淘宝汽车配件名字大全 编辑:程序博客网 时间:2024/06/08 01:04

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.

0 0
原创粉丝点击