headers-more: NGINX Headers More 动态模块
安装
您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:
- RedHat Enterprise Linux 7、8、9 和 10
- CentOS 7、8、9
- AlmaLinux 8、9
- Rocky Linux 8、9
- Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-headers-more
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-headers-more
通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用该模块:
load_module modules/ngx_http_headers_more_filter_module.so;
本文档描述了 nginx-module-headers-more v0.33,于 2022 年 6 月 28 日发布。
# 设置 Server 输出头
more_set_headers 'Server: my-server';
# 设置和清除输出头
location /bar {
more_set_headers 'X-MyHeader: blah' 'X-MyHeader2: foo';
more_set_headers -t 'text/plain text/css' 'Content-Type: text/foo';
more_set_headers -s '400 404 500 503' -s 413 'Foo: Bar';
more_clear_headers 'Content-Type';
# 这里是您的 proxy_pass/memcached_pass/或任何其他配置...
}
# 设置输出头
location /type {
more_set_headers 'Content-Type: text/plain';
# ...
}
# 设置输入头
location /foo {
set $my_host 'my dog';
more_set_input_headers 'Host: $my_host';
more_set_input_headers -t 'text/plain' 'X-Foo: bah';
# 现在 $host 和 $http_host 拥有它们的新值...
# ...
}
# 仅在输入头 X-Foo 已存在时替换
more_set_input_headers -r 'X-Foo: howdy';
描述
此模块允许您添加、设置或清除您指定的任何输出或输入头。
这是标准 headers 模块的增强版本,因为它提供了更多的工具,例如重置或清除 Content-Type、Content-Length 和 Server 等“内置头”。
它还允许您在使用 more_set_headers 和 more_clear_headers 指令修改输出头时,使用 -s 选项指定可选的 HTTP 状态码标准,使用 -t 选项指定可选的内容类型标准。例如,
more_set_headers -s 404 -t 'text/html' 'X-Foo: Bar';
您还可以在单个 -t 选项中指定多个 MIME 类型进行过滤。例如,
more_set_headers -t 'text/html text/plain' 'X-Foo: Bar';
切勿在 -t 选项值中使用其他参数,如 charset=utf-8;它们不会按您预期的那样工作。
输入头也可以被修改。例如
location /foo {
more_set_input_headers 'Host: foo' 'User-Agent: faked';
# 现在 $host、$http_host、$user_agent 和
# $http_user_agent 都拥有它们的新值。
}
选项 -t 在 more_set_input_headers 和 more_clear_input_headers 指令中也可用(用于请求头过滤),而 -s 选项则不允许。
与标准 headers 模块不同,此模块的指令默认将应用于所有状态码,包括 4xx 和 5xx。
指令
more_set_headers
语法: more_set_headers [-t <content-type list>]... [-s <status-code list>]... <new-header>...
默认: 无
上下文: http, server, location, location if
阶段: output-header-filter
当响应状态码与 -s 选项指定的代码匹配 并且 响应内容类型与 -t 选项指定的类型匹配时,替换(如果有)或添加(如果没有)指定的输出头。
如果未指定 -s 或 -t 或其值为空列表,则不需要匹配。因此,以下指令将 Server 输出头设置为自定义值,适用于 任何 状态码和 任何 内容类型:
more_set_headers "Server: my_server";
具有相同名称的现有响应头始终会被覆盖。如果您想逐步添加头,请使用标准 add_header 指令。
单个指令可以设置/添加多个输出头。例如
more_set_headers 'Foo: bar' 'Baz: bah';
在单个指令中允许多次出现选项。它们的值将合并在一起。例如
more_set_headers -s 404 -s '500 503' 'Foo: bar';
等同于
more_set_headers -s '404 500 503' 'Foo: bar';
新头应为以下形式之一:
Name: ValueName:Name
最后两个有效地清除头 Name 的值。
Nginx 变量在头值中是允许的。例如:
set $my_var "dog";
more_set_headers "Server: $my_var";
但由于性能考虑,变量在头键中将不起作用。
在单个 location 中允许多个设置/清除头指令,它们按顺序执行。
从上级作用域(例如,http 块或 server 块)继承的指令在 location 块中的指令之前执行。
请注意,尽管 more_set_headers 在 location if 块中是允许的,但在 server if 块中 不 允许,如下所示:
? # 这是不允许的!
? server {
? if ($args ~ 'download') {
? more_set_headers 'Foo: Bar';
? }
? ...
? }
在幕后,使用此指令及其朋友 more_clear_headers 将(延迟)注册一个输出头过滤器,以您指定的方式修改 r->headers_out。
more_clear_headers
语法: more_clear_headers [-t <content-type list>]... [-s <status-code list>]... <new-header>...
默认: 无
上下文: http, server, location, location if
阶段: output-header-filter
清除指定的输出头。
实际上,
more_clear_headers -s 404 -t 'text/plain' Foo Baz;
与
more_set_headers -s 404 -t 'text/plain' "Foo: " "Baz: ";
或
more_set_headers -s 404 -t 'text/plain' Foo Baz
完全等效。
有关更多详细信息,请参见 more_set_headers。
通配符字符 * 也可以用于头名称的末尾以指定模式。例如,以下指令有效地清除以 "X-Hidden-" 开头的 任何 输出头:
more_clear_headers 'X-Hidden-*';
* 通配符支持首次在 v0.09 中引入。
more_set_input_headers
语法: more_set_input_headers [-r] [-t <content-type list>]... <new-header>...
默认: 无
上下文: http, server, location, location if
阶段: rewrite tail
与 more_set_headers 非常相似,只是它操作的是输入头(或请求头),并且仅支持 -t 选项。
请注意,在此指令中使用 -t 选项意味着按 Content-Type 请求 头进行过滤,而不是响应头。
在幕后,使用此指令及其朋友 more_clear_input_headers 将(延迟)注册一个 rewrite phase 处理程序,以您指定的方式修改 r->headers_in。请注意,它始终在 rewrite 阶段的 末尾 运行,因此在标准 rewrite module 之后运行,并且在子请求中也有效。
如果指定了 -r 选项,则仅在头已存在的情况下将其替换为新值。
more_clear_input_headers
语法: more_clear_input_headers [-t <content-type list>]... <new-header>...
默认: 无
上下文: http, server, location, location if
阶段: rewrite tail
清除指定的输入头。
实际上,
more_clear_input_headers -t 'text/plain' Foo Baz;
与
more_set_input_headers -t 'text/plain' "Foo: " "Baz: ";
或
more_set_input_headers -t 'text/plain' Foo Baz
完全等效。
要删除所有传入请求的请求头 "Foo" 和 "Baz",无论内容类型如何,我们可以写:
more_clear_input_headers "Foo" "Baz";
有关更多详细信息,请参见 more_set_input_headers。
通配符字符 * 也可以用于头名称的末尾以指定模式。例如,以下指令有效地清除以 "X-Hidden-" 开头的 任何 输入头:
more_clear_input_headers 'X-Hidden-*';
限制
- 与标准 headers 模块不同,此模块不会自动处理
Expires、Cache-Control和Last-Modified头之间的约束。您必须自己正确处理它们,或者将此模块与 headers 模块一起使用。 - 您无法使用此模块删除
Connection响应头,因为Connection响应头是由 Nginx 核心中的标准ngx_http_header_filter_module生成的,其输出头过滤器总是在此模块的过滤器 之后 运行。实际删除Connection头的唯一方法是修补 Nginx 核心,即编辑src/http/ngx_http_header_filter_module.c文件中的 C 函数ngx_http_header_filter。
更改
此模块每个版本的更改可以从 OpenResty 包的变更日志中获取:
测试套件
此模块附带一个基于 Perl 的测试套件。 测试用例 也是 声明式的。感谢 Perl 世界中的 Test::Nginx 模块。
要在您的环境中运行它:
$ PATH=/path/to/your/nginx-with-headers-more-module:$PATH prove -r t
要使用 valgrind 的 memcheck 运行测试套件,请使用以下命令:
$ export PATH=/path/to/your/nginx-with-headers-more-module:$PATH
$ TEST_NGINX_USE_VALGRIND=1 prove -r t
如果您更改了 Nginx 服务器二进制文件,则需要终止任何 Nginx 进程,然后再运行测试套件。
由于所有测试脚本(.t 文件)都使用单个 nginx 服务器(默认情况下为 localhost:1984),因此在调用 prove 工具时指定 -jN 并行运行测试套件是没有意义的。
测试套件的某些部分还需要在构建 Nginx 时启用模块 proxy、rewrite 和 echo。
另请参阅
- 该模块开发灵感来源于 Nginx 邮件列表上的原始线程:“关于 add_header 复制的问题”(http://forum.nginx.org/read.php?2,11206,11738)。
- Nginx 邮件列表上的原始公告线程:“'headers_more' 模块:设置和清除输出头... 超过 'add'!”(http://forum.nginx.org/read.php?2,23460)。
- 关于此模块初始开发的原始 博客文章。
- 用于 Nginx 模块自动化测试的 echo module。
- 标准 headers 模块。
GitHub
您可以在 nginx-module-headers-more 的 GitHub 仓库 中找到此模块的其他配置提示和文档。