HttpWebResponse().GetResponse Timed out - c#

I'm trying to get my program to talk to an API using the HttpWebRequest/Response. The POST call works and generates an auth code.
The second call I'm making is a GET call and for some reason it times out every time. I've tried Request.Timeout, .readwritetimeout, content type, servicepoint and protocolVersion with no success.
This is my code:
public void InHouseReservations()
{
try
{
int Id = 0;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"{Properties.Settings.Default.RMSAPIIp}reservations/inHouse?modelType=basic&propertyId=1");
//request.Method = "GET";
request.ContentType = "application/json";
request.Headers.Add($"authtoken: {RMSAuthToken}");
request.Timeout = 200000;
request.ReadWriteTimeout = 200000;
request.ServicePoint.Expect100Continue = false;
request.ProtocolVersion = HttpVersion.Version11;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
using (var dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
}
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
dynamic tokenJSON = JObject.Parse(responseString);
ReservationID = tokenJSON.Id;
response.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

Related

308 permanent redirect with uploading PDF to REST API

I want to upload PDF to CrossEngage platform using HttpWebRequest or RestClient. As response I'm getting : 308 permanent redirect, but when i try this on POSTMAN all is fine (200 OK). What i'm not doing that POSTMAN is doing ?
//RestClient
byte[] dataBytes = System.IO.File.ReadAllBytes(path);
string converted = Convert.ToBase64String(dataBytes);
var client = new RestClient(Url+Action);
client.FollowRedirects = true;
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("x-xng-authtoken", AuthToken);
request.AddHeader("x-xng-apiversion", "2");
request.AddHeader("content-type", "application/pdf");
request.AddParameter("application/pdf", converted, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
return response.Content;
//HttpWebRequest
try
{
byte[] dataBytes = System.IO.File.ReadAllBytes(path);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + Action);
//request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.Headers.Add("X-XNG-ApiVersion", "2");
request.Headers.Add("X-XNG-AuthToken", AuthToken);
request.Method = method;
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 1;
request.UseDefaultCredentials = false;
request.PreAuthenticate = true;
request.ContentLength = 0;
request.CookieContainer = new CookieContainer();
if (1 == 1)
{
request.ContentLength = dataBytes.Length;
request.ContentType = contentType;
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();
}
}
catch (WebException webex)
{
string m = "";
using (HttpWebResponse response = (HttpWebResponse)webex.Response)
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
throw new Exception(reader.ReadToEnd());
}
}
I expect 200 OK status code
Thanks in advance
UPDATE: I have found a solution so it might help someone.
Simply you need to call location given in Location response header.
Hereby complete code :
try
{
byte[] dataBytes = System.IO.File.ReadAllBytes(path);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + Action);
//request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request.Headers.Add("X-XNG-ApiVersion", "2");
request.Headers.Add("X-XNG-AuthToken", AuthToken);
request.Method = method;
request.AllowAutoRedirect = false;
if (1 == 1)
{
request.ContentLength = dataBytes.Length;
request.ContentType = contentType;
using (Stream requestBody = request.GetRequestStream())
{
requestBody.Write(dataBytes, 0, dataBytes.Length);
}
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if ((int)response.StatusCode >= 300 && (int)response.StatusCode <= 399)
{
var uriString = response.Headers["Location"];
var apiClient = (HttpWebRequest)WebRequest.Create(uriString);
apiClient.ContentType = contentType;
apiClient.Method = method;
apiClient.AllowAutoRedirect = false;
apiClient.Accept = "*/*";
apiClient.Headers.Add("X-XNG-ApiVersion", "2");
apiClient.Headers.Add("X-XNG-AuthToken", AuthToken);
apiClient.ContentLength = dataBytes.Length;
using (Stream requestBody = apiClient.GetRequestStream())
{
requestBody.Write(dataBytes, 0, dataBytes.Length);
}
var r = apiClient.GetResponse();
}
response.Close();
}
return "";
}
catch (WebException webex)
{
string m = "";
using (HttpWebResponse response = (HttpWebResponse)webex.Response)
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
throw new Exception(reader.ReadToEnd());
}
}

Login into iCloud via Json Post request

I'm trying to log in into iCloud using a Json Post request in C#. Before trying to implement the code I was studying a little bit the iCloud requests using Chrome Console and using an Ad-on to replicate the requests in order to obtain the same result of the website.
First of All I checked the request directly from iCloud website:
And this is the response:
{
"serviceErrors" : [ {
"code" : "-20101",
"message" : "Il tuo IDĀ Apple o la password non sono corretti."
} ]
}
Using "Advance REST Client" ad Chrome plugin to replicate the request I ve tried the same Json request to the same Url. But I get Empty response:
I Also tried to copy and paste the whole Header (All the settings) and than send the request but the response is the same:
Anyone has an Advice?
UPDATE: I tried to implement A Json request through c# program:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://idmsa.apple.com/appleauth/auth/signin");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{accountName: \"briesanji #gmail.com\", password: \"testPassword\", rememberMe: false, trustTokens: []}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
The problem is that Execution breaks when the
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
is hit and it gives me this error: System.Net.WebException: 'Error Remote Server: (400) Request not valid.'
UPDATE: I solved in this way:
void POST(string url, string jsonContent)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(jsonContent);
request.ContentLength = byteArray.Length;
request.ContentType = #"application/json";
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
long length = 0;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
length = response.ContentLength;
}
}
catch (WebException ex)
{
// Log exception and throw as for GET example above
}
}
string GET(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try
{
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
catch (WebException ex)
{
WebResponse errorResponse = ex.Response;
using (Stream responseStream = errorResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// log errorText
}
throw;
}
}
Anyways I tested also the Answer and it was good to.. So I check it as valid thanks.
With this i dont get any error and the response content of the second request just tells me that there were too many failed logins for the test account...
private static void ICloud()
{
var cc = new CookieContainer();
var first = (HttpWebRequest)WebRequest.Create("https://idmsa.apple.com/appleauth/auth/signin?widgetKey=83545bf919730e51dbfba24e7e8a78d2&locale=de_DE&font=sf");
first.Method = "GET";
first.CookieContainer = cc;
var response1 = (HttpWebResponse)first.GetResponse();
using (var streamReader = new StreamReader(response1.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
var second = (HttpWebRequest)WebRequest.Create("https://idmsa.apple.com/appleauth/auth/signin");
second.ContentType = "application/json";
second.Method = "POST";
second.Accept = "application/json";
second.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
second.Referrer = "https://idmsa.apple.com/appleauth/auth/signin?widgetKey=83545bf919730e51dbfba24e7e8a78d2&locale=de_DE&font=sf";
second.Headers.Add("X-Requested-With", "XMLHttpRequest");
second.Headers.Add("X-Apple-Widget-Key", "83545bf919730e51dbfba24e7e8a78d2");
using (var streamWriter = new StreamWriter(second.GetRequestStream()))
{
string json = "{\"accountName\":\"test#icloud.com\",\"password\":\"test\",\"rememberMe\":false,\"trustTokens\":[]}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
try
{
var response2 = (HttpWebResponse)second.GetResponse();
using (var streamReader = new StreamReader(response2.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
catch(WebException we)
{
using (var r = new StreamReader(we.Response.GetResponseStream()))
{
var result2 = r.ReadToEnd();
}
}
}

Exception while trying to post data from PCL project

I am trying to post data from PCL project to remote server. Below is my code:
public async Task<bool> SendToken(string deviceToken, string userId)
{
HttpWebRequest request;
string url = "http://192.168.1.171:91/api/updatePushDeviceToken";
request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "application/json";
request.Method = "POST";
string postData = string.Format("userId={0};token={1}&deviceType={2}", userId, deviceToken, deviceType);
var data = Encoding.UTF8.GetBytes(postData);
try
{
request.BeginGetResponse(new AsyncCallback(FinishRequest), request);
}
catch (Exception e)
{
string m = e.Message;
}
return false;
}
private void FinishRequest(IAsyncResult result)
{
HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream);
var responseString = readStream.ReadToEnd();
}
While running above code, below exception was thrown:
System.Net.WebException: The remote server returned an error: (411)
Length Required.
PCL doesn't contain ContentLength property, hence I added Length as below but now I am getting exception as:
try
{
request.Headers[HttpRequestHeader.ContentLength] = "0";
}
catch (Exception e)
{
}
System.ArgumentException: This header must be modified with the
appropiate property. at
System.Net.WebHeaderCollection.CheckRestrictedHeader (System.String
headerName)
Your request is missing of ContentLength property of your post parameters.
var parameters = Encoding.ASCII.GetBytes(qstring);
var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.AllowAutoRedirect = false;
request.ContentType="application/x-www-form-urlencoded";
request.Method = "POST";
request.ContentLength = parameters.Length;
//Send it
var reqStream = request.GetRequestStream();
reqStream.Write(parameters, 0, parameters.Length);
reqStream.Close();
//read it
var response = (HttpWebResponse)request.GetResponse();
var sr = new StreamReader(response.GetResponseStream());
string responseHtml = sr.ReadToEnd().Trim();
And please use querystring format to post data, for example : "userId={0}&token={1}&..."

C# Anyways Of Making POST Request Faster?

So I have a program which has to make a POST request. The request takes way too long! The code for this is:
string entity = "some text in here";
byte[] _entity = Encoding.UTF8.GetBytes(entity);
Stopwatch sw = new Stopwatch();
sw.Start();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentLength = _entity.Length;
request.UserAgent = UserAgent;
request.ContentType = "application/json";
request.Accept = "application/json";
request.Headers["CustomHeader"] = "value";
request.Headers["AnotherCustom"] = "valueAgain";
request.Headers["AnotherHeader"] = "value";
request.Headers["AnotherOne"] = "value";
request.Referer = "referer";
using (Stream stream = request.GetRequestStream())
{
stream.Write(_entity, 0, _entity.Length);
}
WebResponse response = request.GetResponse();
string responseString = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
responseString = reader.ReadToEnd();
}
sw.Stop();
Console.WriteLine("took: " + sw.ElapsedMilliseconds);
When my program loads, I set these:
ServicePointManager.DefaultConnectionLimit = 1000;
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.Expect100Continue = false;
WebRequest.DefaultWebProxy = null;
What other things can I do to increase the speed? The ping to the site that I am POSTing too is only 5ms, and I have a 10mb/s upload speed, yet the request takes around 400ms every time.
Would sending less headers work?

Code analysis complains that object can be disposed more than once. Why?

I get warning on responseStream in following function:
private static string GetResponseString(WebResponse response)
{
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (var responseReader = new StreamReader(responseStream))
{
var strResponse = responseReader.ReadToEnd();
return strResponse;
}
}
}
return string.Empty;
}
I call this function from places like like this one:
var request = (HttpWebRequest)WebRequest.Create(Uri);
request.Headers.Add("Authorization", "GoogleLogin auth=" + this.SecurityToken);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Timeout = 5000;
// build the post string
var postString = new StringBuilder();
postString.AppendFormat("registration_id={0}", recipientId);
postString.AppendFormat("&data.payload={0}", message);
postString.AppendFormat("&collapse_key={0}", collapseKey);
// write the post-string as a byte array
var requestData = Encoding.ASCII.GetBytes(postString.ToString());
request.ContentLength = requestData.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(requestData, 0, requestData.Length);
requestStream.Close();
// Do the actual request and read the response stream
try
{
var response = request.GetResponse();
var responseString = GetResponseString(response);
response.Close();
return responseString.Contains("id=")
? SendStatus.Ok
: GetSendStatusFromResponse(responseString);
}
catch (WebException ex)
{
var webResponse = (HttpWebResponse)ex.Response;
if (webResponse != null)
{
if (webResponse.StatusCode.Equals(HttpStatusCode.Unauthorized))
{
return SendStatus.Unauthorized;
}
if (webResponse.StatusCode.Equals(HttpStatusCode.ServiceUnavailable))
{
return SendStatus.ServiceUnavailable;
}
}
this.LoggerService.Log(null, ex);
return SendStatus.GeneralException;
}
StreamReader takes ownership of the stream passed to it in the constructor call in the sense that it will call Dispose on it when the StreamReader itself is closed - hence it will already be disposed when the outer Using statement attempts to dispose of it.

Categories