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

Websocket proxy failed "Error during WebSocket handshake" #72

Open
martindybal opened this issue Dec 5, 2020 · 5 comments
Open

Websocket proxy failed "Error during WebSocket handshake" #72

martindybal opened this issue Dec 5, 2020 · 5 comments

Comments

@martindybal
Copy link

I'm trying to proxy twilio comunnication. They have sample in doc how to do that with ngix

Sample configuration:

# Proxy requests to /signaling to https://global.vss.twilio.com/signaling
#
    location /signaling {
        proxy_pass https://global.vss.twilio.com/signaling;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }

# 
# Proxy requests for the SDK Gateway "/sdkgw" to 'http://sdkgw.us1.twilio.com
#   
    location /sdkgw {
        proxy_pass http://sdkgw.us1.twilio.com;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;

I'm tried to use AspNetCore.Proxy but I wasn't succeeded.

            app.UseProxies(proxies =>
            {
                proxies.Map("twilio/signaling", proxy => proxy.UseWs("https://global.vss.twilio.com/signaling"));
                proxies.Map("twilio/sdkgw", proxy => proxy.UseWs("http://sdkgw.us1.twilio.com"));
            });

failed: Error during WebSocket handshake: Unexpected response code: 502

            app.UseProxies(proxies =>
            {
                proxies.Map("twilio/signaling", proxy => proxy.UseWs("wss://global.vss.twilio.com/signaling"));
                proxies.Map("twilio/sdkgw", proxy => proxy.UseWs("wss://sdkgw.us1.twilio.com"));
            });

failed: Error during WebSocket handshake: Unexpected response code: 404

How should I setup AspNetCore.Proxy correctly?

@GrumpyBear57
Copy link

I think I'm having the same issue here, when I try to connect through the ASP proxy, I get a HTTP 502 on my websocket client. I've created very simple test server and clients in node.js to try and debug if it's something we're doing on that end that would interfere, but still can't get it to work. Any direction as to where to go from here would be greatly appreciated.

My server:

const WebSocket = require('ws');

const server = new WebSocket.Server({ port: 8000 });
server.on('connection', socket => {
  console.log(`socket connected`);

  socket.send('who');

  socket.on('message', msg => {
      console.log(`mesage: ${msg}`);
  });

  socket.on('close', () => {
      console.log(`socket closed`);
  });
});

Clients:

const WebSocket = require('ws');

const directSocket = new WebSocket('http://192.168.2.228:8000');
const proxiedSocket = new WebSocket('http://192.168.2.228:5000/kanatran/proxy');

directSocket.on('open', () => {
    console.log('direct socket connection opened');
});

directSocket.on('message', msg => {
    if (msg === 'who')
        directSocket.send('I am direct');
});

directSocket.on('error', console.log);

proxiedSocket.on('open', () => {
    console.log('proxied socket connection opened');  
});

proxiedSocket.on('message', msg => {
    if (msg === 'who')
        proxiedSocket.send('I am proxied');
});

proxiedSocket.on('error', console.log);

ASP Proxy route:

[Route("proxy")]
public Task Proxy() {
    _logger.LogInformation("Proxy request from {RemoteIP}, forwarding", HttpContext.Connection.RemoteIpAddress);
    return this.WsProxyAsync("http://192.168.2.228:8000");
}

Server output:

socket connected
mesage: I am direct

Client output:

direct socket connection opened
Error: Unexpected server response: 502
{stacktrace snipped}

ASP Proxy output:

info: API.Controllers.KanatranController[0]
      Proxy request from ::ffff:192.168.2.228, forwarding

@GrumpyBear57
Copy link

Alright I think I have this figured out now...

First step was to actually enable websockets on the ASP Proxy (add app.UseWebSockets() to startup.cs -- I think this needs to go before app.UseRouting() and/or app.UseEndpoints). This totally makes sense, but it isn't documented in the setup instructions for this package, so I had omitted it.

The next thing I found was that I MUST specify ws://url instead of http://url, both when connecting to the proxy, and when specifying where to proxy to. I'm not entirely sure why this is, since with my normal websocket connections I could use either ws or http protocols, but I digress.

My working client now looks like this:

const proxiedSocket = new WebSocket('ws://192.168.2.228:5000/kanatran/proxy');

And my ASP Proxy route looked like this:

[Route("proxy")]
public Task Proxy() {
    _logger.LogInformation("Proxy request from {RemoteIP}, forwarding", HttpContext.Connection.RemoteIpAddress);
    return this.WsProxyAsync("ws://192.168.2.228:8000");
}

However I now just map it directly in startup.cs, which means I give up logging, but I'm not particularly concerned about that since it was originally for trying to debug this issue anyways.

app.UseProxies(proxies => proxies.Map("kanatran/controller", proxy => proxy.UseWs("ws://localhost:8000")));

@twitchax
Copy link
Owner

Hi, sorry: just got to this.

So, good call out: I can add that to the README. The Microsoft Docs call this out, but I agree that people using this as a WS proxy likely don't look beyond this package.

As of now, the proxy uses the protocol to determine whether the connection is a websocket or not: there may be a better way to do this.

Is the non-Startup.cs handler not working?

@twitchax
Copy link
Owner

Leaving this open until I fix the docs.

@GrumpyBear57
Copy link

As of now, the proxy uses the protocol to determine whether the connection is a websocket or not: there may be a better way to do this.

When I was stepping through the decompiled code in the debugger, it looks like you're already doing a check to context.WebSockets.IsWebSocketRequest, which I think should probably be enough, but some further testing may be required for that to ensure proper compatibility.

Is the non-Startup.cs handler not working?

No it is working, I just don't need a full controller for the proxy endpoint, so I opted to do it in startup.cs instead of a dedicated controller class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants