I have the following code :
public static QHttpResponse Execute(QHttpRequest request)
{
//Setup the request
HttpWebRequest webrequest = (HttpWebRequest) WebRequest.Create(request.GetFinalUrl());
webrequest.AllowAutoRedirect = request.IsAllowRedirects;
webrequest.Method = request.Method;
webrequest.Accept = "application/json, text/javascript;q=0.9, */*;q=0.5";
webrequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
//request.Host is set automatically
webrequest.UserAgent = request.UserAgent;
if (!String.IsNullOrEmpty(request.Referrer))
webrequest.Referer = request.Referrer;
webrequest.Timeout = 50000;
webrequest.KeepAlive = false;
webrequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Revalidate);
webrequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
if (request.IsAjax)
{
webrequest.Headers.Add("X-Request", "JSON");
webrequest.Headers.Add("X-Requested-With", "XMLHttpRequest");
webrequest.Headers.Add("X-Prototype-Version", "1.7");
}
// Cookies
webrequest.CookieContainer = request.Cookies;
// Write the data to the body for POST and other methods
if (request.IsMethodPost())
{
byte[] dataBytes = Encoding.UTF8.GetBytes(request.GetDataParamString());
webrequest.ContentLength = dataBytes.Length;
using (Stream requestStream = webrequest.GetRequestStream())
requestStream.Write(dataBytes, 0, dataBytes.Length);
}
// Get the response
HttpWebResponse webresponse;
try
{
webresponse = webrequest.GetResponse() as HttpWebResponse;
}
catch (WebException wex)
{
if(request.IsBypassError)
webresponse = wex.Response as HttpWebResponse;
else
throw;
}
// Read to QHttpResponse object
QHttpResponse response = new QHttpResponse();
response.StatusCode = webresponse.StatusCode;
response.NewCookies = webresponse.Cookies;
using (Stream responseStream = webresponse.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
response.Reply = reader.ReadToEnd();
webresponse.Close();
return response;
}
I have this code run multiple times from various locations and randomly (Every couple of hours), it hangs at this line :
webresponse = webrequest.GetResponse() as HttpWebResponse;
I tried setting webrequest.KeepAlive = false;, but I continued to receive the error.
I'd like any available help on solving this, thanks in advance.
EDIT : I'd like to add that this code is executed from two threads. Occasionally they may connect to the same host, but only from these 2 threads. Also, as I see, the response is closed appropriately.
EDIT 2 : Visual studio's debugger says the execution is really stuck at System.dll!System.Net.Sockets.Socket.Receive.
EDIT 3 : In an attempt to see exactly what was causing the bug, I modified the "Get the response" code from above to
// Get the response
HttpWebResponse webresponse = null;
try
{
webresponse = webrequest.GetResponse() as HttpWebResponse;
}
catch (WebException wex)
{
Console.WriteLine("Time : " + DateTime.Now);
Console.WriteLine("Thread name : " + Thread.CurrentThread.Name);
Console.WriteLine("Exception : " + wex);
Console.WriteLine("Exc msg : " + wex.Message);
Console.WriteLine("Url : " + request.GetFinalUrl());
if (request.IsBypassError)
webresponse = wex.Response as HttpWebResponse;
else
{
if (webresponse != null)
{
webresponse.Close();
webresponse.Dispose();
}
throw;
}
}
I received this output :
Time : 5/11/2015 3:13:35 AM
Thread name : BOT A
Exception : System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
at Gameloop.Util.Web.QWebClient.Execute(QHttpRequest request) in e:\Visual Studio - Workspace\Gameloop.Util\Gameloop.Util\Web\QWebClient.cs:line 52
Exc msg : The remote server returned an error: (500) Internal Server Error.
Url : https://website1.com/url/path/to/something (I changed this)
This was the only displayed error and was encountered by thread "BOT A". However, this was not the url the threads appear to have actually frozen at. "BOT A" was actually frozen at 12:00pm at website2.com and "BOT B" was actually frozen at 7:00am at website3.com. I doubt the hanging has much to do with the exception since the requests would have been made a large number of times after that before the actual hang.
My first inclination is that you may need to dispose of your HttpWebResponse. Normally you might wrap that in a using block, but since you have two places where webresponse might be assigned, you might just want to dispose it explicitly, like this.
webresponse.Close();
webresponse.Dispose();
I would start there.
Just add below in the try block:
httpWReq.Timeout = 3000;
Related
I'm attempting to access a remote API and I'm getting a few exceptions during the HTTPWebResponse call. Below is my code:
//url
string responseValue = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("www.someapi.com")
request.Method = "GET";
request.UseDefaultCredentials = true;
request.ContentType = "application/json; charset=utf-8";
request.Headers("x-ms-client-id", "data");
try{
using (var response = (HttpWebRequest)req.GetResponse()){ <--- this line is the one that fails. System.IO.IOException here.
using (var stream = response.GetResponseStream()){
using(var sr = new StreamReader(stream)){
responseValue = sr.ReadToEnd();
}
}
}
} catch ///catch
The errors I'm getting are SocketExceptions and WebExceptions. I'm not sure why this specific call is failing. When I attempt the same URL and headers in Postman, the call returns a 200.
Any ideas would be appreciated.
EDIT:
Adding the error messages I'm getting. The exception being thrown when the response is attempted is
System.IO.IOException: "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
Usually, I often use HttpWebRequest like below code.
You can download the HttpHelper I compiled and call it according to my reference example, or you can add Http Header as required.
How to invoke HttpHelper, ex: Get Method
Console app to use azure storage tableapi
String PostParam = String.Empty;
if (Data != null)
{
PostParam = Data.ToString();//Newtonsoft.Json.JsonConvert.SerializeObject(Data);
}
byte[] postData = Encoding.UTF8.GetBytes(PostParam);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url + (Id == null ? "" : '/' + Id.ToString())));
request.Method = Method;
request.ServicePoint.Expect100Continue = false;
request.Timeout = HttpRequestTimeOut;
request.ContentType = "application/json";
request.ContentLength = postData.Length;
if (postData.Length > 0)
{
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(postData, 0, postData.Length);
}
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Response.Code = response.StatusCode;
using (StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
Response.Data = stream.ReadToEnd();
}
}
Here is my web request code block,
scroll down to the bottom of it to the catch exception
try
{
var webRequest = System.Net.WebRequest.Create (WEBSERVICE_URL);
if (webRequest != null) {
webRequest.Method = "POST";
//webRequest.Timeout = 12000;
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Headers.Add ("Key", _apiKey);
webRequest.Headers.Add ("Sign", genHMAC ());
byte[] dataStream = Encoding.UTF8.GetBytes("command=returnBalances&nonce=" + nonce);
webRequest.ContentLength = dataStream.Length;
Stream newStream = webRequest.GetRequestStream();
newStream.Write(dataStream, 0, dataStream.Length);
newStream.Close();
using (System.IO.Stream s = webRequest.GetResponse ().GetResponseStream ()) {
using (System.IO.StreamReader sr = new System.IO.StreamReader (s)) {
var jsonResponse = sr.ReadToEnd ();
OutputText.text = jsonResponse.ToString ();
}
}
}
}
catch (Exception ex)
{
OutputText.text = ex.ToString ();
}
This gives me an "error(403) Forbidden" and the exception stack trace, but I am trying to get the 403 Response Body:
I cannot get Unity C# to accept the following code: mentioned here
catch(WebException ex)
{
var response = (HttpWebResponse)ex.Response;
}
What do I need to make this method work? I need the Response body
hmac.ToString() will not generate valid sign. To generate valid sign for Poloniex, you must use HMACSHA512.ComputeHash method and pass it dataStream as an argument. Bytes returned from this method then must be converted to hexadecimal string.
This should generate valid sign:
var hmac = new HMACSHA512(APISecret_Bytes);
var signBytes = hmac.ComputeHash(dataStream);
var sign = String.Join("", signBytes.Select(b => b.ToString("X2")));
Regarding WebException, it is declared in System.Net namespace, so make sure you have using System.Net;. Depending on target framework, WebException shoul be in System.Net.Requests.dll, System.dll, or netstandard.dll. Unfortunatelly I don't have any experience with Unity, but if my guess that it targets ordinary .NET Framework is correct, then WebException is declared in System.dll and your project should already have reference to it and no additional assembly reference should be needed.
I'm using WinForms and accessing my Restful webservice. For some reason the code after a while breaks, by giving the timeout error while connecting to the server.
The problem might also be due to my code design.
Here's my Restful client class
public class Restful
{
public string auth = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("MyUserName:MyPassword"));
public string POST(string parameters)
{
var request = (HttpWebRequest)WebRequest.Create("http://myserverdomain.com/api/webservice/someMethod");
byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
request.Method = WebRequestMethods.Http.Post;
request.Headers["Authorization"] = this.auth;
request.ContentLength = byteArray.Length;
request.ContentType = "application/x-www-form-urlencoded";
Stream postStream = null;
try
{
// ERROR IS IN THIS LINE
postStream = request.GetRequestStream();
}
catch (WebException ex)
{
// I'm kind of creating an hack here..which isn't good..
if (ex.Status.ToString() == "ConnectFailure")
{
System.Threading.Thread.Sleep(1000);
this.POST(parameters);
}
}
if (postStream == null)
return string.Empty;
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
return responseValue;
using (var responseStream = response.GetResponseStream())
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
responseValue = reader.ReadToEnd();
return responseValue;
}
}
}
I'm receiving the error (after a few successfully send items):
Unable to connect to remote server
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond MyServerIpAddress
Sometimes I send thousands of items to the server, sometimes I only send 2 or 4. So I call this POST function within a loop.
try
{
foreach (app.views.Documents doc in DocumentsView)
{
var parameters = "key=" + doc.key;
parameters += "¶m1=" + doc.param1 + "¶m2=" + doc.param2;
/*
* Validates the response of Restful service.
* The response is always in JSON format.
*/
if (response(Restful.POST(parameters)) == false)
{
MessageBox.Show("Error while sending the ID: " + doc.id.ToString());
break;
};
}
}
catch (Exception ex)
{
MessageBox.Show("Error while sending documents: " + ex.Message);
}
You can change the default timeout of your HttpWebRequest to be some thing larger than the default, for example:
request.Timeout = 120000;
I think the default is 100 seconds.
You can also check this adjusting-httpwebrequest-connection-timeout-in-c-sharp
taking the failure at face value, it says that the remote machine didnt respond. Most likely causes
wrong name or ip address
windows firewall is on on the remote machine
I am implementing REST service and I am getting the above error. I searched a lot and used different methods to resolve this error but no luck. The service is working fine when I am using Postman or fiddler.
Here is my code :
try
{
string content = string.Empty;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(new Uri("https://api.MYDOMAIN.com/servlet/Year"));
httpWebRequest.Method = "POST";
string parsedContent = "{\"securitykey\":\"KEY\"}";
var data = JObject.Parse(parsedContent);
Byte[] bytes = Encoding.UTF8.GetBytes(data.ToString());
httpWebRequest.ContentLength = bytes.Length;
httpWebRequest.ContentType = "application/json";
Stream newStream = httpWebRequest.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
var response = (HttpWebResponse)httpWebRequest.GetResponse();
var stream = response.GetResponseStream();
if (stream != null)
{
var sr = new StreamReader(stream);
content = sr.ReadToEnd();
}
}
catch (WebException ex)
{
throw;
}
So in the above code I tried with :
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
HttpUtility.UrlEncode()
I also tried the below code but it is giving me the same error :
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
result = client.UploadString("https://api.MYDOMAIN.com/servlet/Year", "POST", "{\"securitykey\":\"MYKEY\"}");
}
I added the security key in raw header as httpWebRequest.Headers.Add("{\"securitykey\":\"MYKEY\"}") but still no luck.
Really appreciate if I can get some help.
After a lot of RND I tried doing this in PHP, so it gave me an error as UserAgent is required. I added httpWebRequest.UserAgent and it worked. This error was never displayed in WebException.
We have a url and we need to check whether web page is active or not. We tried following code:
WebResponse objResponse = null;
WebRequest objRequest = HttpWebRequest.Create(URL);
objRequest.Method = "HEAD";
try
{
objResponse = objRequest.GetResponse();
objResponse.Close();
}
catch (Exception ex)
{
}
Above code gave exception if unable to get a response but also works fine even if we have a "server error" on that page? Any help how to get server error?
The HttpResponse class has a StatusCode property which you can check. If it's 200 everything is ok.
You can change your code to this:
HttpWebResponse objResponse = null;
var objRequest = HttpWebRequest.Create("http://google.com");
objResponse = (HttpWebResponse) objRequest.GetResponse();
if(objResponse.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine("It failed");
}else{
Console.WriteLine("It worked");
}
For one thing, use a using statement on the response - that way you'll dispose of it whatever happens.
Now, if a WebException is thrown, you can catch that and look at WebException.Response to find out the status code and any data sent back:
WebRequest request = WebRequest.Create(URL);
request.Method = "HEAD";
try
{
using (WebResponse response = request.GetResponse())
{
// Use data for success case
}
}
catch (WebException ex)
{
HttpWebResponse errorResponse = (HttpWebResponse) ex.Response;
HttpStatusCode status = errorResponse.StatusCode;
// etc
}