HttpWebException Operation has timed out - c#

I'm running into an issue where on the first request, and then randomly over time, my client is getting operation time out, with http time out set to 5 seconds. I have 3 other clients running on other machines that are not failing. This machine is windows xp and a bit slower, but it seems like this is happening too frequently. In these instances the server does not even receive a connection attempt. The below code is run in a loop with a monitor.wait so that it only polls every 10 seconds. I thought at first that I wasn't disposing of the connection properly but it seems like I am. I can't run a debugger on this machine(it's not my machine) so I'm struggling to find the issue. It seems like the client is sometimes too slow to even open a connection.
try
{
Uri targetUri = new Uri(urlFormatted.ToString());
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUri);
request.Method = "GET";
request.Timeout = 10000;
WriteInfo(this.GetType(), "Requesting URL: " + urlFormatted.ToString());
response = (HttpWebResponse)request.GetResponse();
break;
}
catch (System.Net.WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
response = (HttpWebResponse)ex.Response;
logger.Error("Http request failed with errorcode:" + (int)response.StatusCode);
}
logger.Error("Error connecting to [" + server + "]", ex);
if (ex.InnerException != null)
{
responseString = ex.InnerException.Message;
}
else
{
responseString = ex.ToString();
}
}
if (response != null)
{
try
{
//Response handling
}
catch (Exception ex)
{
//errorhandling
}
finally
{
response.Close();
response.Dispose();
}
}
Is there a way to get more info? It seems like the exception is just saying "the operation has timed out", which doesn't give me a lot to go on. On my debugging machine I can get a connection refused message by shutting down my server, but nothing like this, where the server never receives the request.
Also note: The other machines are all windows 7, and a little beefier. They all have the same .net library installed.
More information:
netstat -a 1 -n -p tcp
does not show the connection at all when it's attempting to connect but gets the operation timed out message. This seems weird. It's like it's not actually attempting the connection. It does show when it establishes correctly.

Related

Restsharp delay prior to call (15 sec) - postman instant

I have the following code in a C# WPF app. This has been working perfectly in testing for a month:
try
{
string zServerName = "http://" + dispenseDetails.dipenseServerCompName + ":8800/Api/";
var options = new RestClientOptions(zServerName);
var client = new RestClient(options);
var request = new RestRequest(endpoint + APIparameter);
request.Method = apiMethod;
Debug.WriteLine(zServerName + endpoint + APIparameter);
request.Method = apiMethod;
if (!getToken)
{
if (string.IsNullOrEmpty(dispenseDetails.curZToken))
{
dispenseDetails.curZToken = getNewToken();
Debug.WriteLine("Got new token: " + dispenseDetails.curZToken);
}
else
{
Debug.WriteLine("Already have token: " + dispenseDetails.curZToken);
}
request.AddHeader("Authorization", "Bearer " + dispenseDetails.curZToken);
}
var response = client.ExecuteAsync(request).Result;
Debug.WriteLine(response);
if (response.ErrorException != null)
{
msgBox.Show(null, "Connection failed. " + response.ResponseStatus);
return "false";
}
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var JsonString = response.Content;
Debug.WriteLine(JsonString);
return JsonString;
}
else
{
Utility.LogFile("API Fail", response.StatusCode.ToString() + ":" + response.Content, apiMethod + " " + endpoint, "zDispenseServer: " + APIparameter + reqBody, false);
return "false";
}
}
catch (Exception exe)
{
Utility.LogFile(exe.Message, "Critial Error: Cannot contact ZDispense Server", "Api Utility", "RestAPI",false);
return "false";
}
Now I am aware it isn't great code and I'm fixing up on the responses (I'm self taught amateur).
My issue is now when I make this call the comp hangs and waits and gets an answer... 15-> 30 secs later.
I understand I'm not using async/await and this will fix the hang, but it has always worked instantly.
TESTED:
I do exactly the same call (using same user and password and everything) with Postman
Status 200OK
Time 40ms
So postman is wokring as per usual.
Wireshark
I have never used wireshark but installed for this reason.
I tested with Postman and the instant I send the call it appears on Wireshark.
0.03s response time.
Tested with my app/restsharp:
0.03s response time BUT it takes about 15-30 secs to appear in wireshark.
My theory is that the call is fast (eg the call then response) as it shows on WS fast BUT it's like the call sits there and is delayed THEN makes the call...
I have other code and another API which is working perfectly fine using the exact code above but to a different server.
The "fast" server is my own nodejs API
This one is a companies API test software on a computer on my local network (home/personal).
I don't know if that matters but thought to mention it.
Could anyone point me in the right direction?
Am I right in saying if it doesnt appear in WS for 15 secs, that means its... "sitting" in Visual Studio before being sent, and if this is the case.... why??
I have no proxies, no weird interesting stuff.
Fresh install of Vis studio because I tried that in case I had some setting screwing things up.
EDIT:
It hangs at
var response = client.ExecuteAsync(request).Result;
Hang might not be the right word, I know it isnt an AWAIT but it used to pause for 0.5 sec but now it hangs for 15-30 secs
In WPF, you should either make your method async void and await ExecuteAsync or use the latest version with sync methods that were recently brought back. These methods do some advanced stuff with thread scheduling to ensure it doesn't block.

Recover from a NameResolutionFailure error during a HTTPWebRequest

In our Outlook COM add-in, we're making an API call to our server using the .NET HTTPWebRequest method. One of our customers is running into a System.Net.WebException with the message The remote name could not be resolved: 'mydomain.com' and WebExceptionStatus.NameResolutionFailure as the status. All the users from this particular customer's company are using outlook/the addin from behind a VPN so we are piggy-backing proxy configuration from IE in order to make the request.
Our API calls work for a period of time but then it randomly disconnects and then does not allow future requests to go through either. Once the users close and restart Outlook though, it seems to work just fine again without changing any network configuration or reconnecting to wifi etc.
Other posts like this suggested retrying with a sleep in between. We have added a retry mechanism with 3 attempts, each with a sleep in between but that has not resolved the intermitent issue.
Our domain is hooked up to an AWS Classic Load Balancer so mydomain.com actually resolves a CNAME record to an AWS static domain, pointing to the ELB. I'm not sure if that would have any impact on the request or routing it.
The strange part is we also have a web browser component that loads a web page in a sidebar from the exact same domain as the API calls. It works perfectly and loads a URL from the same domain. The users can also load the URL in their browsers without any issues. It just appears that the HTTPWebRequest is running into the domain resolution issue. We've checked that it's not just a matter of a weak wifi signal. Since they are able to use IE which has the same proxy config to access the site just fine, I don't think it's that.
We're at a loss for how to gracefully recover and have the request try again. I've looked into suggestions from this answer and this other answer, we'll be trying those next. Unfortunately, we are not able to make the requests use direct IP addresses as some of the other answers suggest. That also eliminates the ability to edit the hosts file to point straight to it. The reason is we can't assign a static IP on a classic ELB.
We're considering trying to set the host to use the CNAME record from AWS directly but this is going to cause SSL errors as it doesn't have a valid cert for the CNAME entry. Is there a way to get around that by masking it via a header, similar to the IP approach?
Feel free to ask for more information, I will do my best to provide it.
Any suggestions on what to try / troubleshoot are welcome!
Update: We’re targeting .NET v4.5
Here's the code
var result = string.Empty;
bool retrying = false;
int retries = 0;
HttpWebRequest webRequest = null;
try
{
ServicePointManager.ServerCertificateValidationCallback =
CertificateCheck;
ServicePointManager.MaxServicePoints = 4;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
retry:
webRequest = (HttpWebRequest)WebRequest.Create(uriParam);
webRequest.Timeout = 120000;
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Accept = acceptParam;
webRequest.Headers.Add("Cookie", cookieParam);
webRequest.UseDefaultCredentials = true;
webRequest.Proxy = null;
webRequest.KeepAlive = true; //default
webRequest.ServicePoint.ConnectionLeaseTimeout = webRequest.Timeout;
webRequest.ServicePoint.MaxIdleTime = webRequest.Timeout;
webRequest.ContentLength = dataParam.Length;
using (var reqStream = webRequest.GetRequestStream())
{
reqStream.Write(dataParam, 0, dataParam.Length);
reqStream.Flush();
reqStream.Close();
}
try
{
using (WebResponse webResponse = webRequest.GetResponse())
{
using (var responseStream = webResponse.GetResponseStream())
{
if (responseStream != null)
{
using (var reader = new StreamReader(responseStream))
{
result = reader.ReadToEnd();
}
}
}
webResponse.Close();
}
}
catch (WebException)
{
if (retrying && retries == 3)
{
//don't retry any more
return string.Empty;
}
retrying = true;
retries++;
webRequest.Abort();
System.Threading.Thread.Sleep(2000);
goto retry;
}
}
catch (Exception ex)
{
Log.Error(ex);
result = string.Empty;
}
finally
{
webRequest?.Abort();
}
return result;

Error Handling for WebRequest & Response

I am currently running a method that takes a string (a domain name) and checks to see if the site is available or not and passes the information into a Domain object I have created. Currently, I am running into an issue where one of the sites is down and is in turn crashing the application. Below is the method:
private Domain GetStatus(string x)
{
string status = "";
WebRequest req = HttpWebRequest.Create("http://www." + x);
WebResponse res = req.GetResponse();
HttpWebResponse response = (HttpWebResponse)res;
if ((int)response.StatusCode > 226 || response.StatusCode == HttpStatusCode.NotFound)
{
status = "ERROR: " + response.StatusCode.ToString();
}
else
{
status = "LIVE";
}
Domain temp = new Domain(x, status);
return temp;
}
Initial thoughts were that the response.StatusCode == HttpStatusCode.NotFound would handle such an error but it is currently crashing on the line WebResponse res = req.GetResponse(); with the following response:
System.Net.WebException: 'The remote name could not be resolved: 'www.DOMAIN.com''
The issue is due to the fact that your own code is raising an exception.
This can be due to the lack of an internet connection, or a dns resolve issue (which could be caused by the remote party).
So, if the remote server throws an error, you'll get HTTP 500 Internal Server Error, if you can't reach it; your code throws an exception and you'll need to handle that.
To fix this, you can use a try/catch block, something like this:
private Domain GetStatus(string x)
{
string status = "";
try
{
WebRequest req = HttpWebRequest.Create("http://www." + x);
WebResponse res = req.GetResponse();
HttpWebResponse response = (HttpWebResponse)res;
if ((int)response.StatusCode > 226 ||
response.StatusCode == HttpStatusCode.NotFound)
{
status = "ERROR: " + response.StatusCode.ToString();
}
else
{
status = "LIVE";
}
}
catch (Exception e)
{
status = "ERROR: Something bad happend: " + e.ToString();
}
Domain temp = new Domain(x, status);
return temp;
}
By the way, the message,
The remote name could not be resolved
indicates that the host cannot be resolved.
Most likely cause is that your internet is down or, the domain is misspelled or the route to the domain is faulty (e.g. on intranet environments).
HttpWebRequest is all about HTTP protocol, which is kind of a agreed upon language.
But if the person on the other end doesn't exists, so how should you expect him to return you an "Hello" for example ?
So StatusCode is really just about if the actual remote site did response, what did the response state was according to the request resource, is it Successful(200) ? Not Found(404) ? Unauthorized(401) and so on.
Exception means, i couldn't reach the site because of many reasons.
StatusCode means the resource you requested has return this response type.
But a more actual check if the site is alive or not, is querying a static page and not getting exception, a more healthy check, will querying a static page, you will always count as being Healthy; meaning will return a 200 OK response.
So it all depends on what LIVE means for you (or the client using it).
Is it the remote host is actually receiving requests, meaning no Exceptions.
Or it actually means, he's able to get requests and returning me a valid StatusCode response that i expect him to return (Healthy).

Win10 IOT / UWP: How to detect if a network device (Arduino) is availabe

I'd like to connect if my Arduino is available on the network. I'm trying to access the Arduino web server using an HTTP client and processing the JSON answer.
Since ping is not available in UWP what are my options? (see: Article)
One option would be to handle the exception of the HTTP client. But is there any more elegant way to check the connection before requesting the JSON data?
One method might be using the HTTPClient to do a GetAsync() and check the Status code coming out of it.
Depending on your time constraints, you can wait for it to time out naturally or pass a cancellation token to break it sooner than the defaults.
From here https://learn.microsoft.com/en-us/windows/uwp/networking/httpclient (slightly modified):
//Send the GET request asynchronously and retrieve the response as a string.
Windows.Web.Http.HttpResponseMessage httpResponse = new Windows.Web.Http.HttpResponseMessage();
string httpResponseBody = "";
try
{
//Send the GET request
httpResponse = await httpClient.GetAsync(requestUri);
if(httpResponse.IsSuccessStatusCode) { /* Do something with it */ }
else { /* Do fallback here */ }
}
catch (Exception ex)
{
httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message;
}

RestSharp + Server Down - How do you know if server is down?

I am wondering how can I check if the RestSharp request I made failed because the server is down vs something else.
When I shutdown my server I get a status code of "NotFound" but that could be a particular record was not found(which I do on my site if say they try to find a record that might be recently deleted).
How can I figure out the server is actually down?
Edit
here is my code
private readonly RestClient client = new RestClient(GlobalVariables.ApiUrl);
var request = new RestRequest("MyController", Method.POST);
request.AddParameter("UserId", "1");
request.AddParameter("Name", name.Trim());
var asyncHandle = client.ExecuteAsync(request, response =>
{
var status = response.StatusCode;
});
When the server is down, it should not return a "404 NotFound" error.
The most appropriate in this case is HTTP Error 503 - Service unavailable
The Web server (running the Web site) is currently unable to handle
the HTTP request due to a temporary overloading or maintenance of the
server. The implication is that this is a temporary condition which
will be alleviated after some delay. Some servers in this state may
also simply refuse the socket connection, in which case a different
error may be generated because the socket creation timed out.
That way checking that RestResponse.StatusCode is 503 it will tell you that the server is down.
I am having the same issue.
I decided to check for the ContentLength too. At least my webservice always returns ContentLength>0 (even for NotFound occurrences). This seems to work out.
if ( response.StatusCode == System.Net.HttpStatusCode.NotFound &&
response.ContentLength == -1 ){
==> client couldn't connect to webservice
}
In my scenario, I needed to check if anything happened to the connection, e.g. connection time out, can't resolve the host name, etc. So I also added following code:
try
{
var client = new RestClient(_configuration.ServerUrl);
var request = new RestRequest
{
Resource = _configuration.SomeUrl,
Method = Method.POST
};
var response = client.Execute(request);
if (response.ErrorException != null)
{
throw response.ErrorException;
}
}
catch (WebException ex)
{
// TODO: check ex.Status, if it matches one of needed conditions.
}
For more information about WebExceptionStatus Enumeration, please, see following link https://msdn.microsoft.com/en-us/library/system.net.webexceptionstatus(v=vs.110).aspx

Categories

Resources