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

7z5jn7bk  于 2023-10-21  发布在  .NET
关注(0)|答案(9)|浏览(187)

我知道你们都会回答“使用像Fiddler这样的调试代理服务器”,但这并不那么简单。
我的情况是这样的:我有一些在服务器上运行的代码,在一个ASP.NET页面代码隐藏(aspx. cs)中,它(在其他事情中)建立到 * 另一个 * 服务器的连接,抓取一些东西,然后格式化它并将其返回给浏览器。
问题是另一个服务器正在做错误的事情,所以我希望能够将调试标志传递到页面中(通过查询字符串,例如:?debug=true),这样它就可以打印出它发送到另一个服务器的 * 完全原始的 * HTTP请求,这样我就可以看到到底出了什么问题。这段代码在多个地方运行,所以我希望能够在dev、staging或production上传递这个标志,只看到请求,而不必弄清楚生产服务器是否可以与某个地方存在的代理服务器进行通信。
你会认为这是很容易做到的,对吧?所以我觉得我疯了,但是我看了HttpWebRequest的参考资料和它的父类WebRequest,什么都没有。没办法。你可能会认为微软会想到这一点。最接近的事情是,你可以访问“Headers”集合,但当我尝试它时,它忽略了一些非常重要的头,如“内容长度”-所以它必须对我“撒谎”(我知道它在撒谎,因为我知道远程服务器正在返回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();
roqulrg3

roqulrg31#

我知道这是一个老问题。@feroze的回答说了该怎么做,但没有详细说明如何设置System.Net跟踪来实现它。
由于这个问题是我查询这个主题的第一个谷歌结果,而且我们都是忙碌的人,我想我会保存你们所有人都不必寻找这些信息。
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>

在代码中添加一个简单的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服务客户端错误的原因时特别有用。结果发现我少了一个头球。

ljo96ir5

ljo96ir52#

您可以使用System.Net跟踪机制来查看网络上发送的原始HTTP请求。您还可以将自己的tracelistener添加到进程中。

wwodge7n

wwodge7n3#

你可以使用像wireshark这样的网络流量嗅探器。
这不是一个调试代理,但会嗅探 * 所有 * 流量,让你看到原始的请求/响应。

h5qlskok

h5qlskok4#

回答了我自己的问题,因为我想到了另一种方法。基本上,这个想法是--你将HttpWebRequest重新指向一个记录传入的原始HTTP请求的页面。换句话说,按照这个论坛帖子设置一个自定义HTTP处理程序:
http://forums.asp.net/t/353955.aspx
然后仅更改HttpWebRequest中的URL以指向此新端点,但保持请求的所有其他元素不变。把结果写进一个文件或什么的,你就很好了。

zhte4eai

zhte4eai5#

我知道这是一个老问题,但我在一个坚韧的地方,我没有控制应用程序配置文件,所以我需要一个简单的方法来启用跟踪通过代码,然后轻松地访问原始请求/响应数据的事件。所以我把这个自定义类,HttpRawTraceReader,它可能对其他处于我位置的人有用:
https://github.com/jhilgeman/HttpRawTraceListener/blob/master/HttpRawTraceListener.cs
它被设计为简单到将文件添加到项目中,然后调用:

System.Diagnostics.HttpRawTraceListener.Initialize();

开始追踪从那里,请求/响应将从跟踪消息中解析出来,然后通过System.Diagnostics. HttpRawTraceServer. RedshedCommunication事件提供。
它可能不是100%完美的每一个场景(例如。它不是一个代理,所以它不会捕获来自浏览器的Web请求),但它可以很好地捕获对Web服务的HttpWebRequests请求/响应,如果你需要这样的东西,它可能是一个很好的起点。

mdfafbf1

mdfafbf16#

我建议你下载Telerik Fiddler来捕获传入/传出的流量。
这里是一个简单的例子,如何使用该工具:
1.确保已启用捕获流量:

1.打开浏览器并刷新页面,或者通过HTTP客户端发送请求。

1.切换到Fiddler后,您应该看到您的请求:

1.在顶部尝试导航“原始”选项卡。

1.在下面的窗口中是您的原始请求x1c4d 1x

lpwwtiir

lpwwtiir7#

另一个建议。Implement your own web proxy,并将您的请求设置为与WebRequest.Proxy一起使用。然后,您应该能够从代理示例中提取流量。
编辑:更新链接。

wnrlj8wa

wnrlj8wa8#

你说你认为.NET在欺骗你,你给予的具体例子是HTTP响应中缺少头Content-Length
但是HTTP响应中不需要报头Content-Length。事实上,如果响应的主体是任何动态的,并且如果它的长度事先不知道,那么很有可能Content-Length头将被省略!

vjrehmav

vjrehmav9#

此回答不包含请求内容。(但如果您需要诊断连接问题,它仍然可以提供帮助)。
NET Core中System.Net代码的跟踪日志记录可以通过创建一个继承自System.Diagnostics.Tracing. EventLog的类来捕获
参见https://github.com/dotnet/runtime/issues/64977了解详细信息+原始建议。
范例:

private class SystemNetEventListener : EventListener
{
  protected override void OnEventSourceCreated(EventSource eventSource)
  {
    // take anything from System.Net
    if (eventSource.Name?.StartsWith("Private.InternalDiagnostics.System.Net.") == true)
    {
      EnableEvents(eventSource, EventLevel.LogAlways);
    }
  }

  protected override void OnEventWritten(EventWrittenEventArgs eventData)
  {
    try
    {
      // produce a string that can be logged
      var sb = new StringBuilder().Append($"{eventData.TimeStamp:HH:mm:ss.fffffff}[{eventData.EventName}] ");
      for (int i = 0; i < eventData.Payload?.Count; i++)
      {
        if (i > 0)
          sb.Append(", ");
        sb.Append(eventData.PayloadNames?[i]).Append(": ").Append(eventData.Payload[i]);
      }

      Console.WriteLine(sb.ToString().Trim());
    }
    catch
    {
      // on failure... well... we are the logger, so there's nobody to tell we failed
    }
  }
}

使用方法:

var listener = new SystemNetEventListener(); // start logging
... // do HTTP/Websocket stuff
listener.Dispose(); // stop logging

相关问题