2

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.

Nick Peppers
  • 3,161
  • 23
  • 27

0 Answers0