SSI是一种轻量级服务端解释机制,语法为;Nginx中需编译开启--with-http_ssi_module、配置ssi on且响应满足Content-Type匹配、未压缩等条件才触发解析。

NGINX 的 ngx_http_ssi_filter_module 模块实现了服务端包含(SSI,Server Side Includes)功能,允许在响应内容中动态嵌入其他文件、执行命令或输出变量。它不是默认启用的模块,需编译时显式开启(--with-http_ssi_module),并在配置中通过 ssi on 启用。理解其源码实现,对定制过滤逻辑、调试 SSI 行为或开发类似内容处理模块很有帮助。
SSI 是什么?Nginx 中如何触发
SSI 是一种轻量级服务端解释机制,语法形如 <!--# include file="header.html" -->。Nginx 不会在所有响应中解析它——只有满足三个条件才会进入 SSI 过滤流程:
- 请求对应的 location 配置了
ssi on(或ssi on+ssi_types匹配到响应 MIME 类型) - 响应头中
Content-Type属于允许的类型(默认仅text/html,可通过ssi_types扩展) - 响应体由上游模块(如
ngx_http_static_module或ngx_http_proxy_module)生成且未被压缩(gzip或brotli开启时会跳过)
满足后,该模块注册的 output filter(ngx_http_ssi_filter)会被插入到 filter chain 中,在响应写入客户端前逐块扫描并解析 SSI 指令。
核心数据结构:ngx\_http\_ssi\_ctx\_t 与指令解析上下文
每个请求在首次进入 SSI 过滤时,会创建一个 ngx_http_ssi_ctx_t 结构体,挂载在 r->ctx[ngx_http_ssi_filter_module.ctx_index] 上。它保存关键状态:
-
bufs:待输出的链表缓冲区(用于暂存解析后的片段) -
state:有限状态机状态(如ssi_start_state、ssi_comment0_state、ssi_include_state等),驱动对注释块<!--# ... -->的字节流识别 -
command:当前匹配到的指令名(如"include"、"echo"、"config") -
params:指令参数哈希表(ngx_hash_t),键为参数名(如"file"、"virtual"),值为参数值 -
output:指向当前正在构造的输出链表尾部,便于增量追加解析结果
状态机是核心:它不依赖正则或完整 tokenization,而是以单字节为单位推进,高效识别 SSI 注释边界和内部结构,兼顾性能与内存友好性。
指令执行:include / echo / config 如何落地
SSI 指令并非全部同步执行。Nginx 采用“延迟求值 + 子请求”策略处理耗时操作:
-
include:若为file(本地文件),直接调用ngx_http_ssi_include_file读取并加入输出;若为virtual(如<!--# include virtual="/api/status" -->),则构造子请求(subrequest),异步发起内部 HTTP 调用,结果回调后拼接到主响应 -
echo:支持内置变量(DOCUMENT_URI、DATE_LOCAL等)和自定义变量(set var="val"定义),直接查表格式化输出,无 IO -
config:仅设置errmsg和timefmt,影响后续指令行为,不产生输出
注意:子请求受 ssi_max_recursion 限制(默认 10),防止环形包含导致栈溢出;所有子请求共享父请求的限速、超时等上下文。
实战建议:调试与安全控制
启用 SSI 时需警惕路径遍历与服务端执行风险:
- 禁用危险指令:通过
ssi指令本身无法关闭特定命令,但可借助map+if在 location 中拦截含exec cmd的请求(exec指令默认已禁用,除非显式开启ssi_exec) - 限制 include 范围:使用
root或alias明确指定根目录,避免../绕过;配合valid_referers或 IP 白名单控制子请求来源 - 调试技巧:开启
error_log ... debug并搜索"ssi"关键字,可看到状态机跳转、子请求创建、参数解析等详细日志;用curl -v观察响应头是否含X-Served-By: nginx/ssi(可手动添加)辅助验证
源码位于 src/http/modules/ngx_http_ssi_filter_module.c,主函数 ngx_http_ssi_filter 入口清晰,配合状态机宏定义(ngx_http_ssi_state_e)和指令分发表(ngx_http_ssi_commands),可快速定位任一行为逻辑。


















