跳转至

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-TypeContent-LengthServer 等“内置头”。

它还允许您在使用 more_set_headersmore_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 都拥有它们的新值。
 }

选项 -tmore_set_input_headersmore_clear_input_headers 指令中也可用(用于请求头过滤),而 -s 选项则不允许。

与标准 headers 模块不同,此模块的指令默认将应用于所有状态码,包括 4xx5xx

指令

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';

新头应为以下形式之一:

  1. Name: Value
  2. Name:
  3. Name

最后两个有效地清除头 Name 的值。

Nginx 变量在头值中是允许的。例如:

    set $my_var "dog";
    more_set_headers "Server: $my_var";

但由于性能考虑,变量在头键中将不起作用。

在单个 location 中允许多个设置/清除头指令,它们按顺序执行。

从上级作用域(例如,http 块或 server 块)继承的指令在 location 块中的指令之前执行。

请注意,尽管 more_set_headerslocation 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 模块不同,此模块不会自动处理 ExpiresCache-ControlLast-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 包的变更日志中获取:

http://openresty.org/#Changes

测试套件

此模块附带一个基于 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 时启用模块 proxyrewriteecho

另请参阅

GitHub

您可以在 nginx-module-headers-more 的 GitHub 仓库 中找到此模块的其他配置提示和文档。