public async Task GzipEncodingMultipleMessages() { string text1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc"; string text2 = "dddddddddddddddddddeeeeeeeeeeeeeeeeeeeffffffffffffffffffff"; var data1 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text1)); var data2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2)); await this.BootstrapEnv(data1.ReadableBytes + data2.ReadableBytes); try { IHttp2Headers headers = new DefaultHttp2Headers() { Method = POST, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data1.Retain(), 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data2.Retain(), 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); Assert.Equal(text1 + text2, Encoding.UTF8.GetString(this.serverOut.ToArray())); } finally { data1.Release(); data2.Release(); } }
public async Task DeflateEncodingWriteLargeMessage() { int BUFFER_SIZE = 1 << 12; byte[] bytes = new byte[BUFFER_SIZE]; new Random().NextBytes(bytes); await this.BootstrapEnv(BUFFER_SIZE); var data = Unpooled.WrappedBuffer(bytes); try { IHttp2Headers headers = new DefaultHttp2Headers() { Method = POST, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data.Retain(), 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); Assert.Equal(data.ResetReaderIndex().ToString(Encoding.UTF8), Encoding.UTF8.GetString(this.serverOut.ToArray())); } finally { data.Release(); } }
public void GzipEncodingSingleEmptyMessage() { string text = ""; var data = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); this.BootstrapEnv(data.ReadableBytes); try { IHttp2Headers headers = new DefaultHttp2Headers() { Method = POST, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, false, this.NewPromiseClient()); this.clientEncoder.WriteDataAsync(this.CtxClient(), 3, (IByteBuffer)data.Retain(), 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); Assert.Equal(text, Encoding.UTF8.GetString(this.serverOut.ToArray())); } finally { data.Release(); } }
public async Task JustHeadersNoData() { await this.BootstrapEnv(0); IHttp2Headers headers = new DefaultHttp2Headers() { Method = GET, Path = PATH }; headers.Set(HttpHeaderNames.ContentEncoding, HttpHeaderValues.Gzip); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientEncoder.WriteHeadersAsync(this.CtxClient(), 3, headers, 0, true, this.NewPromiseClient()); this.clientHandler.Flush(this.CtxClient()); }); this.AwaitServer(); this.serverListener.Verify( x => x.OnHeadersRead( It.IsAny <IChannelHandlerContext>(), It.Is <int>(v => v == 3), It.Is <IHttp2Headers>(v => v.Equals(headers)), It.Is <int>(v => v == 0), It.Is <short>(v => v == Http2CodecUtil.DefaultPriorityWeight), It.Is <bool>(v => v == false), It.Is <int>(v => v == 0), It.Is <bool>(v => v == true))); }
public void ClientRequestStreamDependencyInHttpMessageFlow() { this.BootstrapEnv(1, 2, 1); string text = "hello world big time data!"; IByteBuffer content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); string text2 = "hello world big time data...number 2!!"; IByteBuffer content2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2)); IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/some/path/resource", content, true); IFullHttpMessage request2 = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/some/path/resource2", content2, true); try { HttpHeaders httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); HttpHeaders httpHeaders2 = request2.Headers; httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 5); httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamDependencyId, 3); httpHeaders2.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 123); httpHeaders2.SetInt(HttpHeaderNames.ContentLength, text2.Length); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("PUT"), Path = new AsciiString("/some/path/resource"), }; var http2Headers2 = new DefaultHttp2Headers() { Method = new AsciiString("PUT"), Path = new AsciiString("/some/path/resource2"), }; Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient()); this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 5, http2Headers2, 3, 123, true, 0, false, this.NewPromiseClient()); this.clientChannel.Flush(); // Headers are queued in the flow controller and so flush them. this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, content.RetainedDuplicate(), 0, true, this.NewPromiseClient()); this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 5, content2.RetainedDuplicate(), 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var httpObjectCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => httpObjectCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2)); this.capturedRequests = httpObjectCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); Assert.Equal(request2, this.capturedRequests[1]); } finally { request.Release(); request2.Release(); } }
public void PropagateSettings() { this.BootstrapEnv(1, 1, 2); Http2Settings settings = new Http2Settings().PushEnabled(true); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteSettingsAsync(this.CtxClient(), settings, this.NewPromiseClient()); this.clientChannel.Flush(); }); Assert.True(this.settingsLatch.Wait(TimeSpan.FromSeconds(5))); var settingsCaptor = new ArgumentCaptor <Http2Settings>(); this.settingsListener.Verify(x => x.MessageReceived(It.Is <Http2Settings>(v => settingsCaptor.Capture(v))), Times.Exactly(2)); Assert.Equal(settings, settingsCaptor.GetValue()); }
public void ClientRequestTrailingHeaders() { this.BootstrapEnv(1, 1, 1); string text = "some data"; IByteBuffer content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/some/path/resource2", content, true); try { HttpHeaders httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); HttpHeaders trailingHeaders = request.TrailingHeaders; trailingHeaders.Set(AsciiString.Of("Foo"), AsciiString.Of("goo")); trailingHeaders.Set(AsciiString.Of("fOo2"), AsciiString.Of("goo2")); trailingHeaders.Add(AsciiString.Of("foO2"), AsciiString.Of("goo3")); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Path = new AsciiString("/some/path/resource2"), }; IHttp2Headers http2Headers2 = new DefaultHttp2Headers(); http2Headers2.Set(new AsciiString("foo"), new AsciiString("goo")); http2Headers2.Set(new AsciiString("foo2"), new AsciiString("goo2")); http2Headers2.Add(new AsciiString("foo2"), new AsciiString("goo3")); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient()); this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, content.RetainedDuplicate(), 0, false, this.NewPromiseClient()); this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers2, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v)))); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); } finally { request.Release(); } }
public void ClientRequestSingleHeaderCookieSplitIntoMultipleEntries() { this.BootstrapEnv(1, 1, 1); IFullHttpRequest request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/some/path/resource2", true); try { HttpHeaders httpHeaders = request.Headers; httpHeaders.Set(HttpConversionUtil.ExtensionHeaderNames.Scheme, "https"); httpHeaders.Set(HttpHeaderNames.Host, "example.org"); httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.Set(HttpHeaderNames.Cookie, "a=b; c=d; e=f"); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Scheme = new AsciiString("https"), Authority = new AsciiString("example.org"), Path = new AsciiString("/some/path/resource2"), }; http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"a=b"); http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"c=d"); http2Headers.Add(HttpHeaderNames.Cookie, (AsciiString)"e=f"); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v)))); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); } finally { request.Release(); } }
public void ClientRequestSingleHeaderNonAsciiShouldThrow() { this.BootstrapEnv(1, 1, 1); var http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Scheme = new AsciiString("https"), Authority = new AsciiString("example.org"), Path = new AsciiString("/some/path/resource2"), }; http2Headers.Add(new AsciiString(Encoding.UTF8.GetBytes("çã"), true), new AsciiString(Encoding.UTF8.GetBytes("Ãã"), true)); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitResponses(); Assert.True(Http2Exception.IsStreamError(this.clientException)); }
public void ServerResponseHeaderInformational() { this.BootstrapEnv(1, 2, 1, 2, 1); IFullHttpMessage request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Put, "/info/test", true); HttpHeaders httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.Set(HttpHeaderNames.Expect, HttpHeaderValues.Continue); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); IHttp2Headers http2Headers = new DefaultHttp2Headers() { Method = new AsciiString("PUT"), Path = new AsciiString("/info/test") }; http2Headers.Set(new AsciiString(HttpHeaderNames.Expect.ToString()), new AsciiString(HttpHeaderValues.Continue.ToString())); IFullHttpMessage response = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.Continue); string text = "a big payload"; IByteBuffer payload = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); IFullHttpMessage request2 = (IFullHttpMessage)request.Replace(payload); IFullHttpMessage response2 = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.OK); try { Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers, 0, false, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); httpHeaders = response.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); IHttp2Headers http2HeadersResponse = new DefaultHttp2Headers() { Status = new AsciiString("100") }; Http2TestUtil.RunInChannel(this.serverConnectedChannel, () => { this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2HeadersResponse, 0, false, this.NewPromiseServer()); this.serverConnectedChannel.Flush(); }); this.AwaitResponses(); httpHeaders = request2.Headers; httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.Remove(HttpHeaderNames.Expect); Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteDataAsync(this.CtxClient(), 3, payload.RetainedDuplicate(), 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests2(); httpHeaders = response2.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); IHttp2Headers http2HeadersResponse2 = new DefaultHttp2Headers() { Status = new AsciiString("200") }; Http2TestUtil.RunInChannel(this.serverConnectedChannel, () => { this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2HeadersResponse2, 0, true, this.NewPromiseServer()); this.serverConnectedChannel.Flush(); }); this.AwaitResponses2(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2)); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(2, this.capturedRequests.Count); // We do not expect to have this header in the captured request so remove it now. Assert.NotNull(request.Headers.Remove((AsciiString)"x-http2-stream-weight")); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); Assert.Equal(request2, this.capturedRequests[1]); var responseCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.clientListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => responseCaptor.Capture((IFullHttpMessage)v))), Times.Exactly(2)); this.capturedResponses = responseCaptor.GetAllValues(); Assert.Equal(2, this.capturedResponses.Count); Assert.Equal(response, this.capturedResponses[0]); Assert.Equal(response2, this.capturedResponses[1]); } finally { request.Release(); request2.Release(); response.Release(); response2.Release(); } }
public void ServerRequestPushPromise() { this.BootstrapEnv(1, 1, 1); string text = "hello world big time data!"; IByteBuffer content = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text)); string text2 = "hello world smaller data?"; IByteBuffer content2 = Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes(text2)); IFullHttpMessage response = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.OK, content, true); IFullHttpMessage response2 = new DefaultFullHttpResponse(DotNetty.Codecs.Http.HttpVersion.Http11, HttpResponseStatus.Created, content2, true); IFullHttpMessage request = new DefaultFullHttpRequest(DotNetty.Codecs.Http.HttpVersion.Http11, HttpMethod.Get, "/push/test", true); try { HttpHeaders httpHeaders = response.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, text.Length); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); HttpHeaders httpHeaders2 = response2.Headers; httpHeaders2.Set(HttpConversionUtil.ExtensionHeaderNames.Scheme, "https"); httpHeaders2.Set(HttpHeaderNames.Host, "example.org"); httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 5); httpHeaders2.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamDependencyId, 3); httpHeaders2.SetInt(HttpHeaderNames.ContentLength, text2.Length); httpHeaders = request.Headers; httpHeaders.SetInt(HttpConversionUtil.ExtensionHeaderNames.StreamId, 3); httpHeaders.SetInt(HttpHeaderNames.ContentLength, 0); httpHeaders.SetShort(HttpConversionUtil.ExtensionHeaderNames.StreamWeight, 16); var http2Headers3 = new DefaultHttp2Headers() { Method = new AsciiString("GET"), Path = new AsciiString("/push/test"), }; Http2TestUtil.RunInChannel(this.clientChannel, () => { this.clientHandler.Encoder.WriteHeadersAsync(this.CtxClient(), 3, http2Headers3, 0, true, this.NewPromiseClient()); this.clientChannel.Flush(); }); this.AwaitRequests(); var requestCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.serverListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => requestCaptor.Capture((IFullHttpMessage)v)))); this.capturedRequests = requestCaptor.GetAllValues(); Assert.Equal(request, (IFullHttpRequest)this.capturedRequests[0]); IHttp2Headers http2Headers = new DefaultHttp2Headers() { Status = new AsciiString("200") }; // The PUSH_PROMISE frame includes a header block that contains a // complete set of request header fields that the server attributes to // the request. // https://tools.ietf.org/html/rfc7540#section-8.2.1 // Therefore, we should consider the case where there is no Http response status. IHttp2Headers http2Headers2 = new DefaultHttp2Headers() { Scheme = new AsciiString("https"), Authority = new AsciiString("example.org") }; Http2TestUtil.RunInChannel(this.serverConnectedChannel, () => { this.serverHandler.Encoder.WriteHeadersAsync(this.CtxServer(), 3, http2Headers, 0, false, this.NewPromiseServer()); this.serverHandler.Encoder.WritePushPromiseAsync(this.CtxServer(), 3, 2, http2Headers2, 0, this.NewPromiseServer()); this.serverHandler.Encoder.WriteDataAsync(this.CtxServer(), 3, content.RetainedDuplicate(), 0, true, this.NewPromiseServer()); this.serverHandler.Encoder.WriteDataAsync(this.CtxServer(), 5, content2.RetainedDuplicate(), 0, true, this.NewPromiseServer()); this.serverConnectedChannel.Flush(); }); this.AwaitResponses(); var responseCaptor = new ArgumentCaptor <IFullHttpMessage>(); this.clientListener.Verify(x => x.MessageReceived(It.Is <IHttpObject>(v => responseCaptor.Capture((IFullHttpMessage)v)))); this.capturedResponses = responseCaptor.GetAllValues(); Assert.Equal(response, this.capturedResponses[0]); } finally { request.Release(); response.Release(); response2.Release(); } }