
理解 ngx_http_try_files_module 的执行路径,关键不是通读全部源码,而是抓住它在 Nginx 请求处理生命周期中的**插入点、匹配逻辑和跳转机制**。它不独立运行,而是深度嵌入到 location 匹配后的 content 阶段,通过修改请求的 URI 和内部重定向来驱动后续处理。
它在哪被调用:定位到 content 阶段的 handler
该模块的核心是注册为一个 content phase handler。在 src/http/modules/ngx_http_try_files_module.c 中,ngx_http_try_files_commands 数组里定义了 try_files 指令,并最终通过 ngx_http_try_files_handler 函数挂载到 location 的 handler 字段上。当请求进入某个 location 且该 location 没有更优先的 content handler(如 index、autoindex 或 proxy_pass)时,Nginx 就会调用这个函数。
它怎么逐项检查:文件/目录存在性判断逻辑
ngx_http_try_files_handler 按照配置中 try_files 后列出的路径顺序依次尝试:
对每个路径(如 $uri、$uri/、/index.html),先做变量展开(如 $uri 替换为当前解码后的 URI 路径) 拼接 root 或 alias 路径,得到完整磁盘路径 调用 ngx_http_map_uri_to_path 获取文件系统路径,再用 ngx_open_cached_file(带缓存)或直接 stat() 检查是否存在且可访问 若检查的是目录(以 / 结尾),则额外判断是否为合法目录(st_mode & S_IFDIR)
它如何触发跳转:内部重定向与请求重入
一旦某一项检查成功(文件存在或目录可访问),模块会:
用该路径更新请求的 r->uri 和 r->args(如有查询参数) 设置 r->internal = 1 标记为内部跳转 调用 ngx_http_internal_redirect(r, &r->uri, &r->args)
这个 internal_redirect 不发 HTTP 重定向响应,而是让请求重新走一遍 location 查找流程——即再次执行 ngx_http_core_find_location,根据新 URI 匹配到对应 location,再执行其 content handler(比如静态文件服务、PHP-FPM 代理等)。这才是“try files”真正起作用的机制:不是简单返回文件,而是把控制权交还给路由系统。
它何时失败:兜底路径与 404 处理
如果所有 try_files 列出的路径都不存在,模块会处理最后一个参数:
若最后一项是 @named_location(如 try_files $uri /index.html @fallback;),则调用 ngx_http_named_location(r, &name) 跳转到命名 location 若最后一项是普通路径(如 /404.html),则同样走 internal redirect;若该路径也不存在,Nginx 最终返回 404 注意:最后一项不能是变量(如 $uri.html),否则编译期报错,因为兜底必须是确定路径或命名 location
掌握这四点,就能在调试时快速定位:加 ngx_log_debug 日志看 handler 是否被调、strace 观察 stat/openat 系统调用、用 curl -v 配合 error_log debug 看重定向过程。不需要读懂整个 core,聚焦在 handler → check → redirect 这条主线即可。

评论(0)