web-dev-qa-db-ja.com

HttpWebRequestクラスが送信する未加工のHTTP要求を表示するにはどうすればよいですか?

「Fiddlerのようなデバッグプロキシサーバーを使用してください」と答えるつもりですが、それほど簡単ではありません。

私の状況は次のとおりです。ASP.NETページのコードビハインド(aspx.cs)で、サーバー上で実行されるコードがあります。このコードは(とりわけ)another serverへの接続を確立します。いくつかのものを作成し、フォーマットしてからブラウザに返します。

問題は、他のサーバーが間違ったことをしているため、ページにデバッグフラグを渡して(クエリ文字列、たとえば?debug = trueを使用して)、完全に未加工他のサーバーに送信しているHTTPリクエスト。このコードは複数の場所で実行されているため、本番サーバーがどこかに存在するプロキシサーバーと通信できるかどうかを把握せずに、dev、ステージング、または本番でこのフラグを渡して、要求を表示できるようにしたいなど.

これを行うのは簡単だと思いますよね?だから私は気が狂っているかのように感じますが、HttpWebRequestとその親クラスWebRequestのリファレンスを見て、何もしませんでした。できません。 Microsoftはこれを考えていたと思うでしょう。最も近いのは、「Headers」コレクションにアクセスできることですが、試してみると、「content length」などのいくつかの本当に重要なヘッダーが省略されているため、「嘘をついている」必要がありますリモートサーバーが200ステータスを返しているという事実のために-リクエストは成功しました、それは単に悪い/異なる/間違ったデータを返しているだけです)

以下はコードの例です:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.whatever.com");
req.Method = ... whatever ...;
... other setup for the request ...
/* At this point we are about to send the request.
   What does the raw HTTP request look like? */
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
63
eeeeaaii

System.Netトレースメカニズムを使用して、ワイヤ上で送信された生のHTTP要求を確認できます。独自のtracelistenerをプロセスに追加することもできます。

14
feroze

これは古い質問です。 @ feroze's answer は何をすべきかを示していますが、System.Netトレースを設定してそれを達成する方法については詳しく説明していません。

この質問は、件名へのクエリに対するGoogleの最初の結果であり、私たちは皆忙しいので、この情報を追い詰める必要がなくなると思いました。

System.WebHttpWebRequestsのデバッグに非常に強力であり、web.configを使用して簡単に設定できます。

<configuration>
    <system.diagnostics>

        <trace autoflush="true" /> 

        <sources>
            <source name="System.Net" maxdatasize="1024">
                <listeners>
                    <add name="MyTraceFile"/>
                    <add name="MyConsole"/>
                </listeners>
            </source>
        </sources>

        <sharedListeners>
            <add
              name="MyTraceFile"
              type="System.Diagnostics.TextWriterTraceListener"
              initializeData="System.Net.trace.log" />
                <add name="MyConsole" type="System.Diagnostics.ConsoleTraceListener" />
        </sharedListeners>

        <switches>
            <add name="System.Net" value="Verbose" />
        </switches>

    </system.diagnostics>
</configuration>

コードに単純なHttpWebRequestを追加し、Visual Studioでデバッグモードで実行すると、デバッグコンソールに次の情報が表示されます。

System.Net Verbose: 0 : [6596] WebRequest::Create(https://example.com/service.asmx)
System.Net Verbose: 0 : [6596] HttpWebRequest#62063506::HttpWebRequest(https://example.com/service.asmx#11234)
System.Net Information: 0 : [6596] RAS supported: True
System.Net Verbose: 0 : [6596] Exiting HttpWebRequest#11234::HttpWebRequest() 
System.Net Verbose: 0 : [6596] Exiting WebRequest::Create()     -> HttpWebRequest#11234
System.Net Verbose: 0 : [6596] HttpWebRequest#11234 ::GetRequestStream()
System.Net Verbose: 0 : [6596] ServicePoint#11234 ::ServicePoint(example.com:443)
System.Net Information: 0 : [6596] Associating HttpWebRequest#11234with ServicePoint#11234
System.Net Information: 0 : [6596] Associating Connection#11234 with HttpWebRequest#11234 
System.Net Information: 0 : [6596] Connection#11234 - Created connection from x.x.x.x:xx to x.x.x.x:xx.
System.Net Information: 0 : [6596] TlsStream#11234 ::.ctor(Host=example.com, #certs=0)
System.Net Information: 0 : [6596] Associating HttpWebRequest#11234 with ConnectStream#11234 
System.Net Verbose: 0 : [6596] Exiting HttpWebRequest#11234 ::GetRequestStream()    -> ConnectStream#11234 
System.Net Verbose: 0 : [6596] ConnectStream#7740977::Write()
System.Net Verbose: 0 : [6596] Data from ConnectStream#11234::Write
System.Net Verbose: 0 : [6596] 00000000 : 3C 73 6F 61 70 3A 45 6E-76 65 6C 6F 70 65 0D 0A : <soap:Envelope..
...etc

これは、Webサービスクライアントエラーの原因を見つけようとするときに特に役立ちます。ヘッダーが欠けていたことがわかりました。

125
kamui

wireshark のようなネットワークトラフィックスニファーを使用できます。

これはデバッグプロキシではありませんが、allトラフィックを探知し、生のリクエスト/レスポンスを確認できます。

5
Oded

ここで自分の質問に答えます。別の方法を考えたからです。基本的には、着信Webリクエストを記録するページにHttpWebRequestを再ポイントするという考え方です。言い換えると、このフォーラムの投稿に従ってカスタムHTTPハンドラーをセットアップします。

http://forums.asp.net/t/353955.aspx

そして、この新しいエンドポイントを指すようにHttpWebRequestのURLを変更しますが、リクエストの他のすべての要素は同じままにします。結果をファイルなどに書き込むと、黄金色になります。

4
eeeeaaii

Telerik Fiddler をダウンロードして、着信/発信トラフィックをキャプチャすることをお勧めします。

ここに、そのツールでそれを行う方法の簡単な例を示します。

  1. キャプチャトラフィックが有効になっていることを確認してください: enter image description here
  2. ブラウザを開いてページを更新するか、HTTPクライアント経由でリクエストを送信します。 enter image description here
  3. Fiddlerへの切り替え後、リクエストが表示されるはずです。 enter image description here
  4. 上部で「未加工」タブをナビゲートしてみてください。 enter image description here
  5. 下のウィンドウには、生のリクエストがあります enter image description here
3
Mroczny Arturek

別の提案。 独自のWebプロキシを実装する 、および WebRequest.Proxy でそれを使用するように要求を設定します。その後、プロキシインスタンスからトラフィックを抽出できるはずです。

編集:リンクの更新。

1
Mike Atlas

これは古い質問であることはわかっていますが、アプリケーション構成ファイルを制御しなかった厳しい場所にいたので、コードを介してトレースを有効にし、生の要求/応答データに簡単にアクセスする簡単な方法が必要でしたイベント。そこで、私はこのカスタムクラスHttpRawTraceListenerをまとめました。これは、私の立場にある他の人に役立つかもしれません。

https://github.com/jhilgeman/HttpRawTraceListener/blob/master/HttpRawTraceListener.cs

ファイルをプロジェクトに追加して、次のように呼び出すのと同じくらい簡単に設計されました:

System.Diagnostics.HttpRawTraceListener.Initialize();

...トレースを開始します。そこから、要求/応答はトレースメッセージから解析され、System.Diagnostics.HttpRawTraceListener.FinishedCommunicationイベントを介して利用可能になります。

おそらくすべてのシナリオに完全に対応するわけではありません(たとえば、プロキシではないため、ブラウザーからのWeb要求をキャプチャしません)が、WebサービスへのHttpWebRequests要求/応答をキャプチャするには非常にうまく機能します。このようなものが必要な場合は、良い出発点になります。

0
jhilgeman

.NETが嘘をついていると思うと言います。具体的な例は、ヘッダーContent-LengthがHTTP応答にありません。

しかし、ヘッダーContent-Lengthは、HTTP応答には必要ありません。実際、応答の本文が動的であり、その長さが事前にわからない場合、Content-Lengthヘッダーは省略されます!

0
yfeldblum