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

2023-10-30

/**
 * 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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nginx源码分析--状态机执行 的相关文章

随机推荐

  • 基于Springboot的SSO单点登陆系统的登陆操作实战

    一 前言 1 使用环境 SpringBoot2 X MyBatis 基于redis存储的springSession 2 基础学习 关于SSO的基础学习可以参考该文章 单点登录 SSO 从原理到实现 代码风格使用的是晓风轻的代码规范 对于其中
  • c语言的文法,c语言实现First文法

    最近编译原理课程实验做LL 1 中的First和Follow文法的算法实现 百度了半天 要么是要钱 要么是觉得好复杂 作为学渣的我看不懂 那为了完成实验 只能自己慢慢搞出来 由于之前的课也没怎么听 研究这两个文法都用了好长时间 那么关于Fi
  • Maven下Druid连接池配置及使用

    1 在pom xml中导入架包及jdbc架包
  • 如何做一个成功的系统架构师

    首先 何谓系统架构师 IBM工程师的说明是 架构师的主要责任是提供开发人员和项目经理之间的共用沟通媒体 他们负责让业务规则及需求与工程实践及限制相适应 以确保成功 中文Wiki上的说明是 系统架构师负责设计系统整体架构 从需求到设计的每个细
  • Pytorch学习(3):Tensor合并、分割与基本运算

    文章目录 前言 一 合并Cat Stack 1 Cat 2 Stack 二 分割Split Chunk 1 Split 2 Chunk 三 基本运算 1 加减乘除 2 矩阵乘法mm matmul 3 幂运算 4 指数exp 对数log 5
  • 从一年开发经验的视角看如何优雅编程

    编程绝非易事 需要大家在日常工作中仔细钻研 下面我们从实际业务开发的角度来分析一下如何优雅地进行编程 简单可以总结几点 1 整体理解业务 2 从开发角度分解业务 3 结合各业务点整体分析系统结构 4 针对每一个业务点进行边界分析 5 对每个
  • 网络编程之udp学习之udp的多播(组播)和广播案例03

    概述 关于多播 广播这些我Qt相关的文章 也有讲述过 https blog csdn net weixin 44517656 article details 105950817 ip相关知识 https blog csdn net weix
  • React与Vue的区别和对比

    前言 JavaScript是世界上最流行的语言之一 React和Vue是JS最流行的两个框架 但各有优缺点 本文将详细对比两大框架 目录 前言 一 框架背景 二 框架简介 三 框架共同点 四 各自优势 五 两者区别 六 应用场景 七 总结
  • 图的遍历(DFS & BFS)详解与完整代码+走迷宫

    一 深度优先遍历 DFS 基本思想 从初始访问结点出发 先访问第一个邻接结点 然后再以该邻接结点作为初始结点 访问它的第一个邻接结点 优先向纵向挖掘深入 而不是对一个结点的所有邻接结点进行横向访问 递归过程 深度优先遍历从某个顶点出发 首先
  • 关于C语言中源码反码补码的介绍

    最近在入门课里学习了原码反码补码 有些地方理解起来还是比较困难的 所以用一篇文章来梳理一下 首先我们要考虑这三个码的作用 我们都知道 计算机在储存信息时是使用二进制的 通过电信号的有无来表示0和1 而在C语言中数字类型都是默认有符号位的 在
  • 7-17 实数四舍五入后的相加运算

    本题目实现实数保留两位小数的四舍五入存储后 再相加 输入格式 输入两个双精度实数A B 输出格式 第一行输出A B的真实值 第二行输出A B进行四舍五入后再相加后的值 输入样例 12 345 4 896 输出样例 17 241000 17
  • 746. 使用最小花费爬楼梯

    class Solution public int minCostClimbingStairs vector
  • 将n个数按从大到小输出(C语言)

    用数组存储需要排序的数 用for循环输入需要排序的数 用冒泡排序法对n个数进行排序 最后用for循环输出排好的数 输入需要排序的数 for i 0 i lt n i scanf d a i 冒泡排序法进行排序 for int j 0 j l
  • 基于改进的混沌引力常数的引力搜索算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 Matlab代码实现 4 参考文献 1 概述 本文将十张混沌图嵌入到最近提出的基于人口的
  • 第 46 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(沈阳)

    有时候 很简单的模板题 可能有人没有做出来 特指 I 到时候一定要把所有的题目全部看一遍 文章目录 B 题解 E F 题解 H I 题解 代码 J B 输入样例 3 2 1 2 1 2 3 1 输出样例 1 说明 In the first
  • qt问题之no known conversion from ... to “const QObject *“ ...

    函数体 connect socket SIGNAL readyRead this SLOT hasPendingMessage 解决办法 connect socket SIGNAL readyRead const QObject this
  • SAT&SMT

    前言 本文性质 个人学习笔记 SAT SATISFIABILITY 布尔可满足性问题 SMT Satisfiability Modulo Theories 可满足性模理论 根据哥德尔不完备定理 停机问题 莱斯定理 我们可以知道在有限时间内是
  • 基于Python的手机数据收集软件-爬虫可视化大屏Python爬虫安装数据分析与可视化计算机毕业设计

    更多项目资源 最下方联系我们 目录 一 项目技术介绍 二 项目配套文档 部分内容 资料获取 一 项目技术介绍 该项目含有源码 文档 PPT 配套开发软件 软件安装教程 项目发布教程 包运行成功以及课程答疑与微信售后交流群 送查重系统不限次数
  • Identity and Access Management - python decorators (代码)

    from functools import wraps def add greeting f wraps f def wrapper args kwargs print Hello return f args kwargs return w
  • 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