我正在使用手工調製的HttpWebRequest
調用和JSON序列化來處理與Ruby on Rails中實現的Web服務接口的小型C#/ WPF應用程序。如果沒有緩存,所有事情都按照預期運行,並且我也有HTTP認證和壓縮工作。啓用緩存的HttpWebRequest引發異常
一旦啓用緩存,通過設置request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable);
,事情就會出錯 - 在生產環境中。當連接到一個簡單的WEBrick實例,事情工作正常,我得到HTTP/1.1 304 Not Modified
預期和HttpWebRequest
提供緩存的內容。
當我對生產服務器進行同樣的嘗試時,運行nginx/0.8.53 + Phusion Passenger 3.0.0,應用程序中斷。第一個請求(未緩存)被正確地服務,但是對於導致304響應的第二個請求,我得到一個WebException
,說明「請求已中止:請求被取消。」「只要我調用request.GetResponse()
。
我已經通過fiddler運行連接,這並沒有幫助很多; WEBrick和nginx都返回一個空的實體主體,雖然不同的響應頭。攔截請求並更改nginx的響應頭以匹配WEBrick的響應頭並沒有改變任何內容,導致我認爲它可能是一個存活問題;設置request.KeepAlive = false;
不會改變任何內容,但它不會在連接到WEBrick時破壞內容,並且在連接到nginx時不會修正內容。
對於它的價值,在WebException.InnerException
是NullReferenceException
具有以下StackTrace
:
at System.Net.HttpWebRequest.CheckCacheUpdateOnResponse()
at System.Net.HttpWebRequest.CheckResubmitForCache(Exception& e)
at System.Net.HttpWebRequest.DoSubmitRequestProcessing(Exception& exception)
at System.Net.HttpWebRequest.ProcessResponse()
at System.Net.HttpWebRequest.SetResponse(CoreResponseData coreResponseData)
頭的(工作)的WEBrick連接:
########## request
GET /users/current.json HTTP/1.1
Authorization: Basic *REDACTED*
Content-Type: application/json
Accept: application/json
Accept-Charset: utf-8
Host: testbox.local:3030
If-None-Match: "84a49062768e4ca619b1c081736da20f"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
########## response
HTTP/1.1 304 Not Modified
X-Ua-Compatible: IE=Edge
Etag: "84a49062768e4ca619b1c081736da20f"
Date: Wed, 01 Dec 2010 18:18:59 GMT
Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-08-16)
X-Runtime: 0.177545
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: *REDACTED*
頭的(除了投擲) nginx連接:
########## request
GET /users/current.json HTTP/1.1
Authorization: Basic *REDACTED*
Content-Type: application/json
Accept: application/json
Accept-Charset: utf-8
Host: testsystem.local:8080
If-None-Match: "a64560553465e0270cc0a23cc4c33f9f"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
########## response
HTTP/1.1 304 Not Modified
Connection: keep-alive
Status: 304
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.0
ETag: "a64560553465e0270cc0a23cc4c33f9f"
X-UA-Compatible: IE=Edge,chrome=1
X-Runtime: 0.240160
Set-Cookie: *REDACTED*
Cache-Control: max-age=0, private, must-revalidate
Server: nginx/0.8.53 + Phusion Passenger 3.0.0 (mod_rails/mod_rack)
更新:
我試圖做一個快速和骯髒的手動ETag的緩存,但事實證明這是一個不走的:我得到一個WebException
調用request.GetResponce()
的時候,告訴我,「遠程服務器返回錯誤:( 304)未修改「。 - 是的,.NET,我有點知道,我想(嘗試)自己處理它,grr。
UPDATE 2:
更接近問題的根源。 showstopper似乎是初始請求的響應標題中的差異。 WEBrick包含一個Date: Wed, 01 Dec 2010 21:30:01 GMT
標題,它在nginx答覆中不存在。還有其他的不同點,但是用提琴手攔截最初的nginx回覆並添加一個Date
標題,後續的HttpWebRequest
能夠處理(未修改的)nginx 304回覆。
想要尋找解決方法,以及讓nginx添加Date標頭。
更新3:
看來,服務器端的問題是與乘客的Phusion,他們有一個open issue關於缺乏Date
頭的。我仍然認爲HttpWebRequest
的行爲是......不理想。
UPDATE 4:
增加了Microsoft Connect票的bug。
嗨!我認爲你在HttpWebRequest中發現了一個錯誤。您可以創建repro日誌(請參閱http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html)並在http:// connect?上創建一個bug請求。這樣,微軟可以解決這個問題。 – feroze 2010-12-02 00:37:16
@feroze:昨天我用完了時間,但我現在在Connect上添加了錯誤票。 – snemarch 2010-12-02 09:37:53