twitchax / AspNetCore.Proxy

ASP.NET Core Proxies made easy.
MIT License
505 stars 80 forks source link

Websockets fail to connect #101

Open AntonC9018 opened 1 year ago

AntonC9018 commented 1 year ago

The plain HTTP requests work, however websockets fail to connect.

This is the error that I see in the browser console that attempts to establish the connection:

[vite] connecting... client.ts:19:8
GETwss://localhost:7186/vite-ws
[HTTP/1.1 502 Bad Gateway 51ms]

GET
    wss://localhost:7186/vite-ws
Status
502
Bad Gateway
VersionHTTP/1.1
Transferred309 B (0 B size)

Firefox can’t establish a connection to the server at wss://localhost:7186/vite-ws. client.ts:78:17

The relevant code:

if (isDevelopment)
{
    const string vitePort = "5173";

    app.UseProxies(proxies =>
    {
        proxies.Map("/vite-ws", proxy => proxy
            .UseWs($"wss://localhost:{vitePort}/vite-ws"));
        proxies.Map("/{**all}", proxy => proxy
            .UseHttp((_, args) => $"https://localhost:{vitePort}/{args["all"]}"));
    });
}

I'm not seeing a websocket request being sent to the endpoint in the server console, but I do see a multiple of these quite suspicious logs:

info: System.Net.Http.HttpClient.AspNetCore.Proxy.HttpProxyClient.ClientHandler[101]
      Received HTTP response headers after 4.6509ms - 304
info: System.Net.Http.HttpClient.AspNetCore.Proxy.HttpProxyClient.LogicalHandler[101]
      End processing HTTP request after 4.715ms - 304
warn: Microsoft.AspNetCore.Server.Kestrel[41]
      One or more of the following response headers have been removed because they are invalid for HTTP/2 and HTTP/3 responses: 'Connection', 'Transfer-Encoding', 'Keep-Alive', 'Upgrade' and 'Proxy-Connection'.

I don't know much about HTTP headers, but they might be related to this. Maybe I just need to enable some of these https://content-security-policy.com/

Also, the request used HTTP/1.1, but ASP.NET Core seems to be expecting HTTP/2 or /3, which may or may not matter.

I'm on .NET 6.

AntonC9018 commented 1 year ago

Request headers:

GET /vite-ws HTTP/1.1
Host: localhost:7186
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Sec-WebSocket-Version: 13
Origin: https://localhost:7186
Sec-WebSocket-Protocol: vite-hmr
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: CEV0xqrGS31u+3hwO+MK3w==
Connection: keep-alive, Upgrade
Sec-Fetch-Dest: websocket
Sec-Fetch-Mode: websocket
Sec-Fetch-Site: same-origin
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

Response headers:

HTTP/1.1 502 Bad Gateway
Date: Fri, 11 Nov 2022 20:22:54 GMT
Server: Kestrel
Transfer-Encoding: chunked
twitchax commented 1 year ago

Have you ensured that WebSockets are enabled with app.UseWebSockets()?

AntonC9018 commented 1 year ago

Have you ensured that WebSockets are enabled with app.UseWebSockets()?

Nope, I have not, but I'd expect the app to crash with an error and definitely not silently ignore that. I implore you to add a check for it.

AntonC9018 commented 1 year ago

Still though, the warnings about headers are still there, even after I've added UseWebSockets(). The websocket proxy started working, so you could move the header thing to another issue if you want.

AntonC9018 commented 1 year ago

Might be relevant https://github.com/dotnet/aspnetcore/pull/33502

twitchax commented 1 year ago

@AntonC9018, it's interesting. ASP.NET does not crash in this scenario either.

I think the philosophy is that the routing middleware is just that: it is routing middleware. If you have routing middleware that catches web socket requests, and no requests come in because it is not "turned on", then the middleware just doesn't do anything.

I would prefer to keep similar behavior with ASP.NET.

As for the the headers, those are kestrel warnings. I am guessing that your browser is sending those headers, and kestrel is informing you that they will be stripped for h2 requests.

AntonC9018 commented 1 year ago

@AntonC9018, it's interesting. ASP.NET does not crash in this scenario either.

I think the philosophy is that the routing middleware is just that: it is routing middleware. If you have routing middleware that catches web socket requests, and no requests come in because it is not "turned on", then the middleware just doesn't do anything.

I would prefer to keep similar behavior with ASP.NET.

As for the the headers, those are kestrel warnings. I am guessing that your browser is sending those headers, and kestrel is informing you that they will be stripped for h2 requests.

As much as I don't agree with that philosophy, fair enough.

As for the headers, yes, I'm aware of that now, check out the issue I had linked.

AntonC9018 commented 1 year ago

@twitchax Do you plan on fixing the unfiltered header warnings?