unosquare / embedio

A tiny, cross-platform, module based web server for .NET
http://unosquare.github.io/embedio
Other
1.45k stars 175 forks source link

Socket connetion gives Status Code 500 #559

Closed christian-photo closed 2 years ago

christian-photo commented 2 years ago

Describe the bug When I try to connect to my socket, I get a "500 - Internal Server Error"

500 - Internal Server Error

The server has encountered an error and was not able to process your request.

Please contact the server administrator, informing them of the time this error occurred and the action(s) you performed that resulted in this error.

The following information may help them in finding out what happened and restoring full functionality.

Exception type: EmbedIO.WebSockets.WebSocketException

Message: Includes no Sec-WebSocket-Key header, or it has an invalid value.

The message says, that the header doesn't include a Sec-WebSocket-Key. My question is if I can "turn that off" by either configuring the websocket or disabling this Sec-WebSocket-Key check.

To Reproduce Not sure if it reproducable, but this is my WebServer:

            ActiveServer = new WebServer(o => o
               .WithUrlPrefix($"http://*:{Port}")
               .WithMode(HttpListenerMode.EmbedIO)
               );

            ActiveServer.WithWebApi($"/api", m => m.WithController<Controller>());
            ActiveServer.WithModule(new WebSocket("/socket"));

this is my websocket:

    public class WebSocket : WebSocketModule
    {
        public WebSocket(string urlPath) : base(urlPath, true)
        {
            AdvancedAPI.Controls.Camera.GetInfo().PropertyChanged += CameraChanged;
            AdvancedAPI.Controls.Telescope.GetInfo().PropertyChanged += TelescopeChanged;
            AdvancedAPI.Controls.Focuser.GetInfo().PropertyChanged += FocuserChanged;
            AdvancedAPI.Controls.Rotator.GetInfo().PropertyChanged += RotatorChanged;
            AdvancedAPI.Controls.Dome.GetInfo().PropertyChanged += DomeChanged;
            AdvancedAPI.Controls.FilterWheel.GetInfo().PropertyChanged += FWChanged;
            AdvancedAPI.Controls.Switch.GetInfo().PropertyChanged += SwitchChanged;
            AdvancedAPI.Controls.SafetyMonitor.GetInfo().PropertyChanged += SafetyChanged;
            AdvancedAPI.Controls.Guider.GetInfo().PropertyChanged += GuiderChanged;
            AdvancedAPI.Controls.FlatDevice.GetInfo().PropertyChanged += FlatChanged;

            AdvancedAPI.Server.LogProcessor.NINALogEventSaved += LogProcessor_NINALogEventSaved;
        }

        private void LogProcessor_NINALogEventSaved(object sender, NINALogEvent e) => Send(new HttpResponse() { Response = e.type, Type = HttpResponse.TypeSocket });

        // Some Methods here, deleted to save space

        protected override Task OnMessageReceivedAsync(IWebSocketContext context, byte[] rxBuffer, IWebSocketReceiveResult rxResult)
        {
            Encoding.GetString(rxBuffer); // Do something with it
            return Task.CompletedTask;
        }

        public Task Send(string payload)
        {
            return BroadcastAsync(payload);
        }

        public Task Send(HttpResponse payload)
        {
            return BroadcastAsync(JsonConvert.SerializeObject(payload));
        }
    }

Expected behavior I expect the browser to successfully connect to the socket and the socket to be sending messages

Desktop:

rdeago commented 2 years ago

Hello, @rennmaus-coder, thanks for using EmbedIO!

The presence of the Sec-WebSocket-Key request header is mandated by RFC6455, that defines the WebSocket protocol. The value of this header is used by the server in the Sec-WebSocket-Accept response header, so no, there is simply no way to establish a WebSocket connection without it.

If the client sending the request is a web browser, it is probably sending a normal GET request instead of a WebSocket request. There are different APIs involved on the Javascript side, i.e. you cannot establish a WebSocket request using XMLHttpRequest or fetch(): you have to use a WebSocket object instead. If you are using a client-side Javascript library, please check the library's documentation to see whether the classes / methods you use are expected to successfully establish a WebSocket connection; if so, you will probably have to file an issue with the library.