0

We have a program that has been running for years making API calls to a web server using HttpWebRequest and yesterday it started giving an error (something like "connection forcibly closed by remote host"). The request works just fine when made through a web browser so I would love to be able to see the difference in requests. With the Firefox developer console, I can see the raw request that is made through the browser (that works) and I need to compare that to the http request that is made from our program. It seems like it should be simple (and very useful) to stream the request out to a string or a file so I can look at it (but I have not had any luck finding how to do that).

Can you tell me how to modify the below code to store the request that HttpWebRequest would send to a file or a string (instead of a network stream)?

public string Post(string uri, string data, string contentType, string method = "POST")
{
    byte[] dataBytes = Encoding.UTF8.GetBytes(data);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    request.ContentLength = dataBytes.Length;
    request.ContentType = contentType;
    request.Method = method;

    using(Stream requestBody = request.GetRequestStream())
    {
        requestBody.Write(dataBytes, 0, dataBytes.Length);
    }

    using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using(Stream stream = response.GetResponseStream())
    using(StreamReader reader = new StreamReader(stream))
    {
        return reader.ReadToEnd();
    }
}
David
  • 194
  • 1
  • 13
  • Try converting `request` to a json string? Then take a look at that json to see what all the details of the actual request are. – Casey Crookston Jul 17 '20 at 20:18
  • 1
    If you modernize your code to use `HttpClient` you can add a logging handler. – Aluan Haddad Jul 17 '20 at 20:54
  • Maybe remote server stopped supporting of old TLS. Try set `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12` at application startup. Btw, it's recommended to use `HttpClient` instead of old `HttpWebRequest`. – aepot Jul 17 '20 at 23:26
  • If you're testing that app in Windows 7, setting (or adding) `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12` is mandatory, otherwise it won't be included. In Windows 10,it's the default. Also related to Windows 7, an increasing number of Web Sites are now supporting only the newer cipher suites: Windows 7 doesn't have these (and won't get support, since it's terminated). Web Browsers carry (and manage) cipher suites of their own, so it won't help your case if this is the scenario. HttpClient won't help either, it still uses HttpWebRequest under the hood. – Jimi Jul 18 '20 at 02:54
  • See also the notes here: [Which TLS version was negotiated?](https://stackoverflow.com/a/48675492/7444103) – Jimi Jul 18 '20 at 02:55
  • @Jimi _HttpClient won't help either, it still uses HttpWebRequest under the hood_ - correct but only in .NET Framework. – aepot Jul 18 '20 at 09:46
  • @aepot Well, this is tagged `.Net`. Anyway, not relevant, since this, most probably, goes over the head of both HttpWebRequest and HttpClient. – Jimi Jul 18 '20 at 09:56

1 Answers1

0

You can't simply log the httprequest. Because you should also consider logging all the headers.

I suggest you to use some http sniffer to log the traffic(if you can't debug or modify your code)

In addition you can catch the exceptions by using WebException and get the raw error message from the server. Maybe it'll give you idea what the problem is.

catch (WebException ex)
{
    using (var stream = ex.Response.GetResponseStream())
    using (var reader = new StreamReader(stream))
    {
        var responseString = reader.ReadToEnd();
    }
} 
DLL_Whisperer
  • 815
  • 9
  • 22