Exemple #1
0
        public void Decode100ContinueHttp2HeadersAsFullHttpResponse()
        {
            EmbeddedChannel ch      = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(false));
            IHttp2Headers   headers = new DefaultHttp2Headers();

            headers.Scheme = HttpScheme.Http.Name;
            headers.Status = HttpResponseStatus.Continue.CodeAsText;

            Assert.True(ch.WriteInbound(new DefaultHttp2HeadersFrame(headers, false)));

            IFullHttpResponse response = ch.ReadInbound <IFullHttpResponse>();

            try
            {
                Assert.Equal(HttpResponseStatus.Continue, response.Status);
                Assert.Equal(HttpVersion.Http11, response.ProtocolVersion);
            }
            finally
            {
                response.Release();
            }

            Assert.Null(ch.ReadInbound <object>());
            Assert.False(ch.Finish());
        }
Exemple #2
0
        public void SubsequentHttpRequestsAfterUpgradeShouldReturn403()
        {
            EmbeddedChannel ch = this.CreateChannel();

            WriteUpgradeRequest(ch);

            IFullHttpResponse response = this.responses.Dequeue();

            Assert.Equal(SwitchingProtocols, response.Status);
            response.Release();

            ch.WriteInbound(new DefaultFullHttpRequest(Http11, HttpMethod.Get, "/test"));
            response = this.responses.Dequeue();
            Assert.Equal(Forbidden, response.Status);
            response.Release();
        }
        public void TestDuplicateHandshakeResponseHeaders()
        {
            WebSocketServerHandshaker serverHandshaker = NewHandshaker("ws://example.com/chat",
                                                                       "chat", WebSocketDecoderConfig.Default);
            IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/chat");

            request.Headers
            .Set(HttpHeaderNames.Host, "example.com")
            .Set(HttpHeaderNames.Origin, "example.com")
            .Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket)
            .Set(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade)
            .Set(HttpHeaderNames.SecWebsocketKey, "dGhlIHNhbXBsZSBub25jZQ==")
            .Set(HttpHeaderNames.SecWebsocketOrigin, "http://example.com")
            .Set(HttpHeaderNames.SecWebsocketProtocol, "chat, superchat")
            .Set(HttpHeaderNames.SecWebsocketVersion, WebSocketVersion().ToHttpHeaderValue());
            HttpHeaders customResponseHeaders = new DefaultHttpHeaders();

            // set duplicate required headers and one custom
            customResponseHeaders
            .Set(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade)
            .Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket)
            .Set(AsciiString.Of("custom"), AsciiString.Of("header"));

            if (WebSocketVersion() != Http.WebSockets.WebSocketVersion.V00)
            {
                customResponseHeaders.Set(HttpHeaderNames.SecWebsocketAccept, "12345");
            }

            IFullHttpResponse response = null;

            try
            {
                response = serverHandshaker.NewHandshakeResponse(request, customResponseHeaders);
                HttpHeaders responseHeaders = response.Headers;

                Assert.Equal(1, responseHeaders.GetAll(HttpHeaderNames.Connection).Count);
                Assert.Equal(1, responseHeaders.GetAll(HttpHeaderNames.Upgrade).Count);
                Assert.True(responseHeaders.ContainsValue(AsciiString.Of("custom"), AsciiString.Of("header"), true));
                if (WebSocketVersion() != Http.WebSockets.WebSocketVersion.V00)
                {
                    Assert.False(responseHeaders.ContainsValue(HttpHeaderNames.SecWebsocketAccept, AsciiString.Of("12345"), false));
                }
            }
            finally
            {
                request.Release();
                if (response != null)
                {
                    response.Release();
                }
            }
        }
Exemple #4
0
        public void HttpUpgradeRequest()
        {
            EmbeddedChannel        ch            = this.CreateChannel(new MockOutboundHandler(this));
            IChannelHandlerContext handshakerCtx = ch.Pipeline.Context <WebSocketServerProtocolHandshakeHandler>();

            WriteUpgradeRequest(ch);

            IFullHttpResponse response = this.responses.Dequeue();

            Assert.Equal(SwitchingProtocols, response.Status);
            response.Release();
            Assert.NotNull(WebSocketServerProtocolHandler.GetHandshaker(handshakerCtx.Channel));
        }
Exemple #5
0
        public void WebSocketServerProtocolHandshakeHandlerReplacedBeforeHandshake()
        {
            EmbeddedChannel        ch            = CreateChannel(new MockOutboundHandler(this));
            IChannelHandlerContext handshakerCtx = ch.Pipeline.Context <WebSocketServerProtocolHandshakeHandler>();

            ch.Pipeline.AddLast(new ReplacedBeforeHandshakeHandler());
            WriteUpgradeRequest(ch);

            IFullHttpResponse response = _responses.Dequeue();

            Assert.Equal(SwitchingProtocols, response.Status);
            response.Release();
            Assert.NotNull(WebSocketServerProtocolHandler.GetHandshaker(handshakerCtx.Channel));
            Assert.False(ch.Finish());
        }
Exemple #6
0
        public void HttpUpgradeRequestInvalidUpgradeHeader()
        {
            EmbeddedChannel  ch = this.CreateChannel();
            IFullHttpRequest httpRequestWithEntity = new WebSocketRequestBuilder()
                                                     .HttpVersion(Http11)
                                                     .Method(HttpMethod.Get)
                                                     .Uri("/test")
                                                     .Connection("Upgrade")
                                                     .Version00()
                                                     .Upgrade("BogusSocket")
                                                     .Build();

            ch.WriteInbound(httpRequestWithEntity);

            IFullHttpResponse response = this.responses.Dequeue();

            Assert.Equal(BadRequest, response.Status);
            Assert.Equal("not a WebSocket handshake request: missing upgrade", GetResponseMessage(response));
            response.Release();
        }
Exemple #7
0
        public void HttpUpgradeRequestMissingWsKeyHeader()
        {
            EmbeddedChannel ch          = this.CreateChannel();
            IHttpRequest    httpRequest = new WebSocketRequestBuilder()
                                          .HttpVersion(Http11)
                                          .Method(HttpMethod.Get)
                                          .Uri("/test")
                                          .Key(null)
                                          .Connection("Upgrade")
                                          .Upgrade(HttpHeaderValues.Websocket)
                                          .Version13()
                                          .Build();

            ch.WriteInbound(httpRequest);

            IFullHttpResponse response = this.responses.Dequeue();

            Assert.Equal(BadRequest, response.Status);
            Assert.Equal("not a WebSocket request: missing key", GetResponseMessage(response));
            response.Release();
        }
Exemple #8
0
        private void TestDecodeFullResponseHeaders0(bool withStreamId)
        {
            EmbeddedChannel ch      = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(false));
            IHttp2Headers   headers = new DefaultHttp2Headers();

            headers.Scheme = HttpScheme.Http.Name;
            headers.Status = HttpResponseStatus.OK.CodeAsText;

            IHttp2HeadersFrame frame = new DefaultHttp2HeadersFrame(headers, true);

            if (withStreamId)
            {
                frame.Stream = new TestHttp2FrameStream();
            }

            Assert.True(ch.WriteInbound(frame));

            IFullHttpResponse response = ch.ReadInbound <IFullHttpResponse>();

            try
            {
                Assert.Equal(HttpResponseStatus.OK, response.Status);
                Assert.Equal(HttpVersion.Http11, response.ProtocolVersion);
                Assert.Equal(0, response.Content.ReadableBytes);
                Assert.True(response.TrailingHeaders.IsEmpty);
                Assert.False(HttpUtil.IsTransferEncodingChunked(response));
                if (withStreamId)
                {
                    Assert.Equal(1, response.Headers.GetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 0));
                }
            }
            finally
            {
                response.Release();
            }

            Assert.Null(ch.ReadInbound <object>());
            Assert.False(ch.Finish());
        }
Exemple #9
0
        public void DoNotCreateUTF8Validator()
        {
            var config = WebSocketServerProtocolConfig.NewBuilder()
                         .WebsocketPath("/test")
                         .WithUTF8Validator(false)
                         .Build();

            EmbeddedChannel ch = new EmbeddedChannel(
                new WebSocketServerProtocolHandler(config),
                new HttpRequestDecoder(),
                new HttpResponseEncoder(),
                new MockOutboundHandler(this));

            WriteUpgradeRequest(ch);

            IFullHttpResponse response = _responses.Dequeue();

            Assert.Equal(HttpResponseStatus.SwitchingProtocols, response.Status);
            response.Release();

            Assert.Null(ch.Pipeline.Get <Utf8FrameValidator>());
        }
Exemple #10
0
        public void HandleTextFrame()
        {
            var             customTextFrameHandler = new CustomTextFrameHandler();
            EmbeddedChannel ch = CreateChannel(customTextFrameHandler);

            WriteUpgradeRequest(ch);

            IFullHttpResponse response = _responses.Dequeue();

            Assert.Equal(HttpResponseStatus.SwitchingProtocols, response.Status);
            response.Release();

            if (ch.Pipeline.Context <HttpRequestDecoder>() != null)
            {
                // Removing the HttpRequestDecoder because we are writing a TextWebSocketFrame and thus
                // decoding is not necessary.
                ch.Pipeline.Remove <HttpRequestDecoder>();
            }

            ch.WriteInbound(new TextWebSocketFrame("payload"));

            Assert.Equal("processed: payload", customTextFrameHandler.Content);
            Assert.False(ch.Finish());
        }
Exemple #11
0
        protected internal override void Decode(IChannelHandlerContext context, IHttpObject message, List <object> output)
        {
            IFullHttpResponse response = null;

            try
            {
                if (!this.upgradeRequested)
                {
                    throw new InvalidOperationException("Read HTTP response without requesting protocol switch");
                }

                if (message is IHttpResponse rep)
                {
                    if (!HttpResponseStatus.SwitchingProtocols.Equals(rep.Status))
                    {
                        // The server does not support the requested protocol, just remove this handler
                        // and continue processing HTTP.
                        // NOTE: not releasing the response since we're letting it propagate to the
                        // next handler.
                        context.FireUserEventTriggered(UpgradeEvent.UpgradeRejected);
                        RemoveThisHandler(context);
                        context.FireChannelRead(rep);
                        return;
                    }
                }

                if (message is IFullHttpResponse fullRep)
                {
                    response = fullRep;
                    // Need to retain since the base class will release after returning from this method.
                    response.Retain();
                    output.Add(response);
                }
                else
                {
                    // Call the base class to handle the aggregation of the full request.
                    base.Decode(context, message, output);
                    if (output.Count == 0)
                    {
                        // The full request hasn't been created yet, still awaiting more data.
                        return;
                    }

                    Debug.Assert(output.Count == 1);
                    response = (IFullHttpResponse)output[0];
                }

                if (response.Headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgradeHeader) && !AsciiString.ContentEqualsIgnoreCase(this.upgradeCodec.Protocol, upgradeHeader))
                {
                    throw new  InvalidOperationException($"Switching Protocols response with unexpected UPGRADE protocol: {upgradeHeader}");
                }

                // Upgrade to the new protocol.
                this.sourceCodec.PrepareUpgradeFrom(context);
                this.upgradeCodec.UpgradeTo(context, response);

                // Notify that the upgrade to the new protocol completed successfully.
                context.FireUserEventTriggered(UpgradeEvent.UpgradeSuccessful);

                // We guarantee UPGRADE_SUCCESSFUL event will be arrived at the next handler
                // before http2 setting frame and http response.
                this.sourceCodec.UpgradeFrom(context);

                // We switched protocols, so we're done with the upgrade response.
                // Release it and clear it from the output.
                response.Release();
                output.Clear();
                RemoveThisHandler(context);
            }
            catch (Exception exception)
            {
                ReferenceCountUtil.Release(response);
                context.FireExceptionCaught(exception);
                RemoveThisHandler(context);
            }
        }