7

I'm trying to connect https endpoints from docker container. I have created the project using latest .net core web api 3.1 When I'm consuming https endpoint from container i'm randomly keep getting exception as

Exception: System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.
 ---> System.Net.Sockets.SocketException (104): Connection reset by peer
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
   at System.Net.FixedSizeReader.ReadPacketAsync(Stream transport, AsyncProtocolRequest request)
   at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)
   at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)

However when i test the same using debug mode in my visual studio i get the response from all of the https endpoints but the same in docker is breaking randomly with above exception.

Here is my docker file

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src/myapp
COPY . .
RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "myapp.dll"]

Here is my docker run command

docker run -d -p 443:443 -e ASPNETCORE_URLS="https://+443;http://+80" -e ASPNETCORE_HTTPS_PORT=443 -e ASPNETCORE_Kestrel__Certificates__Default__Password=****** -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/mycert.pfx -v ${HOME}/.aspnet/https:/https/ --link=myappredis --name myappapi myapp-v1

I have tried both the methods i.e using HTTPWebRequest or using HTTPClient but I'm getting the same above exception in containerized app.

Here is my source code for HTTP Wrapper

public class HTTPResponse
    {
        public static async Task<(string, bool)> GetHTTPResponse(HTTPRequestParams request)
        {
            HttpWebResponse httpResponse = null;
            HttpWebRequest httpWebRequest = null;
            string apiResponse = "";
            try
            {
                httpWebRequest = (HttpWebRequest)WebRequest.Create(request.url);
                httpWebRequest.Method = request.method.ToString();
                httpWebRequest.Timeout = request.serviceTimeout * 1000;
                //httpWebRequest.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
                httpResponse = (HttpWebResponse)(await httpWebRequest.GetResponseAsync());

                if (request.GZIP)
                {
                    using (var decompress = new GZipStream(httpResponse.GetResponseStream(), CompressionMode.Decompress))
                    using (var streamReader = new StreamReader(decompress))
                    {
                        apiResponse = await streamReader.ReadToEndAsync();
                    }
                }
                else
                {
                    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                    {
                        apiResponse = await streamReader.ReadToEndAsync();
                    }
                }
                return (apiResponse, true);
            }
            catch (WebException ex)
            {
                Console.WriteLine($"URL: {request.url}| Exception: {ex.ToString()}");
                return ("", false);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"URL: {request.url}| Exception: {ex.ToString()}");
                return ("", false);
            }
            finally
            {
                if (httpResponse != null)
                {
                    httpResponse.Close();
                }
            }
        }

        public static async Task<(string, bool)> GetHTTPResponse1(HTTPRequestParams request)
        {
            try
            {
                string apiResponse = "";
                var client = new HttpClient();
                var response = await client.GetAsync(request.url);
                response.EnsureSuccessStatusCode();
                apiResponse = await response.Content.ReadAsStringAsync();
                return (apiResponse, true);
            }
            catch (WebException ex)
            {
                Console.WriteLine($"URL: {request.url}| Exception: {ex.ToString()}");
                return ("", false);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"URL: {request.url}| Exception: {ex.ToString()}");
                return ("", false);
            }
        }
        public static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification,

            System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }

I don't know what am i missing here. I have tried bypassing httpWebRequest.ServerCertificateValidationCallback but still no lock.

suresh rajput
  • 169
  • 2
  • 9
  • You are using a HTTPS (secure) which is using port 443 which uses either TLS or SSL. Your exception indicates it is failing the TCP encryption. Http default header in c# are different than other methods. You have to set the correct headers in the request to work. So I would use a sniffer like wireshark or fiddler and compare the working docker connection with the failing c#. Then make the headers in c# look exactly like the docker headers. Compare the 1st request in each connection. – jdweng Dec 31 '19 at 10:52
  • @jdweng Then how the same is working in my local ? Sometimes i get the response from HTTPS endpoints and sometimes the fail with SSL exception. – suresh rajput Dec 31 '19 at 10:55
  • There are a few reasons. There may be a cookie so once a connection is established using docker than the c# will work because it is using the same cookie. Normally I recommend for debugging delete cookies between attempts. Also you can fail if the timeout is too small and you will get intermittent results. – jdweng Dec 31 '19 at 11:03
  • @jdweng So as per your comment there is problem with request headers for different http endpoints? – suresh rajput Dec 31 '19 at 11:05
  • Headers are really a negotiation between the client and server to get a common transfer mode. So suppose the server is French and you client defaults to english? Different Server may use different browser (content type) or the server could be using different encryption modes like 32 bit mode or 64 bit mode. See : https://en.wikipedia.org/wiki/Transport_Layer_Security – jdweng Dec 31 '19 at 11:14
  • @jdweng I have tried sending proper request headers still getting the same error randomly. – suresh rajput Dec 31 '19 at 11:57
  • How often are you failing? There a number of reason for random failures 1) A Timeout being too small 2) A server being busy 3) Hardware 4) Encryption option being wrong (like fill mode in TTL/SSL encryption) – jdweng Dec 31 '19 at 13:58
  • @sureshrajput did you find any solution yet? I have exactly the same problem... – DmitriBodiu Dec 01 '21 at 09:34
  • 1
    @DmitriBodiu i remember it was a hosting issue. Earlier my website was hosted in INDIA and when i switched to Singapore there were no errors. The reason of error was basically third party site was blocking traffic coming for some countries. – suresh rajput Dec 08 '21 at 14:09

0 Answers0