Подтвердить что ты не робот

Как просмотреть необработанный HTTP-запрос, отправляемый классом HttpWebRequest?

Я знаю, что вы все будете отвечать "использовать прокси-сервер отладки, такой как Fiddler", но это не так просто.

Вот моя ситуация: у меня есть код, который выполняется на сервере, в ASP.NET-странице с кодом (aspx.cs), который (между прочим) устанавливает соединение с другим сервером, захватывает некоторые вещи и затем форматирует его и возвращает его в браузер.

Проблема в том, что другой сервер делает неправильную вещь, и поэтому я хочу иметь возможность передать флаг отладки на страницу (через строку запроса, например? debug = true), чтобы она распечатывала полностью необработанный HTTP-запрос, который он отправляет на другой сервер, чтобы я мог видеть, что это за ошибка. Этот код работает в нескольких местах, поэтому я хочу иметь возможность просто передать этот флаг на dev, промежуточном или производственном процессе и просто увидеть запрос, не имея необходимости выяснять, могут ли производственные серверы разговаривать с некоторым прокси-сервером, который существует где-то, и т.д.

Вы могли бы подумать, что было бы легко сделать это, не так ли? Поэтому я чувствую, что я сумасшедший или что-то, но я посмотрел ссылку на HttpWebRequest и его родительский класс WebRequest и - ничего. Нет. Вы бы подумали, что Microsoft подумала бы об этом. Самое близкое, что вы можете получить доступ к коллекции "Заголовки", но когда я это пробовал, он опустил некоторые действительно важные заголовки, такие как "длина содержимого", поэтому он должен "лгать" мне (я знаю, что это врет, потому что я знаю за того, что удаленный сервер возвращает статус 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();
4b9b3361

Ответ 1

Вы можете использовать механизм трассировки System.Net, чтобы просмотреть необработанные HTTP-запросы, отправленные на провод. Вы также можете добавить свой собственный tracelistener к процессу.

Ответ 2

Я понимаю, что это старый вопрос. Ответ @feroze говорит о том, что делать, но не раскрывает подробностей о том, как настроить трассировку System.Net для ее достижения.

Поскольку этот вопрос был первым результатом Google для моего запроса по теме, и, поскольку мы все занятые люди, я подумал, что спасу всех вас от необходимости выслеживать эту информацию.

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

Я нашел это особенно полезным, когда пытался выяснить причину ошибки клиента веб-сервиса. Оказалось, мне не хватало заголовка.

Ответ 3

Вы можете использовать сниффер сетевого трафика, например wireshark.

Это не прокси-сервер отладки, но будет обнюхивать весь трафик и просматривать сырые запросы/ответы.

Ответ 4

отвечая на мой собственный вопрос здесь, потому что я думал о другом способе сделать это. В основном идея заключается в том, что вы перенаправляете HttpWebRequest на страницу, которая регистрирует входящий необработанный HTTP-запрос. Другими словами, настроить пользовательский обработчик HTTP в соответствии с этим сообщением форума:

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

И затем измените только URL-адрес в HttpWebRequest, чтобы указать на эту новую конечную точку, но сохраните все остальные элементы запроса одинаково. Напишите результат в файл или что-то еще, и вы золотые.

Ответ 5

Я предлагаю вам скачать Telerik Fiddler для захвата входящего/исходящего трафика.

Вот простой пример, как это сделать с помощью этого инструмента:

  • Убедитесь, что включен Capture Traffic: введите описание изображения здесь
  • Откройте браузер и обновите страницу или просто отправьте запрос через HTTP-клиент. введите описание изображения здесь
  • После этого переключения на Fiddler вы должны увидеть свой запрос: введите описание изображения здесь
  • Наверху перейдите на вкладку "Raw". введите описание изображения здесь
  • В приведенном ниже окне находится ваш необработанный запрос введите описание изображения здесь

Ответ 7

Вы говорите, что считаете, что .NET лжет вам, и конкретный пример, который вы даете, состоит в том, что заголовок Content-Length отсутствует в ответе HTTP.

Но заголовок Content-Length не требуется из ответа HTTP. На самом деле, если тело ответа находится в любой динамике, и если его длина неизвестна заранее, то весьма вероятно, что заголовок Content-Length будет опущен!

Ответ 8

Я знаю, что это старый вопрос, но я оказался в трудном положении, когда я не управлял файлом конфигурации приложения, поэтому мне нужен был простой способ включить трассировку через код, а затем легко получить доступ к необработанным данным запроса/ответа в событие. Поэтому я собрал этот пользовательский класс, HttpRawTraceListener, который может быть полезен для других, находящихся на моей позиции:

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

Он был разработан так, чтобы было просто добавить файл в проект, а затем вызвать:

System.Diagnostics.HttpRawTraceListener.Initialize();

... чтобы начать след. Оттуда запросы/ответы будут проанализированы из сообщений трассировки, а затем будут доступны через событие System.Diagnostics.HttpRawTraceListener.FinishedCommunication.

Вероятно, он не на 100% идеален для каждого сценария (например, это не прокси-сервер, поэтому он не будет захватывать веб-запросы из браузера, например), но он довольно хорошо работает для захвата запросов/ответов HttpWebRequests к веб-службам, и это может быть хорошей отправной точкой, если вам нужно что-то подобное.

Ответ 9

Мне нужно что-то упустить, потому что получение необработанного 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);

}