Nginx 源代码笔记 - 知识点

Nginx 将 HTTP 请求处理流程分为几个阶段(PHASE)进行,每个阶段对应的 phase checker 按注册顺序逐个 调用 各模块提供的回调函数,也就是 phase handler 。针对所有请求的 phase checkerphase handler 执行顺序在 Nginx 进程启动时,在 ngx_http_init_phase_handlers 函数中定义。

下面列出 Nginx 定义的阶段,以及该阶段中 phase checker 可以处理的 phase handler 返回值。

该阶段的 phase checker 函数是 ngx_http_core_generic_phase 。各模块注册到该阶段的 phase handler 可以使用如下返回值控制请求处理流程:

错误码 处理方式
NGX_OK 将请求转入下一处理阶段(跳过本阶段还未调用的 phase handler)
NGX_DECLINED 为请求调用下一个 phase handler(可能是本阶段的,也可能是下一个阶段的)
NGX_AGAIN/NGX_DONE 需对该请求再次调用当前 phase handler
其它 错误码是 NGX_ERROR 或者 NGX_HTTP_* 等等时,提前结束当前请求

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_realip_module - Change the client address to the one sent in the specificed header field.

该阶段的 phase checker 函数为 ngx_http_core_rewrite_phase 。各模块注册到该阶段的 phase handler 可以使用如下返回值控制请求处理流程:

错误码 处理方式
NGX_DECLINED 为请求调用下一个 phase handler(可能是本阶段的,也可能是下一个阶段的)
NGX_DONE 需对该请求再次调用当前 phase handler
其它 错误码是 NGX_OK , NGX_AGAIN , NGX_ERROR 或者 NGX_HTTP_xx 等等 时,提前结束当前请求

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_rewrite_module - 执行定义于 server {}rewrite , set , if 等指令。

该阶段的 phase checker 函数为 ngx_http_core_find_config_phase 。该阶段属于 Nginx 内部流程, 不允 许模块注册 phase handler

ngx_http_core_find_config_phase 函数根据请求 uri 匹配合适的 location {} 配置块。

该阶段的 phase checker 函数为 ngx_http_core_rewrite_phase 。各模块注册到该阶段的 phase handler 可以使用的返回值和 Nginx 对这些返回值的处理方式和 SERVER_REWRITE 阶段一致。

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_rewrite_module - 执行定义于 location {}rewrite , set , if 等指令。

该阶段的 phase checker 函数为 ngx_http_core_post_rewrite_phase 。该阶段属于 Nginx 内部流程, 不 允许模块注册 phase handler

该阶段检查 REWRITE 阶段的执行结果并执行不同逻辑:如果请求 uri 被上个阶段修改过的话 ( r->uri_changed = 1 ),将此请求转到 FIND_CONFIG 阶段,重新进行 location {} 查找和匹配;如 果请求 uri 未被上个阶段修改的话,继续为请求调用 PREACCESS 阶段的 phase handler

该阶段的 phase checker 函数为 ngx_http_core_generic_phase 。各模块注册到该阶段的 phase handler 可以使用的返回值和 Nginx 对这些返回值的处理方式和 POST_READ 阶段一致。

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_limit_conn_module - limits the number of connections per the defined key, in particular, the number of of connections from a single IP address.
  • ngx_http_limit_req_module - limits the request processing rate per the defined key, in particular, the processing rate of requests coming from a single IP address.
  • ngx_http_degradation_module - returns 204 or 444 code for some locations on low memory condition.
  • ngx_http_realip_module - Change the client address to the one sent in the specificed header field.

该阶段的 phase checker 函数为 ngx_http_core_access_phase 。各模块注册到该阶段的 phase handler 可以使用如下返回值控制请求处理流程:

错误码 处理方式
r != r->main 当前请求是子请求,直接将其转入下一处理阶段
NGX_DECLINED 为请求调用下一个 phase handler(可能是本阶段的,也可能是下一个阶段的)
NGX_AGAIN/NGX_DONE 需对该请求再次调用当前 phase handler
NGX_OK
  • SATISFY_ALL: 为请求调用下一个 phase handler(可能是本阶段的,也可能是 下一个阶段的)
  • SATISFY_ANY: r->access_code 0 值,并将请求转到下一处理阶段
NGX_HTTP_FORBIDDEN
  • SATISFY_ALL: 提前结束当前请求
  • SATISFY_ANY: 将该错误码赋值给 r->access_code 变量,并为请求调用下一个 phase handler。
NGX_HTTP_UNAUTHORIZED 处理逻辑和 NGX_HTTP_FORBIDDEN 相同
其它 错误码是 NGX_ERROR 或者 NGX_HTTP_* 等等时,提前结束当前请求

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_auth_basic_module - limits access to resources by validating the user name and password using the "HTTP Basic Authentication" protocol.
  • ngx_http_access_module - limits access to certain client addresses.

该阶段的 phase checker 函数为 ngx_http_core_post_access_phase 。该阶段属于 Nginx 内部流程, 不允 许模块注册 phase handler

该阶段检查 ACCESS 阶段的处理结果并执行不同逻辑:如果 r->access_code == NGX_HTTP_FORBIDDEN 则 提 前结束该请求处理(使用 NGX_HTTP_FORBIDDEN 作为 HTTP 响应码);如果 r->access_code 为其它 非 0 值,则提前结束该请求处理;如果 r->access_code == 0 值,为请求调用下一下 phase handler

TRY_FILES (PRECONTENT)

NOTES:从 Nginx 1.13.4 开始,此阶段更名为 PRECONTENT ,并使用 ngx_http_core_generic_phase 作 为 phase checkertry_files 指令功能由模块 ngx_http_try_files_module 提供。

在 Nginx 1.13.4 之前的版本,该阶段的 phase checker 函数为 ngx_http_core_try_files_phase 。该 阶 段属于 Nginx 内部流程,不允许模块注册 phase handler

如果请求使用的 location {} 块未配置 try_files 指令,将该请求转入下一个 phase handler

如果请求使用的 location {} 中使用了 try_files 指令,那么继续检查该指令的参数:如果参数(最后 一个 参数除外)对应的磁盘静态文件存在,将静态文件内容返回给客户端;如果参数对应的磁盘静态文件都不存 在,使用函数 ngx_http_internal_redirect 将该请求重定向到 try_files 指令最后一个参数指定的 location 后, 重新处理该请求。

该阶段的 phase checker 函数为 ngx_http_core_content_phase 。各模块注册到该阶段的 phase handler 可以使用如下返回值控制请求处理流程:

错误码 处理方式
r->content_handler 如果 location {} 配置有 content handler ,使用它处理请求,并忽略其它 phase handler
NGX_DECLINED 为请求调用下一个 phase handler。如果所有 phase handler 都已经被调用过后,则结束该 请求处理过程(使用响应码: NGX_HTTP_FORBIDDEN (请求 uri 以 '/' 结束) 或者 NGX_HTTP_NOT_FOUND (请求 uri 不以 '/' 结束))
其它 结束该请求处理流程(错误码作为 ngx_http_finalize_request 函数参数使用)

从上面的分析可以看到,请求的响应数据可以由 content handler 函数或者 phase handler 函数提供。 content handler 优先级比 phase handler 高,并且具有排他性。 phase handler 可以看作是 CONTENT 阶段为请求提供的通用处理逻辑,而 content handler 是某个 location {} 块为请求提供 的 特殊处理逻辑。

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_random_index_module - processes requests ending with the slash character ('/') and picks a random file in a directory to serve as an index file.
  • ngx_http_index_module - processes requests ending with the slash character ('/').
  • ngx_http_autoindex_module - processes requests ending with the slash character ('/') and produces a directory listings.
  • ngx_http_dav_module - intended for file management automation via the WebDAV protocol. The module processes HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY, and MOVE.
  • ngx_http_gzip_static_module - allows sending precompressed files with the ".gz" filename extension instead of regular files.
  • ngx_http_static_module - 静态文件响应模块

Nginx 自带模块中提供了 content handler 的有:

  • ngx_http_fastcgi_module
  • ngx_http_scgi_module
  • ngx_http_memcached_module
  • ngx_http_proxy_module
  • ngx_http_stub_status_module
  • ngx_http_flv_module
  • ngx_http_mp4_module
  • ngx_http_empty_gif_module
  • ngx_http_perl_module
  • ngx_http_uwsgi_module

该阶段比较特殊,它并没有对应 phase checker ,该阶段的 phase handler 在请求处理结束时,由 ngx_http_log_request 函数直接调用。

Nginx 自带模块中在此阶段注册 phase handler 的模块有:

  • ngx_http_log_module
我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章