2009-08-25 5 views
1

アプリケーションをホストするためにIIS7を使用してHTTP上に存在するアプリケーション用に、C#で包括的な統合テストフレームワークを構築しています。C#でHTTP用に不適切なコンテンツ長ヘッダーをシミュレート

統合テストの一環として、クライアントが実際よりも大きなボディサイズを示すHTTPヘッダーを送信したときに発生するEndOfStreamExceptions(「ストリームの終わりを超えて読み取ることができません」)体の一部として送信されます。この状態のエラーリカバリコードをテストして、これらの種類のリクエストをシミュレートする必要があります。

.NET FxベースのソケットライブラリまたはカスタムHttpWebRequestの代替品を探しています。具体的には、開発者がこのような条件をシミュレートして、統合テストスイートに追加することができます。誰もそのようなライブラリを知っていますか?スクリプト可能なソリューションも同様に機能します。

答えて

4

GetRequestStream(またはBeginGetRequestStream)を呼び出す前にContentLengthプロパティを設定し、そのストリームに書き込むバイト数を減らします。リクエストストリームを取得した後にContentLengthを設定しようとすると、ContentLengthがスローされます。 ContentLengthを設定しない場合、HttpWebRequestは、ストリームが閉じられてContentLengthを適切に設定できるようになるまで、ヘッダーをバッファします(代わりに、SendChunkedを使用できますが、ここでは機能しません)。これを最大限に制御したい場合は、1つまたは2つの不正なリクエストを手作業で作成し、サーバー上のポート80へのソケットを開き、TCPストリームに要求を書き込み、応答を読み取り、接続が閉じられているかどうかを確認します。 。

ただし、このテストは良い考えではないと思います。問題は次のとおりです。

クライアントからサーバーに要求が送信されます。内容は100バイトと主張しています。次に、90バイトを送信し、送信を停止して接続を開いたままにします。サーバーは90バイトを読み取り、クライアントが100バイトが送信されると言い、残りを待ちます。今、クライアントは2番目の要求を送信します。サーバーは新しいリクエストの最初の10バイトで何をしますか?

答えは、サーバーが前の要求の一部であると仮定し、そのように処理した後、開始から10バイト後に「新しい」要求を読み始めることです。これは明らかに不正なヘッダーになります。サーバーはそれを好まないので、4xxエラーを送信して接続を終了します。接続を閉じる理由は、現在送信されているデータが何を意味するのか、回復する方法がわからないためです。また、接続の終了は正常ではなく、突然になり、2番目のリクエストを送信している相手側のHttpWebRequest(またはキューに入れられている場合は3番目または4番目)がWebExceptionをスローします基本的な接続は閉じられ、なぜあなたは推測のままになります。

これは、接続がExpect 100-continueヘッダーで閉じられ、サーバーがAuthが必要な場合など、100-continueの後に4xxを返した場合に発生します。要求を拒否したとしても、100バイトを送信してこれらのバイトを受信することを約束しているので、次のバイトが同じ要求の一部であると仮定しなければならない。その要求を処理できない場合や、クライアントが要求をキャンセルして新しい認証情報を送信したい場合は、接続を閉じて新しいものを開く必要があります。

最後に、TCPを使用してネットワークストリームからEndOfStreamExceptionをテストしても、まったく意味がありません。 TCPはストリームの「終わり」をマークせず、ソケットに書き込まれるときにデータを送信し続けるだけです。それには「EOF」はなく、期待するデータ量を知らない限り、データがすべて送信されたかどうかを検出する方法はありません。接続が閉じられていない限り、TCPは実際にストリームの「終わり」を持っていません。この場合、スタック内のどこかに応じてWebExceptionまたはSocketExceptionが発生します。プロトコル内の送信エラーはすべて、winsockで処理されます。それ以上のデータが送信されない場合、接続の一方の端は結局キープアライブを他方に送信して、接続が実際に開いており、1つのホストだけがドロップしていないことを確認します。キープアライブがタイムアウトすると、接続が閉じられ、次回から読み込みを試みるときにWebExceptionが発生する可能性があります。どのように動作するかを考えれば、このテストからどのような価値を得るのか分かりません。不正なリクエストを送信し、エラーが適切に処理され、適切な4xxメッセージがクライアントに返され、接続が適切に閉じられていることを確認するほうがはるかに優れています。

0

私はこのようなライブラリについて知らないが、それはあなたがコーディングしている場所なら受信側では非常に簡単だろう。

WebRequest全体を取得し、必要なだけ切り捨てて転送します。インプレースを切り捨てるのではなく、その過程でWebRequestの新しいコピーを作成する必要があるかもしれませんが、単純ではあるはずです。

+0

統合テストでは、クライアントをシミュレートします。テストを容易にするために受信側を変更することはできません。 – cfeduke

0

クライアントのHttpWebRequest.ContentLengthプロパティを、データの実際のサイズよりも小さいか大きい値に設定するだけでは問題ありませんか?

0

HTTPプロトコルに違反しているこのようなことをシミュレートしたい場合は、独自のコードを記述して実行する必要があります。 HttpWebRequestでは、このようなことはできません。

関連する問題