Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpClient difference 3.1 vs 5.0. Getting: connection was aborted #52287

Closed
mikhail-tin opened this issue May 5, 2021 · 13 comments · Fixed by #55012
Closed

HttpClient difference 3.1 vs 5.0. Getting: connection was aborted #52287

mikhail-tin opened this issue May 5, 2021 · 13 comments · Fixed by #55012
Milestone

Comments

@mikhail-tin
Copy link

mikhail-tin commented May 5, 2021

Hi there,

I have found strange behavior when moved from 3.1 to 5.0.
The same request in the same environment produces a different result.

Runtime: 3.1 - OK
Runtime 5.0.4 - Exception:
An error occurred while sending the request. -> Unable to read data from the transport connection -> An established connection was aborted by the software in your host machine.

Code:
program.cs

namespace WebApplication
{
    public class Program
    {
        public static void Main(string[] args) =>
            Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(wb => { wb.UseStartup<Startup>(); }).Build().Run();
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services){}

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    try
                    {
                        var client = new HttpClient();
                        var resp = await client.GetAsync("https://demo.identityserver.io/.well-known/openid-configuration");
                        await context.Response.WriteAsync(Environment.Version.ToString() + ": " + resp.StatusCode);
                    }
                    catch (Exception ex)
                    {
                        await context.Response.WriteAsync(Environment.Version.ToString() + ": " + ex.Message);
                    }
                });
            });
        }
    }
}

WebApplication.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
	<!--<TargetFramework>netcoreapp3.1</TargetFramework>-->
  </PropertyGroup>
</Project>

What could be a reason of this behavior on the same machine(just flip TargetFramework)?
Also I have tried on another machine and both runtime works fine and no exception.

OS: Win 10

Thx!

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Net untriaged New issue has not been triaged by the area owner labels May 5, 2021
@ghost
Copy link

ghost commented May 5, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Hi there,

I have found strange behavior when moved from 3.1 to 5.0.
The same request in the same environment produces a different result.

Runtime: 3.1 - OK
Runtime 5.0.4 - Exception:
An error occurred while sending the request. -> Unable to read data from the transport connection -> An established connection was aborted by the software in your host machine.

Code:
program.cs

namespace WebApplication
{
    public class Program
    {
        public static void Main(string[] args) =>
            Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(wb => { wb.UseStartup<Startup>(); }).Build().Run();
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services){}

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    try
                    {
                        var client = new HttpClient();
                        var resp = await client.GetAsync("https://demo.identityserver.io/.well-known/openid-configuration");
                        await context.Response.WriteAsync(Environment.Version.ToString() + ": " + resp.StatusCode);
                    }
                    catch (Exception ex)
                    {
                        await context.Response.WriteAsync(Environment.Version.ToString() + ": " + ex.Message);
                    }
                });
            });
        }
    }
}

WebApplication.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
	<!--<TargetFramework>netcoreapp3.1</TargetFramework>-->
  </PropertyGroup>
</Project>

What could be a reason of this behavior on the same machine(just flip TargetFramework)?
Also I have tried on another machine and both runtime works fine and no exception.

Thx!

Author: mikhail-tin
Assignees: -
Labels:

area-System.Net, untriaged

Milestone: -

@wfurt
Copy link
Member

wfurt commented May 5, 2021

can you get packet captures with Wireshark? What is your OS?

@mikhail-tin
Copy link
Author

can you get packet captures with Wireshark? What is your OS?

No, I have no chance to download and install something.
OS Name: Windows, OS Version: 10.0.19041, RID: win10-x64

@antonfirsov
Copy link
Member

antonfirsov commented May 5, 2021

@mikhail-tin is this a consistent or an intermittent error? AFAIK the only socket-level change between 3.1 and 5.0 is our switch to dual-mode sockets. Can you check if this ConnectCallback override changes anything: #44686 (comment) (Edit: fixed incorrect link.)

@karelz
Copy link
Member

karelz commented May 5, 2021

@mikhail-tin the code above creates HttpClient per request -- that is not a healthy practice, that may easily lead to other problems. Are you able to reproduce the same problem from a console app? (demonstrating 3.1 works and 5.0 does not)
Same question as above -- is it 100% repro on first request, or is it intermittent?

@mikhail-tin
Copy link
Author

It is 100% repro on first request . With CreateWorkaroundClient() no exception, it helps.

public static HttpClient CreateWorkaroundClient()
        {
            SocketsHttpHandler handler = new SocketsHttpHandler { ConnectCallback = IPv4ConnectAsync };
            return new HttpClient(handler);

            static async ValueTask<Stream> IPv4ConnectAsync(SocketsHttpConnectionContext context, CancellationToken cancellationToken)
            {
                // By default, we create dual-mode sockets:
                // var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.NoDelay = true;

                try
                {
                    await socket.ConnectAsync(context.DnsEndPoint, cancellationToken).ConfigureAwait(false);
                    return new NetworkStream(socket, ownsSocket: true);
                }
                catch
                {
                    socket.Dispose();
                    throw;
                }
            }
        }

Thx

@karelz
Copy link
Member

karelz commented May 5, 2021

OK, looks like another +1 on DualSockets causing problems ... what is your environment? Is it enterprise setup with some specific firewall? (just out of curiosity)

@mikhail-tin
Copy link
Author

OK, looks like another +1 on DualSockets causing problems ... what is your environment? Is it enterprise setup with some specific firewall? (just out of curiosity)

No, I have faced it on my machine for development( with firewall, antivirus and proxy).
I assume we could close the issue as resolved. looks like the reason is firewall or something.

Thx a lot.

@antonfirsov
Copy link
Member

with firewall, antivirus and proxy

@mikhail-tin can you try disabling these one-by-one without the workaround code? That would be valuable info for us, I'd appreciate.

@mikhail-tin
Copy link
Author

with firewall, antivirus and proxy

@mikhail-tin can you try disabling these one-by-one without the workaround code? That would be valuable info for us, I'd appreciate.

I can't do that due corp policies. No ways..

@karelz
Copy link
Member

karelz commented May 5, 2021

@mikhail-tin can you please at least tell us which firewall is used? ... we can then close the issue.

@mikhail-tin
Copy link
Author

@karelz, Kaspersky Endpoint Security for Windows

@karelz
Copy link
Member

karelz commented May 5, 2021

Thanks!

Closing as resolved.

@karelz karelz closed this as completed May 5, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 19, 2021
alnikola pushed a commit that referenced this issue Jul 12, 2021
Fixes #47583. Resolves #52287, #54807 and similar issues, without changing customer application code.

Introduces an AppContext switch `System.Net.DisableIPv6` and environment variable `DOTNET_SYSTEM_NET_DISABLEIPV6` to emulate the lack of OS-level IPv6 support. This is useful to workaround dual-stack socket issues when the OS reports support of IPv6, but some other underlying infrastructure element (typically VPN) doesn't function well with IPv6 request.

For consistency, this switch also impacts NameResolution and Ping, not only Sockets.
@karelz karelz removed the untriaged New issue has not been triaged by the area owner label Oct 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants