Search code examples
.net-corehttprequesthttp-status-code-504http-status-code-502

HTTP Request works in Postman and curl, but not in .NET Core code and throws 504 (Gateway Timeout) and 502 (Proxy Error) errors


I'm trying to call an API in my .NET Core web app project but it returns these errors as a response:

  1. 504 Gateway Timeout
  2. 502 Bad Gateway

Although, this API responds correctly using Postman and CURL.

I investigated all the headers of Postman and CURL in Fiddler and async them in my code, tried different HTTP Client Libraries like 'RestSharp' and 'HttpClient', even tested a simplified code in a raw .NET Core console application, ran the code on two different local machines.

public static async Task GetQuote()
{
    try
    {
        var content = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><job><job_action>QUOTE</job_action></job>";

        using (var handler = new HttpClientHandler())
        {
            handler.Proxy = null; // Explicitly set proxy to null
            handler.UseProxy = false; // Ensure proxy is disabled
            handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12; // Ensure correct SSL/TLS protocol

            using (var client = new HttpClient(handler))
            {
                client.Timeout = TimeSpan.FromMinutes(5); // Increase timeout duration
                // Additional Headers to match POSTMAN request
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
                client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
                client.DefaultRequestHeaders.Connection.Add("keep-alive");
                client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue
                {
                    NoCache = true
                };

                var form = new MultipartFormDataContent();
                var byteArray = Encoding.GetEncoding("ISO-8859-1").GetBytes(content);
                var byteContent = new ByteArrayContent(byteArray);
                byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

                form.Add(byteContent, "jobxml", "job_quote.xml");

                var response = await client.PostAsync("https://www.apiServer.com/online/getxmljob.cl", form);
                Console.WriteLine("Response Status Code: " + response.StatusCode);
                response.EnsureSuccessStatusCode();

                var responseBody = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Response Body: " + responseBody);
            }
        }
    }
    catch (HttpRequestException ex)
    {
        Console.WriteLine($"HttpRequestException: {ex.Message}");
        Console.WriteLine($"Status Code: {ex.StatusCode}");
    }
    catch (TaskCanceledException ex)
    {
        Console.WriteLine("TaskCanceledException: Request timed out.");
        Console.WriteLine($"Exception: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
    }
}

I did everything I knew but I'm still encountering a '504 Gateway Timeout' error.

Unfortunately, the API server isn't under my control and I can't check the server-side logs for more detailed error information.

Is there anything that I can check and I haven't done it yet?

Any Clues and thoughts can save me.


Solution

  • I changed my code to this and it works correctly without any errors:

    public static async Task GetQuote()
    {
        try
        {
            var content = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><job><job_action>QUOTE</job_action></job>";
            string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.apiServer.com/online/getxmljob.cl");
            request.Method = "POST";
            request.ContentType = "multipart/form-data; boundary=" + boundary;
    
            using (var requestStream = request.GetRequestStream())
            {
                var writer = new StreamWriter(requestStream);
                writer.WriteLine("--" + boundary);
                writer.WriteLine($"Content-Disposition: form-data; name=\"jobxml\"; filename=\"file.xml\"");
                writer.WriteLine("Content-Type: application/xml");
                writer.WriteLine();
                writer.WriteLine(content);
                writer.WriteLine("--" + boundary + "--");
                writer.Flush();
            }
    
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                Console.WriteLine("Response Status Code: " + response.StatusCode);
                using (var responseStream = new StreamReader(response.GetResponseStream()))
                {
                    string responseBody = responseStream.ReadToEnd();
                    Console.WriteLine("Response Body: " + responseBody);
                }
            }
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"HttpRequestException: {ex.Message}");
            Console.WriteLine($"Status Code: {ex.StatusCode}");
        }
        catch (TaskCanceledException ex)
        {
            Console.WriteLine("TaskCanceledException: Request timed out.");
            Console.WriteLine($"Exception: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex.Message}");
        }
    }