Apache-2.2

http請求的gzip不正確,找不到是誰在做的

  • March 8, 2016

我們看到一些非常奇怪的 HTTP 響應混亂,我們無法弄清楚這是怎麼回事。我們有一個處理 JSON 請求的應用伺服器。有時,返回的響應是 gzip 壓縮的,但帶有不正確的標頭,這會阻止瀏覽器正確解釋它。

這個問題是間歇性的,並且隨著時間的推移會改變行為。昨天早上,它似乎有 50% 的時間都失敗了,事實上,它似乎與我們的兩台負載平衡伺服器中的一台有關。下午晚些時候,它在 1000 次中只有 20 次失敗,並且與應用伺服器無關。

兩個應用伺服器執行 Apache 2.2,帶有 mod_wsgi 和 Django 應用堆棧。它們具有相同的 Apache 配置和原始碼樹,甚至在 Red Hat 上安裝了相同的軟體包。前面有一個硬體負載均衡器,我不知道品牌或型號。

Akamai 也是食物鏈的一部分,儘管我們移除了 Akamai,但問題仍然存在。

這是一個很好的請求和響應:

* Connected to example.com (97.7.79.129) port 80 (#0)
> POST /claim/ HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: example.com
> Accept: */*
> Referer: http://example.com/apps/
> Accept-Encoding: gzip,deflate
> Content-Length: 29
> Content-Type: application/x-www-form-urlencoded
> 
} [data not shown]
< HTTP/1.1 200 OK
< Server: Apache/2
< Content-Language: en-us
< Content-Encoding: identity
< Content-Length: 47
< Content-Type: application/x-javascript
< Connection: keep-alive
< Vary: Accept-Encoding
< 
{ [data not shown]
* Connection #0 to host example.com left intact
* Closing connection #0
{"msg": "", "status": "OK", "printer_name": ""}

這是一個壞的:

* Connected to example.com (97.7.79.129) port 80 (#0)
> POST /claim/ HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: example.com
> Accept: */*
> Referer: http://example.com/apps/
> Accept-Encoding: gzip,deflate
> Content-Length: 29
> Content-Type: application/x-www-form-urlencoded
> 
} [data not shown]
< HTTP/1.1 200 OK
< Server: Apache/2
< Content-Language: en-us
< Content-Encoding: identity
< Content-Type: application/x-javascript
< Content-Encoding: gzip
< Content-Length: 59
< Connection: keep-alive
< Vary: Accept-Encoding
< X-N: S
< 
{ [data not shown]
* Connection #0 to host example.com left intact
* Closing connection #0
�V�-NW�RPR�QP*.I,)-���A���̼�Ԣ����T��Z�
��/

不良反應有兩點需要注意:

  1. 它有兩個 Content-Encoding 標頭,瀏覽器似乎使用第一個。因此他們看到了一個身份編碼標頭和壓縮的內容,因此他們無法解釋響應。
  2. 錯誤響應有一個額外的“XN: S”標頭。

也許如果我能找出中間人在響應中添加了“XN:S”標題,我就可以找到罪魁禍首……

一些額外的線索

根據http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5

  • identity預設(身份)編碼;不使用任何轉換。此內容編碼僅在 Accept-Encoding 標頭中使用,不應在 Content-Encoding 標頭中使用。

Akamai 似乎忽略了這樣一個事實,即伺服器可以在其響應中包含此標頭,並且在將編碼更改為“gzip”時不會將其刪除。

由於上游伺服器“不應該”首先添加標頭,這是解決此問題的另一種方法。

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