HttpWebRequestを使用して、HTTP経由で一連のファイルをフェッチしようとしています。最初のリクエストは正常に処理されますが、同じコードを介した2回目は、GetResponse()がハングしてタイムアウトします。 WireSharkは、2番目のリクエストに対してHTTPトラフィックが送信されていないことを示しているため、APIの問題であるように見えます。
調査の結果、content-lengthの指定に関係していることがわかりました。これを省略した場合、コードは正常に機能します。
私のコードは:
HttpWebRequest httpWebRequest = ConfigureRequest();
using (WebResponse webResponse = httpWebRequest.GetResponse())
// On the second iteration we never get beyond this line
{
HttpWebResponse httpWebResponse = webResponse as HttpWebResponse;
using (Stream webResponseStream = httpWebResponse.GetResponseStream())
{
if (webResponseStream != null)
{
// Read the stream
}
}
statusCode = httpWebResponse.StatusCode;
httpWebResponse.Close();
}
症状は この質問 と この質問 に非常に似ているように見えますが、どちらの場合も、私がすでに行っているWebResponseを破棄することをお勧めします。
EditGregoryに応答して、次はConfigureRequest()です。
private HttpWebRequest ConfigureRequest()
{
string sUrl = CreateURL(bucket, key);
HttpWebRequest httpWebRequest = WebRequest.Create(sUrl) as HttpWebRequest;
httpWebRequest.AllowWriteStreamBuffering = false;
httpWebRequest.AllowAutoRedirect = true;
httpWebRequest.UserAgent = this.m_sUserAgent;
httpWebRequest.Method = "GET";
httpWebRequest.Timeout = this.m_iTimeout;
// *** NB: This line was left out of my original posting, and turned out to be
// crucial
if (m_contentLength > 0)
httpWebRequest.ContentLength = m_contentLength;
httpWebRequest.Headers.Add(StaticValues.Amazon_AlternativeDateHeader, timestamp);
httpWebRequest.Headers.Add(StaticValues.HttpRequestHeader_Authorization, StaticValues.Amazon_AWS + " " + aWSAccessKeyId + ":" + signature);
return httpWebRequest;
}
編集:検証していないコードを質問から削除するという根本的な罪を犯したことが、問題とは無関係であることがわかりました。次の行を削除しました。
if (m_contentLength > 0)
httpWebRequest.ContentLength = m_contentLength;
gETリクエストにはcontent-lengthが指定されないと思ったからです。私が間違っていたことがわかりました。この行を削除すると、問題が修正されます。
私が今持っている唯一の質問はなぜですか? Ithink指定されたコンテンツの長さは正しいと思いますが、1つずれている可能性があります。短すぎるコンテンツの長さを指定すると、完全なダウンロードが行われなくなり、接続が開いたままになりますか?とにかく、Close()やDispose()が接続を切断するはずだと思っていたでしょう。
毎回新しいHttpWebRequestを作成していることを確認してください。 GetResponse メソッドに関するMSDNリファレンスからの引用:
GetResponseを複数回呼び出すと、同じ応答オブジェクトが返されます。要求は再発行されません。
更新1:わかりました。 webResponseStreamも閉じようとした場合はどうでしょうか。現在は閉じていません。webResponseを閉じているだけです(除外しようとしているだけです)。 httpWebResponseも破棄します(WebResponseだけでなく)
更新2:私が提案できる他の唯一のことは、私があなたと同じようなことをしたときに見た次の記事を見てみることです。再実行:
http://arnosoftwaredev.blogspot.com/2006/09/net-20-httpwebrequestkeepalive-and.html
http://www.devnewsgroups.net/dotnetframework/t10805-exception-with-httpwebrequest-getresponse.aspx
私が違うのは、次のことだけです。
-webrequest.KeepAlive = falseを設定します
-構成に接続管理機能がありません(一連の要求を行うためにループしません)
HttpWebRequest.ContentLength のドキュメントによると:
ContentLengthプロパティの-1以外の値は、リクエストがデータをアップロードし、データをアップロードするメソッドのみがMethodプロパティに設定できることを示します。
ContentLengthプロパティを値に設定した後、そのバイト数を、GetRequestStreamメソッドまたはBeginGetRequestStreamメソッドとEndGetRequestStreamメソッドの両方を呼び出して返される要求ストリームに書き込む必要があります。
コンテンツの長さを設定しているのにデータをアップロードしていないため、ハングしていると思われます。その場合は例外をスローする必要があると思うかもしれませんが、明らかにそうではありません。
使用してみてください:
HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
httpWebRequest.CachePolicy = noCachePolicy;