Как увидеть необработанный HTTP-запрос, который отправляет класс HttpWebRequest? - PullRequest
62 голосов
/ 28 сентября 2010

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

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

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

Вы бы подумали, что это будет легко сделать, верно? Поэтому я чувствую, что я сумасшедший или что-то в этом роде, но я посмотрел ссылку на 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();

Ответы [ 9 ]

123 голосов
/ 05 сентября 2014

Я понимаю, что это старый вопрос. @ feroze's answer говорит, что делать, но не вдавается в подробности о том, как настроить 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

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

14 голосов
/ 28 сентября 2010

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

5 голосов
/ 28 сентября 2010

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

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

4 голосов
/ 06 октября 2010

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

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

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

3 голосов
/ 13 марта 2018

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

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

  1. Убедитесь, что включен захват трафика: enter image description here
  2. Откройте браузер и обновите страницу, или просто отправьте запрос через HTTP-клиент.enter image description here
  3. После этого переключитесь на Скрипач, вы должны увидеть ваш запрос: enter image description here
  4. Наверху попробуйте перейти «Raw ».enter image description here
  5. В нижнем окне находится ваш необработанный запрос enter image description here
1 голос
/ 28 сентября 2010

Еще одно предложение. Реализуйте свой собственный веб-прокси и настройте запрос на использование его с WebRequest.Proxy . Тогда вы сможете извлечь трафик из экземпляра прокси.

Редактировать: обновить ссылки.

0 голосов
/ 11 июня 2019

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

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

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

System.Diagnostics.HttpRawTraceListener.Initialize();

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

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

0 голосов
/ 26 октября 2016

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

}
0 голосов
/ 28 сентября 2010

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

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

...