public override void ChannelRead(IChannelHandlerContext ctx, object msg)
        {
            var req = (IFullHttpRequest)msg;

            if (this.IsNotWebSocketPath(req))
            {
                ctx.FireChannelRead(msg);
                return;
            }

            try
            {
                if (!Equals(req.Method, Get))
                {
                    SendHttpResponse(ctx, req, new DefaultFullHttpResponse(Http11, Forbidden));
                    return;
                }

                var wsFactory = new WebSocketServerHandshakerFactory(
                    GetWebSocketLocation(ctx.Channel.Pipeline, req, this.websocketPath), this.subprotocols,
                    this.allowExtensions, this.maxFramePayloadSize, this.allowMaskMismatch);
                WebSocketServerHandshaker handshaker = wsFactory.NewHandshaker(req);
                if (handshaker == null)
                {
                    WebSocketServerHandshakerFactory.SendUnsupportedVersionResponse(ctx.Channel);
                }
                else
                {
                    Task task = handshaker.HandshakeAsync(ctx.Channel, req);
                    task.ContinueWith(t =>
                    {
                        if (t.Status != TaskStatus.RanToCompletion)
                        {
                            ctx.FireExceptionCaught(t.Exception);
                        }
                        else
                        {
                            ctx.FireUserEventTriggered(new WebSocketServerProtocolHandler.HandshakeComplete(
                                                           req.Uri, req.Headers, handshaker.SelectedSubprotocol));
                        }
                    },
                                      TaskContinuationOptions.ExecuteSynchronously);

                    WebSocketServerProtocolHandler.SetHandshaker(ctx.Channel, handshaker);
                    ctx.Channel.Pipeline.Replace(this, "WS403Responder",
                                                 WebSocketServerProtocolHandler.ForbiddenHttpRequestResponder());
                }
            }
            finally
            {
                req.Release();
            }
        }
Example #2
0
        public override void ChannelRead(IChannelHandlerContext ctx, object msg)
        {
            var req = (IFullHttpRequest)msg;

            if (IsNotWebSocketPath(req))
            {
                _ = ctx.FireChannelRead(msg);
                return;
            }

            try
            {
                if (!Equals(Get, req.Method))
                {
                    SendHttpResponse(ctx, req, new DefaultFullHttpResponse(Http11, Forbidden, ctx.Allocator.Buffer(0)));
                    return;
                }

                var wsFactory = new WebSocketServerHandshakerFactory(
                    GetWebSocketLocation(ctx.Pipeline, req, _serverConfig.WebsocketPath), _serverConfig.Subprotocols, _serverConfig.DecoderConfig);
                WebSocketServerHandshaker handshaker = wsFactory.NewHandshaker(req);
                if (handshaker is null)
                {
                    _ = WebSocketServerHandshakerFactory.SendUnsupportedVersionResponse(ctx.Channel);
                }
                else
                {
                    // Ensure we set the handshaker and replace this handler before we
                    // trigger the actual handshake. Otherwise we may receive websocket bytes in this handler
                    // before we had a chance to replace it.
                    //
                    // See https://github.com/netty/netty/issues/9471.
                    WebSocketServerProtocolHandler.SetHandshaker(ctx.Channel, handshaker);
                    _ = ctx.Pipeline.Remove(this);

                    Task task = handshaker.HandshakeAsync(ctx.Channel, req);
                    _ = task.ContinueWith(FireUserEventTriggeredAction, (ctx, req, handshaker, _handshakePromise), TaskContinuationOptions.ExecuteSynchronously);
                    ApplyHandshakeTimeout();
                }
            }
            finally
            {
                _ = req.Release();
            }
        }