Kamyar Nazeri
Kamyar Nazeri

Reputation: 26524

HttpWebRequest times out on the second call to the Web Server

I've got a very strange problem here:

There is a RESTfull web service on a Python Paste web server, a WPF .net application makes a http POST request to the server every 2 seconds. The problem is that on the second call to the server, the request times out! sometimes later (say forth or fifth) requests work again and later again I get this "time out" exception!

The IntelliTrace shows that there was a blocked operation in ws2_32.dll:

A blocking operation was interrupted by a call to WSACancelBlockingCall

I simulated the REST web server on the IIS using asp.net and the problem no longer exists, so I assume it might be the Python server config! But the Python Web Server works normally when I make the request from within the browser!

However I tried different things in the .net client application:

None of the above seems to work! However the funny part is that when I set a break-point to the GetRequestStream() line in VS 2012, the request dos not timeout and works properly!

Debugging the .net managed code using reflection I figured that the unmanaged recv method of the ws2_32.dll causes the operation to block and hence the web request times out!

Here's the C# code:

static void Main(string[] args)
{
    Task.Run(() =>
    {
        while (true)
        {
            Thread.Sleep(2000);
            Console.WriteLine(PostData());
        }
    });

    Console.ReadLine();
}

public static string PostData()
{
    try
    {
        var response = "";
        var httpRequest = WebRequest.CreateHttp("http://remote_address");
        httpRequest.ServicePoint.ConnectionLimit = 500;
        httpRequest.Method = "POST";
        httpRequest.ContentType = "application/x-www-form-urlencoded";
        httpRequest.Timeout = 5000;

        using (var writer = new StreamWriter(httpRequest.GetRequestStream()))
        {
            writer.Write("req=" + "[some parameters]");
        }

        using (WebResponse httpResponse = httpRequest.GetResponse())
        {
            using (var data = httpResponse.GetResponseStream())
            {
                StreamReader sr = new StreamReader(data, Encoding.UTF8);
                response = sr.ReadToEnd();
            }

            httpResponse.Close();
        }

        return response;
    }
    catch (WebException ex)
    {
        return "time out!";
    }
}

Is there anything I can do to make this work?

Upvotes: 1

Views: 1751

Answers (1)

Kamyar Nazeri
Kamyar Nazeri

Reputation: 26524

I managed to fix the issue with disabling Expect100Continue header:

ServicePointManager.Expect100Continue = false;

According to the HTTP 1.1 protocol, when this header is sent, client requests that use the POST method expect to receive a 100-Continue response from the server to indicate that the client should send the data to be posted.

Having this property set to true (which is the default behavior of .Net) the data is not sent with the initial request. Instead, this header is sent to the web server which responds with 100-Continue if implemented correctly. However, not all web servers handle this correctly, including the server to which I am attempting to post data. I sniffed the headers using Fiddler and noticed that my code does send this header, while the Python Paste does not!

Upvotes: 1

Related Questions