简体   繁体   English

如何查看HttpWebRequest类发送的原始HTTP请求?

[英]How do I see the raw HTTP request that the HttpWebRequest class sends?

I know you are all going to answer "use a debugging proxy server like Fiddler" but it's not that simple. 我知道你们都会回答“使用像Fiddler这样的调试代理服务器”,但事情并非那么简单。

Here's my situation: I have some code that runs on a server, in an ASP.NET page code-behind (aspx.cs), which (among other things) establishes a connection to another server, grabs some stuff, and then formats it and returns it to the browser. 这是我的情况:我有一些代码在服务器上运行,在ASP.NET页面代码隐藏(aspx.cs)中,其中(除其他外)建立与另一个服务器的连接,抓取一些东西,然后格式化它并将其返回给浏览器。

The problem is that the other server is doing the wrong thing, and so I want to be able to pass a debugging flag into the page (via the query string, eg ?debug=true) so that it will print out the completely raw HTTP request that it is sending to the other server so I can see what the heck is wrong. 问题是其他服务器做错了,所以我希望能够将调试标志传递到页面中(通过查询字符串,例如?debug = true),这样它就会打印出完全原始的 HTTP请求它发送到其他服务器所以我可以看到什么是错的。 This code is running in several places so I want to be able to just pass in this flag on dev, staging, or production and just see the request, without having to figure out whether the production servers can talk to some proxy server that exists somewhere, etc. 这段代码在几个地方运行,所以我希望能够在dev,staging或production上传递这个标志,只看到请求,而不必弄清楚生产服务器是否可以与某个存在的代理服务器通信等

You would think that it would be easy to do this, right? 你会认为这样做很容易,对吧? So I feel like I'm crazy or something but I looked at the reference for HttpWebRequest and its parent class WebRequest and -- nothing. 所以我觉得我疯了或者别的什么,但我查看了HttpWebRequest及其父类WebRequest的参考资料 - 什么都没有。 No can do. 没有办法。 You would think Microsoft would have thought of this. 你会认为微软会想到这一点。 The closest thing is that you can access the "Headers" collection but when I tried it, it omitted some really important headers like "content length" -- so it must be "lying" to me (I know it's lying, because I know for a fact that the remote server is returning a 200 status -- the request is successful, it's just returning bad/different/wrong data) 最接近的是你可以访问“Headers”集合,但是当我尝试它时,它省略了一些非常重要的标题,如“内容长度” - 所以它必须“撒谎”给我(我知道它在撒谎,因为我知道因为远程服务器返回200状态 - 请求成功,它只返回错误/不同/错误的数据)

Here is the asked-for code example: 这是ask-for代码示例:

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();

I realise that this is an old question. 我意识到这是一个老问题。 @feroze's answer says what to do, but does not go into any detail on how to set up System.Net tracing to achieve it. @ feroze的答案说明了该怎么做,但没有详细介绍如何设置System.Net跟踪来实现它。

As this question was the first Google result for my query into the subject, and as we are all busy people, I thought I would save you all from having to hunt down this information. 由于这个问题是我对该主题进行查询的第一个Google结果,并且因为我们都是忙碌的人,所以我认为我可以帮助您解决这些问题。

System.Web is very powerful for debugging HttpWebRequest s and can be easily set up using the web.config : System.Web对于调试HttpWebRequest非常强大,可以使用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>

Adding a simple HttpWebRequest in your code, and running in debugging mode in Visual Studio, the following information will be displayed in the debug console: 在代码中添加简单的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

I found this especially useful when trying to find out the cause of a webservice client error. 我发现这在尝试找出Web服务客户端错误的原因时特别有用。 It turned out I was missing a header. 原来我错过了一个标题。

You can use System.Net tracing mechanism to see the raw HTTP requests sent on the wire. 您可以使用System.Net跟踪机制查看在线路上发送的原始HTTP请求。 You can also add your own tracelistener to the process. 您还可以将自己的tracelistener添加到流程中。

You can use a network traffic sniffer like wireshark . 您可以使用像wireshark这样的网络流量嗅探器。

This is not a debugging proxy, but will sniff all traffic and let you see the raw requests/responses. 这不是调试代理,但会嗅探所有流量并让您看到原始请求/响应。

answering my own question here, because I thought of another way to do it. 在这里回答我自己的问题,因为我想到了另一种方法。 Basically the idea is -- you re-point the HttpWebRequest to a page that logs the incoming raw HTTP Request. 基本上这个想法是 - 你将HttpWebRequest重新指向一个记录传入的原始HTTP请求的页面。 In other words set up a custom HTTP handler as per this forum post: 换句话说,根据此论坛帖子设置自定义HTTP处理程序:

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

And then change just the URL in the HttpWebRequest to point to this new endpoint, but keep all other elements of the request the same. 然后只更改HttpWebRequest中的URL以指向此新端点,但保持请求的所有其他元素相同。 Write the result to a file or something and you're golden. 将结果写入文件或其他内容,你就是金色的。

I suggest you to download Telerik Fiddler to capture incoming/outcoming traffic. 我建议你下载Telerik Fiddler来捕获传入/传出的流量。

Over here is simple example how to do it by that tool: 这里有一个简单的例子,如何通过该工具完成:

  1. Be sure that the Capture Traffic is enabled: 确保已启用“捕获流量”: 在此输入图像描述
  2. Open browser and refresh the page, or just send request via HTTP client. 打开浏览器并刷新页面,或者只通过HTTP客户端发送请求。 在此输入图像描述
  3. After that switch to the Fiddler, you should see your request: 在切换到Fiddler之后,您应该看到您的请求: 在此输入图像描述
  4. At the top try to navigate “Raw” tab. 在顶部尝试导航“原始”选项卡。 在此输入图像描述
  5. In the below window is your raw request 在下面的窗口中是您的原始请求 在此输入图像描述

Another suggestion. 另一个建议。 Implement your own web proxy , and set your request to use it with WebRequest.Proxy . 实现您自己的Web代理 ,并将您的请求设置为与WebRequest.Proxy一起使用。 Then you should be able to extract the traffic from the proxy instance. 然后,您应该能够从代理实例中提取流量。

Edit: update for links. 编辑:更新链接。

You say that you think .NET is lying to you, and the specific example you give is that the header Content-Length is missing from the HTTP response. 你说你认为.NET对你说谎,你给出的具体例子是HTTP响应中缺少标题Content-Length

But the header Content-Length is not required from an HTTP response. 但HTTP响应不需要标头Content-Length In fact, if the body of the response is in any dynamic, and if its length is not known in advance, then it is highly likely that the Content-Length header will be omitted! 事实上,如果响应的主体处于任何动态,并且如果事先不知道它的长度,那么很可能会省略Content-Length标头!

I know this is an old question, but I was in a tough spot where I didn't control the application config file, so I needed an easy way to enable the tracing via code and then easily access the raw request/response data in an event. 我知道这是一个老问题,但我处在一个很难控制应用程序配置文件的地方,因此我需要一种简单的方法来通过代码启用跟踪,然后轻松访问原始请求/响应数据。事件。 So I put together this custom class, HttpRawTraceListener, which might be of use to others that are in my position: 所以我把这个自定义类HttpRawTraceListener放在一起,这可能对我所在的其他人有用:

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

It was designed to be as simple as adding the file to your project, then calling: 它的设计就像将文件添加到项目中一样简单,然后调用:

System.Diagnostics.HttpRawTraceListener.Initialize();

...to start the trace. ......开始追踪 From there, requests/responses will be parsed out of the trace messages and then be made available via the System.Diagnostics.HttpRawTraceListener.FinishedCommunication event. 从那里,请求/响应将从跟踪消息中解析出来,然后通过System.Diagnostics.HttpRawTraceListener.FinishedCommunication事件提供。

It's probably not 100% perfect for every scenario (eg it's not a proxy, so it won't capture web requests from a browser, for example), but it works pretty well for capturing HttpWebRequests requests/responses to web services, and it might be a good starting point if you need something like this. 对于每种情况,它可能不是100%完美(例如,它不是代理,因此它不会捕获来自浏览器的Web请求),但它可以很好地捕获对Web服务的HttpWebRequests请求/响应,并且可能如果你需要这样的东西,那么这是一个很好的起点。

I must be missing something, because getting the raw HTTP request as ASCII text is really easy, as long as you grab it in the Page_Init() it'll be different by Page_Load(). 我必须遗漏一些东西,因为将原始HTTP请求作为ASCII文本获取非常简单,只要你在Page_Init()中获取它,它就会因Page_Load()而不同。

protected void Page_Init(object sender, EventArgs e)
{
    //this gets the raw request as an ASCII String.
    byte[] biData = Request.BinaryRead(Request.TotalBytes);
    string sWholeRequestAsString = System.Text.Encoding.ASCII.GetString(biData);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM