Response 的頭部沒有 Content-Length

文章目錄
1. 背景
2. 緣由
3. 解決方式
4. 知識點
4.1 Fiddler
4.2 Http
4.3 CDN
5.附錄
5.1 請求&回包頭部信息
1. 背景
使用Okhttp的框架,在七牛服務器上進行文件下載,發現一個奇怪的問題,在進行 Http 進行下載的時候,Response 的回包裏面,偶爾會出現沒有 Content-Length 的狀況,致使沒法準確的獲取下載進度。服務器

在查找問題的過程當中,較深刻的瞭解Http下載的流程和fiddler抓包工具的使用,並在與七牛的運維肯定問題後,給出了我認爲較合理的解決方案。網絡

2. 緣由
形成沒有 Content-Length 的緣由,是因爲七牛的服務器沒有返回這個字段,七牛方面給出的回覆以下:負載均衡

這邊排查當請求頭帶有 Accept-encoding: gzip 時,第一次請求到某個節點時,會沒有 content-length 頭,第二次請求到相同節點,就會帶這個頭了。框架

當 CDN 節點須要作 gzip 壓縮時,爲加快第一次響應速度,會在作完 gzip 壓縮後直接先響應內容,再計算 content-length ,這樣第二次訪問到該節點的時候,會把上次的 gzip 壓縮內容和 content-length 都返回。
1
2
3
因此緣由總結要點以下:運維

七牛服務器默認會對文本格式的文件進行 gzip 壓縮,也只有文本格式的文件會出現返回的 Response 裏面沒有 Content-Length 的問題。(目前與官方肯定的是隻有文本文件會進行壓縮,並不肯定是否是其餘文件就真的沒有)
之因此出現有時候有 Content-Length ,有時候沒有,是由於數據來源是不一樣的 CDN 致使的。只有第二次從 CDN 取到相同數據的時候纔有 Content-Length ,雖然咱們訪問的域名沒有變,可是數據來源的 CDN 可能變了,因此致使了第二次獲取的 Content-Length 仍是沒有。
3. 解決方式
因爲是使用的七牛的存儲,不可能要求對方必須返回 Content-Length ,因此咱們能夠經過下面這些手段來實現進度更新或者規避爲空的狀況:ide

必須使用Content-Length(不推薦)工具

在發送的請求頭部,在發送請求時,添加頭部 (「Accept-Encoding」,「identity」) 。這麼處理會告訴服務器不要走壓縮的邏輯,可能會形成數據傳輸量增大。學習

不使用Content-Length.net

因爲問題出在文件大小上面,因此能夠在下載以前先獲取文件大小信息,而不是使用 Content-Length。線程

不使用Progress

若是實在不方便獲取文件大小,在txt文件不太大的狀況下,壓縮後的問價大小沒多少,因此能夠不使用Progress

4. 知識點
4.1 Fiddler
本次使用 Fiddler 對手機發出去的請求進行抓包,該工具的安裝及結合手機的使用教程以下:

Fiddler 安裝下載及結合手機使用教程

Fiddler 使用教程及字段解釋

4.2 Http
在此次事件中,對於Http在下載時的方式有了必定的瞭解,下載方式是單線程、非斷點續傳的常規下載,請求過程的頭部信息的內容以下(具體頭部信息參考附錄5.1):

C->S: 創建http長鏈接,其中head存在頭部信息 Connection: Keep-Alive
S->C: 根據合適的CDN以數據流的形式返回數據,其中head使用頭部信息Connection: Keep-Alive來標記是長鏈接,回包的頭部中,若是CDN上存儲有這個文件,返回Content-Length,若是沒有,則分片返回,其中頭部沒有Content-Length,可是多了Content-Encoding: gzip、Transfer-Encoding: chunked。
下載的具體解析,能夠參考下面這篇文章:

HTTP協議頭部與Keep-Alive模式詳解

4.3 CDN
CDN全稱是Content Delivery Network,即內容分發網絡,其功能包括:內容存儲、內容分發和負載均衡等。主要做用是減小服務器負擔,下降網絡帶寬的阻塞,提升訪問的響應速度。

將一次網絡請求當作是一次去購物的經歷,咱們去了一家分店買某件東西,若是這家店有咱們的東西,咱們就直接拿了回家,若是沒有,咱們就須要等待店員去總店(或者附近別的店)去拿,而後咱們再從分店拿回去。

下面是不含CDN與含CDN的請求路徑對比:


此處不深究CND的實現原理,對CDN的介紹,能夠參考下面文章:

CDN學習筆記

5.附錄
5.1 請求&回包頭部信息
請求頭部:
GET /Fu37K5kksCvSg8iQ-ln2TjlqKXpz?e=1542791189&token=BDlsCI9C9xGl-aBysVoFl7-eu9c2j5JLredsogNl:lHHPRK4Mk3o1xPjZc93rRlMaQkA= HTTP/1.1
Host: dn-kdoss.qbox.me
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.6.0


正常狀況下的回包頭部:

HTTP/1.1 200 OK
Server: Tengine
Content-Type: text/plain
Connection: keep-alive
Date: Wed, 21 Nov 2018 08:45:21 GMT
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Log, X-Reqid
Access-Control-Max-Age: 2592000
Cache-Control: public, max-age=31536000
Content-Disposition: inline; filename="Fu37K5kksCvSg8iQ-ln2TjlqKXpz"; filename*=utf-8' 'Fu37K5kksCvSg8iQ-ln2TjlqKXpz
Content-Transfer-Encoding: binary
Etag: "Fu37K5kksCvSg8iQ-ln2TjlqKXpz.gz"
Last-Modified: Mon, 15 Oct 2018 09:35:49 GMT
Vary: Accept-Encoding
X-Log: mc.g;jjh0EBD;mc.g;IO:25
X-M-Log: QNM:jjh1526;SRCPROXY:jjh1535;SRC:28;SRCPROXY:28;QNM3:44
X-M-Reqid: v1IAAPqytsdFF2kV
X-Private: 1
X-Qiniu-Zone: 0
X-Qnm-Cache: Miss
X-Reqid: A0oAALtgOy5VF2kV
X-Svr: IO
Via: cache40.l2st3-1[242,200-0,M], cache3.l2st3-1[269,0], cache9.cn1260[580,200-0,M], cache17.cn1260[582,0]
Age: 0
Ali-Swift-Global-Savetime: 1542790000
X-Cache: MISS TCP_MISS dirn:-2:-2
X-Swift-SaveTime: Wed, 21 Nov 2018 08:46:40 GMT
X-Swift-CacheTime: 86400
Timing-Allow-Origin: *
EagleId: 77939ca515427899997314719e
Content-Length: 1038998


異常狀況下的回包頭部:

HTTP/1.1 200 OK Server: Tengine Content-Type: text/plain Transfer-Encoding: chunked Connection: keep-alive Date: Wed, 21 Nov 2018 08:51:20 GMT Accept-Ranges: bytes Access-Control-Allow-Origin: * Access-Control-Expose-Headers: X-Log, X-Reqid Access-Control-Max-Age: 2592000 Cache-Control: public, max-age=31536000 Content-Disposition: inline; filename="Fu37K5kksCvSg8iQ-ln2TjlqKXpz"; filename*=utf-8' 'Fu37K5kksCvSg8iQ-ln2TjlqKXpz Content-Encoding: gzip Content-Transfer-Encoding: binary Etag: "Fu37K5kksCvSg8iQ-ln2TjlqKXpz.gz" Last-Modified: Mon, 15 Oct 2018 09:35:49 GMT Vary: Accept-Encoding X-Log: mc.g;IO:18 X-M-Log: QNM:xs451;SRCPROXY:xs1753;SRC:22;SRCPROXY:22;QNM3:36 X-M-Reqid: 9FAAAH5NGeCnF2kV X-Private: 1 X-Qiniu-Zone: 0 X-Qnm-Cache: Miss X-Reqid: BGkAAGptit-nF2kV X-Svr: IO Via: cache40.l2et2-2[113,200-0,M], cache39.l2et2-2[115,0], cache14.cn1260[233,200-0,M], cache17.cn1260[235,0] Age: 0 Ali-Swift-Global-Savetime: 1542790357 X-Cache: MISS TCP_MISS dirn:-2:-2 X-Swift-SaveTime: Wed, 21 Nov 2018 08:52:37 GMT X-Swift-CacheTime: 86400 Timing-Allow-Origin: * EagleId: 77939ca515427903569903531e

相關文章
相關標籤/搜索