nginx源码分析--状态机执行

/**
 * 11个阶段处理HTTP请求
 */
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;
    /* 遍历解析和处理各个阶段的HTTP请求 如果返回rc==NGX_AGAIN 则交由下一个阶段处理;返回OK则返回结果
     * 可以看出ngx_http_request_t结构体中的phase_handler成员将决定执行到哪一个阶段,以及下一个阶段应当执行哪个http模块实现的内容。 
     */
    while (ph[r->phase_handler].checker) {

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

        if (rc == NGX_OK) {
            return;
        }
    }
}

解析:
rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler])
r->phase_handler作为 cmcf->phase_engine.handlers 数组的index 索引,在checker调用过程中,跳转下一阶段记录在r->phase_handler中,在整个while循环中,通过r->phase_handler在 cmcf->phase_engine.handlers 数组中不断跳转,返回状态rc来决定是否退出while循环。

ngx_http_core_generic_phase()是
NGX_HTTP_POST_READ_PHASE 0
NGX_HTTP_PREACCESS_PHASE 5
NGX_HTTP_TRY_FILES_PHASE 8
这三个阶段的checker,在checker中调用rc = ph->handler®,并根据rc决定r->phase_handler的值,即下一步要执行的阶段cmcf->phase_engine.handlers 数组的位置

/**
 * 内容接收阶段
 * 有3个http阶段都使用了ngx_http_core_generic_phase作为它们的checker方法,这意味着任何试图在NGX_HTTP_POST_READ_PHASE,NGX_HTTP_PREACCESS_PHASE,
 * NGX_HTTP_LOG_PHASE这3个阶段处理请求的http模块都需要了解ngx_http_core_generic_phase到底做了些什么。
 */
ngx_int_t
ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
{
    ngx_int_t  rc;

    /*
     * generic phase checker,
     * used by the post read and pre-access phases
     */

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "generic phase: %ui", r->phase_handler);
    /*调用这一阶段中各http模块添加的handler处理方法*/
    rc = ph->handler(r);
    /* 如果handler方法返回NGX_OK,之后进入下一阶段处理,而不会理会当前阶段中是否还有其他的处理方法 */
    if (rc == NGX_OK) {
        r->phase_handler = ph->next;
        return NGX_AGAIN;
    }
    /* 如果handler方法返回NGX_DECLINED,那么将进入下一个处理方法,这个处理方法既可能属于当前阶段,也可能属于下一阶段,注意返回NGX_OK和NGX_DECLINED的区别*/
    if (rc == NGX_DECLINED) {
        r->phase_handler++;
        return NGX_AGAIN;
    }
    //如果handler方法返回NGX_AGAIN或者NGX_DONE,那么当前请求将仍然停留在这一处理阶段
    if (rc == NGX_AGAIN || rc == NGX_DONE) {
        return NGX_OK;
    }

    /* rc == NGX_ERROR || rc == NGX_HTTP_...  */
    //如果handler方法返回NGX_ERROR或者类似于NGX_HTTP_ 开头的返回码,则调用ngx_http_finalize_request结束请求
    ngx_http_finalize_request(r, rc);

    return NGX_OK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值