全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 9 分钟 ✍️ juanwangdev

请求处理与钩子函数

Nginx 请求处理基于多阶段钩子机制,模块在特定阶段挂载回调函数参与请求处理链。

HTTP 请求处理阶段

11 个标准阶段

阶段常量说明
1NGX_HTTP_POST_READ_PHASE读取请求体后
2NGX_HTTP_SERVER_REWRITE_PHASEserver 级重写
3NGX_HTTP_FIND_CONFIG_PHASE匹配 location
4NGX_HTTP_REWRITE_PHASElocation 级重写
5NGX_HTTP_POST_REWRITE_PHASE重写后处理
6NGX_HTTP_PREACCESS_PHASE访问控制前
7NGX_HTTP_ACCESS_PHASE访问权限检查
8NGX_HTTP_POST_ACCESS_PHASE访问控制后
9NGX_HTTP_PRECONTENT_PHASE内容处理前
10NGX_HTTP_CONTENT_PHASE生成响应内容
11NGX_HTTP_LOG_PHASE日志记录

阶段处理流程

C
客户端请求
  → NGX_HTTP_POST_READ_PHASE
  → NGX_HTTP_SERVER_REWRITE_PHASE
  → NGX_HTTP_FIND_CONFIG_PHASE (匹配 location)
  → NGX_HTTP_REWRITE_PHASE
  → NGX_HTTP_PREACCESS_PHASE
  → NGX_HTTP_ACCESS_PHASE (访问控制)
  → NGX_HTTP_PRECONTENT_PHASE
  → NGX_HTTP_CONTENT_PHASE (内容生成)
  → NGX_HTTP_LOG_PHASE
  → 响应返回

钩子注册机制

注册 handler

C
static ngx_int_t
ngx_http_my_init(ngx_conf_t *cf)
{
    ngx_http_handler_pt *h;
    ngx_http_core_main_conf_t *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    // 注册到 content 阶段
    h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }
    *h = ngx_http_my_handler;

    return NGX_OK;
}

请求处理函数

C
static ngx_int_t
ngx_http_my_handler(ngx_http_request_t *r)
{
    // 检查请求方法
    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }

    // 丢弃请求体
    ngx_int_t rc = ngx_http_discard_request_body(r);
    if (rc != NGX_OK) {
        return rc;
    }

    // 设置响应头
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = 12;

    ngx_str_set(&r->headers_out.content_type, "text/plain");

    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK) {
        return rc;
    }

    // 发送响应体
    ngx_buf_t *b;
    b = ngx_create_temp_buf(r->pool, 12);
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ngx_memcpy(b->pos, "Hello World!", 12);
    b->last = b->pos + 12;
    b->last_buf = 1;

    ngx_chain_t out;
    out.buf = b;
    out.next = NULL;

    return ngx_http_output_filter(r, &out);
}

handler 返回 NGX_OK 继续处理,NGX_DECLINED 跳过本模块,NGX_ERROR 终止请求。

请求结构体关键字段

ngx_http_request_t 核心字段

C
struct ngx_http_request_s {
    uint32_t                  signature;
    ngx_connection_t         *connection;       // 底层连接

    ngx_str_t                 request_line;     // 请求行
    ngx_str_t                 uri;              // URI
    ngx_str_t                 args;             // 查询参数
    ngx_str_t                 exten;            // 文件扩展名

    ngx_http_headers_in_t     headers_in;       // 请求头
    ngx_http_headers_out_t    headers_out;      // 响应头

    ngx_http_request_body_t  *request_body;     // 请求体

    unsigned                  method;           // 请求方法
    unsigned                  http_version;     // HTTP 版本

    ngx_http_phase_handler    phase_handler;    // 当前阶段
};

过滤链机制

header_filter 过滤

C
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;

static ngx_int_t
ngx_http_my_header_filter(ngx_http_request_t *r)
{
    // 检查是否已处理
    if (r->headers_out.status != NGX_HTTP_OK) {
        return ngx_http_next_header_filter(r);
    }

    // 修改响应头
    r->headers_out.content_length_n += 10;

    return ngx_http_next_header_filter(r);
}

// 初始化
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_my_header_filter;

body_filter 过滤

text
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;

static ngx_int_t
ngx_http_my_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_chain_t *cl;

    for (cl = in; cl; cl = cl->next) {
        // 处理每个 buffer
        if (cl->buf->last_buf) {
            cl->buf->last_buf = 0;
            cl->buf->last_in_chain = 1;
        }
    }

    return ngx_http_next_body_filter(r, in);
}

// 初始化
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_my_body_filter;

过滤器以链表形式执行,必须调用下一个过滤器,否则请求中断。

要点总结

  • Nginx HTTP 请求经历 11 个处理阶段,模块可注册到特定阶段
  • handler 注册到 cmcf->phases[].handlers 数组,通过 NGX_HTTP_CONTENT_PHASE 等指定阶段
  • 请求结构体 ngx_http_request_t 封装请求全量信息
  • 过滤器分 header_filter 和 body_filter 两种,形成链式调用
  • 每个过滤器必须调用下一个过滤器,否则请求中断

📝 发现内容有误?点击此处直接编辑

← 上一篇 模块配置指令解析
下一篇 → 调试与日志机制
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库