0

My code works well and gets response on my local system, but when I deploy on to the server, the error is 'The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing'. Here is my code.

[HttpPost("GetJsoncode")]
public async Task<IActionResult> CallAPI([FromBody] JsonObject jsonBody, [FromQuery] string? validFrom, [FromQuery] string? validTo)
{
    string CertificateKey = "certKey";
    string SubscriptionKey = "123443434";
   
    string CertPath = _configuration["CertPath"]!;

    try
    {
        var handler = new HttpClientHandler();
        handler.ClientCertificates.Add(new X509Certificate2(CertPath, CertificateKey));
        handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;

        using (var client = new HttpClient(handler))
        {
            client.BaseAddress = new Uri("https://stage2.api.abc.com");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("Subscription-Key", SubscriptionKey);
            var cts = new CancellationTokenSource();
            cts.CancelAfter(TimeSpan.FromSeconds(20));
            client.Timeout = TimeSpan.FromSeconds(30);

            try
            {
                      HttpResponseMessage response = await client.PostAsJsonAsync(@"api/regions/abc/code?validfrom=" + validFrom + "&validTo=" + validTo, jsonBody,cts.Token).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();
                var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                
                return Ok(responseContent);
            }
            catch (Exception ex)
            {
                return StatusCode(400, ex.Message);
            }

        }
    }
    catch(Exception)
    {
        return StatusCode(500, "Certificate Error");
    }   
}

I have tried with long timeout, still no response. Anyone have this issue when deploying to a server with security. All other API's in the same controller are working fine on the server. And from the server I can use postman and able to get response from the target url.

Sajan Alex
  • 27
  • 3
  • If you catch an Exception, why would you assume it's a certificate error? This doesn't make sense. Anyways - how long do you expect the request to take that the HttpClient is making? – mason Mar 24 '23 at 12:52
  • Why did you use .ConfigureAwait(false)? – mason Mar 24 '23 at 12:52
  • 1
    Read the [remarks section on HttpClient](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-8.0#instancing): _"HttpClient is intended to be instantiated once and reused throughout the life of an application. [...] If you instantiate an HttpClient class for every request, the number of sockets available under heavy loads will be exhausted."_ – Fildor Mar 24 '23 at 14:03
  • Hi Mason, I have added ConfigureAwait(false) to confirm deadlock avoided. I have tried it without that as well. It is not a certificate error, It is not working on staging server. – Sajan Alex Mar 24 '23 at 14:59
  • Are you sure you are able to connect to that URL, for example from a web browser, from that server? Side note: the response needs a `using`, although for performance you may want to just pass it all the way through as a stream, instead of using JSON. – Charlieface Mar 24 '23 at 15:41
  • I have tried all available suggestions, but it is not working on company servers. Working without issue on local system and local IIS server – Sajan Alex Apr 28 '23 at 11:08
  • mason was referring to the last `catch` clause, where you return the message "Certificate Error" regardless of what kind of exception was thrown. The inner catch is similarly problematic, assuming that any error thrown by your outbound http request represents a 400 (Bad Request). And Fildor is right that you're using HttpClient wrong, which could lead to serious performance problems if you have much traffic. – StriplingWarrior May 17 '23 at 16:51

1 Answers1

0

I have resolved the issue with just one setting in the Application pool. Changed LoadUserProfile to true. Resolved the issue. This answer also worked out for me to avoid change setting on Application Pool. X509Certificate Constructor Exception

Sajan Alex
  • 27
  • 3
  • Why does that solve your problem? – StriplingWarrior May 17 '23 at 16:46
  • It was trying to access the user certificate store. So the LoadUserProfile to true solved the issue. But when I added X509KeyStorageFlags.MachineKeySet, it is working even with false, because I have installed the certificate on the local machine. – Sajan Alex May 18 '23 at 21:20