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:
-
I have increased the ServicePoint’s
DefaultConnectionLimit:ServicePointManager.DefaultConnectionLimit = 500; -
I created a new thread for any new request to the server and aborted it when request is done!
-
I created a new
AppDomainbefore any request and explicitly unloaded it when process is done! -
Tried different http request headers:
connection=keep-alive, accept=*
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?
I managed to fix the issue with disabling
Expect100Continueheader:According to the
HTTP 1.1protocol, when this header is sent, client requests that use the POST method expect to receive a100-Continueresponse 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 with100-Continueif 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 usingFiddlerand noticed that my code does send this header, while thePython Pastedoes not!