之前扒網頁扒到「伺服器認可通訊協定違規. Section=...」的問題,決定追根究柢一下,這個訊息不是只有在用 RestSharp 接收 Response 時會這樣,用 Fiddler 做側錄的時候也會跳出警告訊息來。
這裡的訊息就比較明顯了,它說伺服器沒有回傳正確格式的 HTTP Headers,HTTP Headers 應該是要 CRLFCRLF
結尾,但是收到的 HTTP Headers 卻是 LFLF
結尾。
真的是這樣嗎?!
W3C HTTP/1.1 HTTP Message 規範
我翻了一下 W3C 對 HTTP/1.1 HTTP Message 的說明。
重點在這句話
...an empty line (i.e., a line with nothing preceding the CRLF) indicating the end of the header fields, and possibly a message-body.
header fields 與 message body 之間要隔一個空行(只有 CRLF 結尾的那種空行),意即 header fields 的結尾要是 CRLFCRLF,所以意思是只要 header fields 不是 CRLFCRLF 結尾就會違規。
我把有問題的 Response Message dump 出來,可以看到 header fields 的結尾有四個 CRLF,根據 W3C 的規範,這四個 CRLF 會被切割成後面兩個是屬於 message body 的、前面兩個是屬於 header 區塊的,可是明明看到 header 就是 CRLFCRLF 結尾啊,怎麼 Fildder 跟我說是 LFLF 結尾!?
自製簡易的 HTTP Server
為了測試方便,我用 TcpListener 製作簡易的 HTTP Server,以便完全控制要回傳的 Response 訊息。
先依照 W3C 所說的規範產生 Response 訊息並回傳
瀏覽器可以正確解讀,Fiddler 也沒有跳警告訊息。
接著我把 headers 的結尾用 LFLF 取代
瀏覽器可以正常解讀,但是 Fiddler 卻跳出了警告訊息,跟我要扒特定網頁時跳出來的訊息一樣。
這時候我再 dump 訊息出來看,疑!怎麼變 CRLFCRLF 了?!
很明顯的,dump 出來的訊息已經失真了,已經被 Fiddler 修正過了,這時候我腦海中浮現出一種場景:
A 工程師說:「我用 RestSharp 去呼叫你寫的 WebApi 回傳說格式有問題!」
B 工程師說:「我的沒問題,你看 Fiddler 雖然有警告訊息,但是最後還是可以正常解析啊!你會不會寫啊?」
有時候人跟人之間會為了這種事情而撕破臉,其實沒有必要,多用幾套工具來驗證一下,大家可以不用傷感情。
Wireshark
既然 Fiddler dump 出來的資料已經失真了,我就用網路封包擷取器 - Wireshark 直接看原始的數據封包。
CRLF 的 HEX 是 0D 0A
,從 Fiddler 上看到的 HEX 也的確是 0D 0A 0D 0A。
但是我從 Wireshark 擷取下來的資料是 0A 0A,是 LFLF,真相大白了。
至於為何我扒的網頁會回傳不符合規範的 HTTP Message?那是別人家的網站,也沒有合作關係,無法去做確認了,只能把這樣的追蹤過程及結果當成是一個經驗。
< Source Code >