Nginx

為什麼 SPDY 會在 Nginx 1.4.3 中破壞“Vary: Accept-Encoding”?

  • September 18, 2015

我已經使用 SPDY 模組從原始碼編譯了 Nginx 1.4.3。

但是,當啟用 SPDY 時,它似乎破壞了我的“Vary: Accept-Encoding”標頭。

我的 Nginx 配置:

./configure
--conf-path=/etc/nginx/nginx.conf
--pid-path=/var/run/nginx.pid
--error-log-path=/var/log/nginx/error.log
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--http-log-path=/var/log/nginx/access.log
--with-http_ssl_module --prefix=/usr
--add-module=./nginx-sticky-module-1.1
--add-module=./headers-more-nginx-module-0.23
--with-http_spdy_module

我的“nginx.conf”文件:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
   worker_connections  1024;
}


http {
   include       /etc/nginx/mime.types;
   default_type  application/octet-stream;

   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

   access_log  /var/log/nginx/access.log  main;

   sendfile        on;
   #tcp_nopush     on;

   keepalive_timeout  65;

   #Compression Settings
   gzip on;
   gzip_http_version 1.0;
   gzip_comp_level 2;
   gzip_proxied any;
   gzip_min_length  1100;
   gzip_buffers 16 8k;
   gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
   # Some version of IE 6 don't handle compression well on some mime-types, 
   # so just disable for them
   gzip_disable "MSIE [1-6].(?!.*SV1)";
   # Set a vary header so downstream proxies don't send cached gzipped 
   # content to IE6
   gzip_vary on;

   proxy_cache_path /var/www/nginx_cache levels=1:2 keys_zone=qnx-cache:10m inactive=24h max_size=1g;
   proxy_temp_path /var/www/nginx_cache/tmp;

   server_tokens off;

   include /etc/nginx/conf.d/*.conf;

   map $geo $mapping {
       default default;
       US US;
       DE DE;
   CA CA;
   GB GB;
   }
   geo $geo {
       default default;
       include geo.conf;
   }
   upstream default.backend {
#   sticky;
       server 192.168.0.5:8080;
       server 192.168.0.6:8080;
       server 192.168.0.7:8080;
   }
   upstream mysite.backend {
       sticky name=servIDTrack hash=sha1;
       server 192.168.0.5:8080 weight=10 max_fails=3 fail_timeout=10s;
       server 192.168.0.6:8080 weight=10 max_fails=3 fail_timeout=10s;
       server 192.168.0.7:8080 weight=10 max_fails=3 fail_timeout=10s;
   }
server {
       listen      80;
       server_name secure.mysite.com;
       return 301 https://$server_name$request_uri;
   }
server {
       listen 443 ssl;
       server_name secure.mysite.com;
       more_set_headers    "Server: X-nginx/v1.1 [LB01]";

       ssl_certificate     /etc/nginx/ssl/secure_mysite_com_ssl.cert;
       ssl_certificate_key /etc/nginx/ssl/secure_mysite_com_ssl.key;

       ssl_protocols           SSLv3 TLSv1 TLSv1.1 TLSv1.2;
#       ssl_ciphers             RC4:HIGH:!aNULL:!MD5;
       ssl_ciphers         ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA;
       ssl_prefer_server_ciphers on;
       keepalive_timeout       120;
       ssl_session_cache       builtin:1000 shared:SSL:10m;
       ssl_session_timeout     10m;

       location / {
           proxy_pass http://mysite.backend;
           proxy_set_header        Host            $host;
           proxy_set_header        X-Real-IP       $remote_addr;
           proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_redirect          off;
           proxy_http_version      1.1;

           add_header Strict-Transport-Security "max-age=31556926; includeSubdomains";

   # Cache
               proxy_cache qnx-cache;
               proxy_cache_valid  200 301 302  120m;
               proxy_cache_valid 404 1m;
               add_header X-Cache-Status $upstream_cache_status;
               proxy_cache_key "$scheme$host$request_uri";

       }
   }
}

啟用/禁用 SPDY 的標題結果:

url: mypage.php (SPDY enabled)

HTTP/1.1 200 OK
cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
content-encoding: gzip
content-type: text/html; charset=utf-8
date: Wed, 20 Nov 2013 13:39:30 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
pragma: no-cache
server: X-nginx/v1.1 [LB01]
status: 200
strict-transport-security: max-age=31556926; includeSubdomains
version: HTTP/1.1
x-cache-status: MISS

url: mypage.php (SPDY disabled)

HTTP/1.1 200 OK
Date: Wed, 20 Nov 2013 13:45:00 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Server: X-nginx/v1.1 [LB01]
Strict-Transport-Security: max-age=31556926; includeSubdomains
X-Cache-Status: MISS
Content-Encoding: gzip

url: mystyle.css (SPDY enabled)

HTTP/1.1 200 OK
date: Wed, 20 Nov 2013 12:53:49 GMT
content-encoding: gzip
last-modified: Mon, 18 Nov 2013 22:09:32 GMT
server: X-nginx/v1.1 [LB01]
x-cache-status: HIT
strict-transport-security: max-age=31556926; includeSubdomains
content-type: text/css
status: 304
expires: Wed, 18 Dec 2013 22:42:35 GMT
cache-control: max-age=2592000
version: HTTP/1.1

url: mystyle.css (SPDY disabled)

HTTP/1.1 200 OK
Date: Wed, 20 Nov 2013 13:45:01 GMT
Content-Type: text/css
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Mon, 18 Nov 2013 22:09:32 GMT
Cache-Control: max-age=2592000
Expires: Wed, 18 Dec 2013 22:10:13 GMT
Server: X-nginx/v1.1 [LB01]
Strict-Transport-Security: max-age=31556926; includeSubdomains
X-Cache-Status: HIT
Content-Encoding: gzip

如您所見,啟用 SPDY 後,Vary: Accept-Encoding標題消失了。

這是我nginx.conf的配置方式的問題嗎?

SPDY(和 HTTP/2.0)要求使用者代理支持壓縮,這使得Vary: Accept-Encoding標頭毫無用處。這就是為什麼 nginx 會刪除標頭。

它可能是也可能不是錯誤,但由於 SPDY 始終使用壓縮,並且目前沒有 SPDY 轉發代理(因為 SPDY 始終使用 TLS),所以 Vary 標頭是無用的。僅代理使用 Vary 來確定是發送壓縮內容還是未壓縮內容

基本上,如果連接系統支持 SPDY,它也支持 gzip 壓縮內容,因此無需在 Vary 標頭上浪費字節。這就是至少一些支持 SPDY 的大型網站正在做的事情。有關詳細資訊,請參閱此頁面

從理論上講,有朝一日可能會有 SPDY 代理出現在那些擁有不支持 HTTP 壓縮的舊版瀏覽器的公司中,但我真的希望不會。即使有,如果客戶端沒有發送“Accept-Encoding:gzip”標頭,代理也可以以低成本即時解壓縮。

引用自:https://serverfault.com/questions/556258