public void ExpectContinueResetHttpObjectDecoder() { // request with header "Expect: 100-continue" must be replied with one "100 Continue" response // case 5: Test that HttpObjectDecoder correctly resets its internal state after a failed expectation. var decoder = new HttpRequestDecoder(); const int MaxBytes = 10; var aggregator = new HttpObjectAggregator(MaxBytes); var testHandler = new TestHandler(); var channel = new EmbeddedChannel(decoder, aggregator, testHandler); string req1 = "POST /1 HTTP/1.1\r\n" + "Content-Length: " + (MaxBytes + 1) + "\r\n" + "Expect: 100-continue\r\n" + "\r\n"; Assert.False(channel.WriteInbound(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(req1)))); var resp = channel.ReadOutbound <IFullHttpResponse>(); Assert.Equal(HttpStatusClass.ClientError, resp.Status.CodeClass); resp.Release(); string req2 = "POST /2 HTTP/1.1\r\n" + "Content-Length: " + MaxBytes + "\r\n" + "Expect: 100-continue\r\n" + "\r\n"; Assert.False(channel.WriteInbound(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(req2)))); resp = channel.ReadOutbound <IFullHttpResponse>(); Assert.Equal(100, resp.Status.Code); resp.Release(); var content = new byte[MaxBytes]; Assert.False(channel.WriteInbound(Unpooled.WrappedBuffer(content))); IFullHttpRequest req = testHandler.Request; Assert.NotNull(req); Assert.Equal("/2", req.Uri); Assert.Equal(10, req.Content.ReadableBytes); req.Release(); AssertHasInboundMessages(channel, false); AssertHasOutboundMessages(channel, false); Assert.False(channel.Finish()); }
public void TestTransferCodingGZIPAndChunked() { string requestStr = "POST / HTTP/1.1\r\n" + "Host: example.com\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Trailer: My-Trailer\r\n" + "Transfer-Encoding: gzip, chunked\r\n" + "\r\n"; HttpRequestDecoder decoder = new HttpRequestDecoder(); HttpContentDecoder decompressor = new HttpContentDecompressor(); EmbeddedChannel channel = new EmbeddedChannel(decoder, decompressor); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(requestStr, Encoding.ASCII))); string chunkLength = GzHelloWorld.Length.ToString("x2"); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(chunkLength + "\r\n", Encoding.ASCII))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(GzHelloWorld))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("\r\n")))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer("0\r\n", Encoding.ASCII))); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer("My-Trailer: 42\r\n\r\n", Encoding.ASCII))); IHttpRequest request = channel.ReadInbound <IHttpRequest>(); Assert.True(request.Result.IsSuccess); Assert.True(request.Headers.ContainsValue(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked, true)); Assert.False(request.Headers.Contains(HttpHeaderNames.ContentLength)); IHttpContent chunk1 = channel.ReadInbound <IHttpContent>(); Assert.True(chunk1.Result.IsSuccess); Assert.Equal(HelloWorld, chunk1.Content.ToString(Encoding.ASCII)); chunk1.Release(); ILastHttpContent chunk2 = channel.ReadInbound <ILastHttpContent>(); Assert.True(chunk2.Result.IsSuccess); Assert.Equal("42", chunk2.TrailingHeaders.Get(AsciiString.Of("My-Trailer"), null)); chunk2.Release(); Assert.False(channel.Finish()); channel.ReleaseInbound(); }
public void Http100ContinueWithBadClient() { var decoder = new HttpRequestDecoder(); var channel = new EmbeddedChannel(decoder); const string Oversized = "PUT /file HTTP/1.1\r\n" + "Expect: 100-continue\r\n" + "Content-Length: 1048576000\r\n\r\n" + "WAY_TOO_LARGE_DATA_BEGINS"; byte[] data = Encoding.ASCII.GetBytes(Oversized); channel.WriteInbound(Unpooled.CopiedBuffer(data)); var req = channel.ReadInbound <IHttpRequest>(); Assert.NotNull(req); var prematureData = channel.ReadInbound <IHttpContent>(); prematureData.Release(); req = channel.ReadInbound <IHttpRequest>(); Assert.Null(req); // At this point, we assume that we sent '413 Entity Too Large' to the peer without closing the connection // so that the client can try again. decoder.Reset(); const string Query = "GET /max-file-size HTTP/1.1\r\n\r\n"; data = Encoding.ASCII.GetBytes(Query); channel.WriteInbound(Unpooled.CopiedBuffer(data)); req = channel.ReadInbound <IHttpRequest>(); Assert.NotNull(req); var last = channel.ReadInbound <ILastHttpContent>(); Assert.NotNull(last); Assert.IsType <EmptyLastHttpContent>(last); Assert.False(channel.Finish()); }
public void TestDanglingComma(bool allowDuplicateContentLengths) { var decoder = new HttpRequestDecoder( HttpObjectDecoder.DefaultMaxInitialLineLength, HttpObjectDecoder.DefaultMaxHeaderSize, HttpObjectDecoder.DefaultMaxChunkSize, HttpObjectDecoder.DefaultValidateHeaders, HttpObjectDecoder.DefaultInitialBufferSize, allowDuplicateContentLengths); var channel = new EmbeddedChannel(decoder); string requestStr = "GET /some/path HTTP/1.1\r\n" + "Content-Length: 1,\r\n" + "Connection: close\n\n" + "ab"; Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(requestStr, Encoding.ASCII))); IHttpRequest request = channel.ReadInbound <IHttpRequest>(); AssertInvalid(request); Assert.False(channel.Finish()); }
public void TestMultipleContentLengthHeadersBehavior(bool allowDuplicateContentLengths, bool sameValue, bool singleField) { var decoder = new HttpRequestDecoder( HttpObjectDecoder.DefaultMaxInitialLineLength, HttpObjectDecoder.DefaultMaxHeaderSize, HttpObjectDecoder.DefaultMaxChunkSize, HttpObjectDecoder.DefaultValidateHeaders, HttpObjectDecoder.DefaultInitialBufferSize, allowDuplicateContentLengths); var channel = new EmbeddedChannel(decoder); string requestStr = SetupRequestString(sameValue, singleField); Assert.True(channel.WriteInbound(Unpooled.CopiedBuffer(requestStr, Encoding.ASCII))); IHttpRequest request = channel.ReadInbound <IHttpRequest>(); if (allowDuplicateContentLengths) { if (sameValue) { AssertValid(request); var contentLengths = request.Headers.GetAll(HttpHeaderNames.ContentLength); Assert.Contains("1", contentLengths.ToString()); ILastHttpContent body = channel.ReadInbound <ILastHttpContent>(); Assert.Equal(1, body.Content.ReadableBytes); Assert.Equal("a", body.Content.ReadCharSequence(1, Encoding.ASCII).ToString()); } else { AssertInvalid(request); } } else { AssertInvalid(request); } Assert.False(channel.Finish()); }