apache - 在 ProxyPass 中使用 Nginx 时,Apache 丢弃 ETag 标头
问题描述
今天是个好日子。我只是注意到在从 Apache 到 Nginx 使用 ProxyPass 时出现了相当奇怪的行为,让我演示一下并询问是否有人遇到过类似的事情。
最小的设置是这样的:
阿帕奇:
LogLevel trace6
SSLProxyEngine On
SSLProxyCheckPeerName Off
SSLProxyCheckPeerCN Off
<LocationMatch "\.js$">
ProxyPassMatch https://static-assets.dev.com:4430
ProxyPassReverse https://static-assets.dev.com:4430
</LocationMatch>
Nginx:
server {
listen *:4430 default_server ssl;
ssl_certificate /etc/nginx/ssl/ssl.crt;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
server_name static-assets.dev.com;
root /assets;
etag on;
gzip off;
server_tokens off;
add_header X-Hi-From-Nginx $sent_http_etag;
location / {
try_files $uri $uri/ =404;
}
}
然后在 Apache 日志中我看到:
[Thu Feb 21 14:49:18.762737 2019] [proxy_http:trace3] [pid 895:tid 139989845219072] mod_proxy_http.c(1424): [client 172.17.0.1:40486] Status from backend: 200
[Thu Feb 21 14:49:18.762744 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1099): [client 172.17.0.1:40486] Headers received from backend:
[Thu Feb 21 14:49:18.762749 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Server: nginx
[Thu Feb 21 14:49:18.762752 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Date: Thu, 21 Feb 2019 06:49:18 GMT
[Thu Feb 21 14:49:18.762759 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Content-Type: application/javascript
[Thu Feb 21 14:49:18.762762 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Content-Length: 1130146
[Thu Feb 21 14:49:18.762765 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Last-Modified: Mon, 18 Feb 2019 05:11:04 GMT
[Thu Feb 21 14:49:18.762768 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Connection: keep-alive
[Thu Feb 21 14:49:18.762771 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] ETag: "5c6a3e68-113ea2"
[Thu Feb 21 14:49:18.762773 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] X-Hi-From-Nginx: "5c6a3e68-113ea2"
[Thu Feb 21 14:49:18.762776 2019] [proxy_http:trace4] [pid 895:tid 139989845219072] mod_proxy_http.c(1101): [client 172.17.0.1:40486] Accept-Ranges: bytes
[Thu Feb 21 14:49:18.762783 2019] [proxy_http:trace3] [pid 895:tid 139989845219072] mod_proxy_http.c(1695): [client 172.17.0.1:40486] start body send
[Thu Feb 21 14:49:18.762837 2019] [http:trace3] [pid 895:tid 139989845219072] http_filters.c(1129): [client 172.17.0.1:40486] Response sent with status 200, headers:
[Thu Feb 21 14:49:18.762841 2019] [http:trace5] [pid 895:tid 139989845219072] http_filters.c(1136): [client 172.17.0.1:40486] Date: Thu, 21 Feb 2019 06:49:18 GMT
[Thu Feb 21 14:49:18.762844 2019] [http:trace5] [pid 895:tid 139989845219072] http_filters.c(1139): [client 172.17.0.1:40486] Server: nginx
[Thu Feb 21 14:49:18.762847 2019] [http:trace4] [pid 895:tid 139989845219072] http_filters.c(958): [client 172.17.0.1:40486] Content-Type: application/javascript
[Thu Feb 21 14:49:18.762849 2019] [http:trace4] [pid 895:tid 139989845219072] http_filters.c(958): [client 172.17.0.1:40486] Content-Length: 1130146
[Thu Feb 21 14:49:18.762852 2019] [http:trace4] [pid 895:tid 139989845219072] http_filters.c(958): [client 172.17.0.1:40486] Last-Modified: Mon, 18 Feb 2019 05:11:04 GMT
[Thu Feb 21 14:49:18.762854 2019] [http:trace4] [pid 895:tid 139989845219072] http_filters.c(958): [client 172.17.0.1:40486] X-Hi-From-Nginx: \\"5c6a3e68-113ea2\\"
[Thu Feb 21 14:49:18.762857 2019] [http:trace4] [pid 895:tid 139989845219072] http_filters.c(958): [client 172.17.0.1:40486] Accept-Ranges: bytes
[Thu Feb 21 14:49:18.762859 2019] [http:trace4] [pid 895:tid 139989845219072] http_filters.c(958): [client 172.17.0.1:40486] Vary: Accept-Encoding
所以基本上它会丢弃 ETag 标头,但是我的具有相同值的自定义 X-Hi-From-Nginx 标头可以毫无问题地传递。我读到 Nginx 在启用 gzip 时可能会遇到一些 ETag 问题,但是禁用它并不能改善任何问题。实际上很明显问题出在 Apache 方面,因为 Nginx 按预期发送了所有标头。
这是我正在使用的软件(通过 Docker):
root@7ac07b106612:/bootstrap# nginx -v
nginx version: nginx/1.10.3 (Ubuntu)
root@7ac07b106612:/bootstrap# apache2ctl -v
Server version: Apache/2.4.18 (Ubuntu)
Server built: 2018-06-07T19:43:03
后天更新。。
我实际上设法使用这样的 expr 设置了另一个自定义标头:
Header always set X-Apache-ETag "expr=%{resp:x-nginx-etag}"
Header always set ETag "expr=%{resp:x-nginx-etag}"
但是它只设置“X-Apache-ETag”标头,而 ETag 仍然被丢弃。它已经开始看起来像一些错误了..
> GET /dist/js/vendor.js HTTP/1.1
> Host: dev.com
> User-Agent: curl/7.53.0
> Accept: */*
> Accept-encoding: br
>
{ [5 bytes data]
< HTTP/1.1 200 OK
< Date: Fri, 22 Feb 2019 04:55:10 GMT
< Server: nginx
< X-Apache-ETag: "5c6f3469-4ad21"
< Content-Type: application/javascript
< Content-Length: 306465
< Last-Modified: Thu, 21 Feb 2019 23:29:45 GMT
< X-Nginx-Etag: "5c6f3469-4ad21"
< Accept-Ranges: bytes
< Vary: Accept-Encoding
更新#2。更多细节..我看到它在“发送状态为 200 的响应,标题:”附近显示“http_filters.c”,所以我开始搜索该文件的来源。这是我发现的:
/*
* Now remove any ETag response header field if earlier processing
* says so (such as a 'FileETag None' directive).
*/
if (apr_table_get(r->notes, "no-etag") != NULL) {
apr_table_unset(r->headers_out, "ETag");
}
不知道为什么会触发这种情况,因为我的配置中没有“FileETag None”。即使我添加“FileETag MTime Size”也无济于事。
解决方案
更新#3 ..
我认为这是由加载的“包含”模块引起的。它有这个特定的 SSIETag指令,默认情况下设置为“关闭” - 基于导致“无 etag”注释和标题最终消失的描述。
在上下文中将其设置为“开”并没有多大帮助,但是完全禁用“包含”模块确实有帮助,所以这是罪魁祸首。
推荐阅读
- visual-studio-code - 如何在我的 *.svelte 文件中配置自动格式化?
- swift - 当 BUILD_LIBRARY_FOR_DISTRIBUTION 设置为 Yes 时,Swift 框架无法构建
- c++ - 为什么这些静态函数不按预期从另一个线程返回?
- vuejs2 - Vuejs 从孙子级发射到基本父级
- r - 测试数字是否在R中的字符串中
- google-apps-script - 自动 CSV 导入错误:选项卡已存在
- c# - 单独文件中的 XML 文档注释
- javascript - 如何让 getUsermedia 在 Instagram 上工作?
- sql - json_build_object() 中的 case 表达式
- javascript - 使用jquery从多个url解析json