原文:http://fiddler2.com/blog/blog/2013/02/13/understanding-the-request-line
最近有一位Fiddler使用者問我一個問題:
我在使用Fiddler檢視HTTP請求的時候發現Raw和HexView兩個皮膚中顯示的資料有點小區別,比如當我請求www.microsoft.com時,Raw皮膚中的資料是這樣的:
GET http://www.microsoft.com/ HTTP/1.1
...
Host: www.microsoft.com而HexView皮膚中是這樣的:
GET / HTTP/1.1
...
Host: www.microsoft.com為什麼請求行(Request Line)中的文字不一樣?我還發現如果我使用socket直接傳送這樣一個使用絕對路徑的GET請求(不經過Fiddler),一些伺服器會返回錯誤資訊.
原理是這樣的.當客戶端比如瀏覽器認為自己在向一個代理伺服器傳送HTTP請求時,它會在請求行中使用絕對路徑的URL.如果它認為自己在向目標伺服器直接傳送請求,則請求行中只會包含相對路徑的URL(完整URL的path部分).這正是遵循了RFC2616 (5.1.2小節)標準的規定.遵照標準,伺服器必須能正確解析這兩種形式的請求行.但正如上面問題中提到的,有些伺服器不能正確解析請求行中包含絕對路徑的情況,會返回HTTP/4xx或者HTTP/5xx錯誤.
提問者遇到的情況,正是瀏覽器向Fiddler傳送了請求行為GET http://www.microsoft.com/ HTTP/1.1的請求(因為Fiddler也是個代理),然後Fiddler將其中的請求行改寫成了GET / HTTP/1.1,再傳送給伺服器.
Fiddler的檢查器(Inspector)中的各個皮膚能夠自由選擇在請求行中顯示絕對路徑還是相對路徑,每種選擇都有各自的好處.顯示絕對路徑能夠讓使用者更方便的檢視,修改(需要開啟Unlock for editing),以及連結化請求地址(Raw皮膚中),而顯示相對路徑更符合實際情況,因為Fiddler傳送給伺服器的請求最終都是使用相對路徑的.
譯者注:在最新的Fiddler版本中,不管Fiddler接受到的請求中的請求行使用絕對路徑還是相對路徑,Fiddler都會在各個皮膚中顯示絕對路徑(也就是說提問中兩個皮膚顯示資料不同的這個表現已經不存在了),而傳送的真實資料會使用相對路徑.
總結一下就是,Fiddler中看到的請求資料並不一定是客戶端傳送的真實資料,Fiddler最後傳送的請求資料也不一定是你在Fiddler中看到的那樣.
有些情況下,我們需要看到客戶端傳送的真實的請求資料,一點也不能經過篡改.我們就得使用真正的抓包軟體,而不是代理,比如SmartSniff.
有些情況下,我們希望我們構造的HTTP請求不經任何修改的傳送給伺服器,這時就不能使用Fiddler自帶的composer了,你可以使用命令列的telnet程式,還可以使用我自己寫的一個小工具,叫HTTP Request Builder.這個工具的特點是,請求資料使用socket直接傳送(沒有使用.net中更高階的封裝類).因此就不會有任何的格式限制和異常捕獲,你甚至可以去谷歌的主機上請求百度的網站,想要的卻是淘寶首頁:
使用這個工具,可以驗證一下原文中所說的Fiddler是否的確會修改請求行中的URL,可以這樣構造請求:
之後在Fiddler中的Raw和HexView兩個皮膚中看看,都是絕對URL.
而在抓包軟體中看到的,也就是Fiddler真正傳送出去的請求,是篡改後的相對URL.