I randomly get a timeout exception when making a request to the server. I've been trying httpwebrequest, restsharp and httpclient. I can't use HttpClient
because I need to add custom certificates and they're not implemented.
This is what I've found out so far:
-requests work fine in a console app
-requests work fine in an http url
-requests don’t work on https with client certificate (.pfx) with X-CSRF-Token and X-FORMS_BASED_AUTH_ACCEPTED (it seems to work fine with NTLM)
-requests seem to work fine when using only NTLM authentication on every call (not cookies)
Initialize RestClient:
Setup.RestClient = new RestClient(App.EnvironmentServerUrl);
Setup.RestClient.ClientCertificates = new X509CertificateCollection() { Setup.Certificate };
Setup.RestClient.CookieContainer = new CookieContainer();
if (!String.IsNullOrEmpty(App.Cookie.Value))
Setup.RestClient.CookieContainer.Add(new Uri(App.EnvironmentServerUrl), App.Cookie);
Setup.RestClient.AddHandler("application/json", NewtonsoftJsonSerializer.Default);
Setup.RestClient.AddHandler("text/json", NewtonsoftJsonSerializer.Default);
Setup.RestClient.AddHandler("text/x-json", NewtonsoftJsonSerializer.Default);
Setup.RestClient.AddHandler("text/javascript", NewtonsoftJsonSerializer.Default);
Setup.RestClient.AddHandler("*+json", NewtonsoftJsonSerializer.Default);
Making the calls:
var request = new RestRequest(url, Method.POST);
request.OnBeforeDeserialization = resp =>
{
string byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (resp.Content != null && resp.Content.Length > 0 && resp.Content.StartsWith(byteOrderMarkUtf8))
resp.Content = resp.Content.Remove(0, byteOrderMarkUtf8.Length);
};
request.AddHeader("Accept", "application/json");
request.Parameters.Clear();
request.AddParameter("application/json", this.SerializeToJson(parameters), ParameterType.RequestBody);
request.JsonSerializer = NewtonsoftJsonSerializer.Default;
request.AddHeader("X-CSRF-Token", "Fetch");
request.AddHeader("X-FORMS_BASED_AUTH_ACCEPTED", "f");
if (App.Cookie == null || String.IsNullOrEmpty(App.Cookie.Value))
{
CredentialCache credentials = new CredentialCache();
credentials.Add(new Uri(App.EnvironmentServerUrl), "NTLM", new NetworkCredential(App.Credentials.UserName, App.Credentials.Password));
request.Credentials = credentials;
}
return await this.ExecuteAsync<T>(request);
public Task<T> ExecuteAsync<T>(RestRequest request) where T : new()
{
var taskCompletionSource = new TaskCompletionSource<T>();
Setup.RestClient.ExecuteAsync<T>(request, (response) => {
if (App.Cookie == null || String.IsNullOrEmpty(App.Cookie.Value))
{
App.Cookie = Setup.RestClient.CookieContainer.GetCookies(Setup.RestClient.BaseUrl)["FedAuth"];
}
if (!this.IsSuccessStatusCode(response.StatusCode))
{
taskCompletionSource.SetException(response.ErrorException);
}
else
{
taskCompletionSource.SetResult(response.Data);
}
});
return taskCompletionSource.Task;
Note: I've managed to implement my own AndroidClientHandler in order to use client certificates, but I'm getting an NTLM authentication error.