/// <summary> /// Create a new object to contain the request data /// </summary> /// <param name="streamId">The stream associated with the request</param> /// <param name="http2Headers">The initial set of HTTP/2 headers to create the request with</param> /// <param name="alloc">The <see cref="IByteBufferAllocator"/> to use to generate the content of the message</param> /// <param name="validateHttpHeaders"><c>true</c> to validate HTTP headers in the http-codec /// <para><c>false</c> not to validate HTTP headers in the http-codec</para></param> /// <returns>A new request object which represents headers/data</returns> /// <exception cref="Http2Exception">see <see cref="AddHttp2ToHttpHeaders(int, IHttp2Headers, IFullHttpMessage, bool)"/></exception> public static IFullHttpRequest ToFullHttpRequest(int streamId, IHttp2Headers http2Headers, IByteBufferAllocator alloc, bool validateHttpHeaders) { // HTTP/2 does not define a way to carry the version identifier that is included in the HTTP/1.1 request line. var method = http2Headers.Method; if (method is null) { ThrowHelper.ThrowArgumentNullException_MethodHeader(); } var path = http2Headers.Path; if (path is null) { ThrowHelper.ThrowArgumentNullException_PathHeader(); } var msg = new DefaultFullHttpRequest(DotNettyHttpVersion.Http11, HttpMethod.ValueOf(AsciiString.Of(method)), path.ToString(), alloc.Buffer(), validateHttpHeaders); try { AddHttp2ToHttpHeaders(streamId, http2Headers, msg, false); } catch (Http2Exception) { _ = msg.Release(); throw; } catch (Exception t) { _ = msg.Release(); ThrowHelper.ThrowStreamError_Http2ToHttp1HeadersConversionError(streamId, t); } return(msg); }
public void DecodeContentDispositionFieldParameters() { const string Boundary = "74e78d11b0214bdcbc2f86491eeb4902"; const string Charset = "utf-8"; const string Filename = "attached_файл.txt"; string filenameEncoded = HttpUtility.UrlEncode(Filename, Encoding.UTF8); string body = "--" + Boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename*=" + Charset + "''" + filenameEncoded + "\r\n\r\n" + "foo\r\n" + "\r\n" + "--" + Boundary + "--"; var req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost", Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(body))); req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary); var inMemoryFactory = new DefaultHttpDataFactory(false); var decoder = new HttpPostRequestDecoder(inMemoryFactory, req); Assert.False(decoder.GetBodyHttpDatas().Count == 0); IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0]; Assert.IsAssignableFrom <IFileUpload>(part1); var fileUpload = (IFileUpload)part1; Assert.Equal(Filename, fileUpload.FileName); decoder.Destroy(); req.Release(); }
public void DecodeFullHttpRequestWithUrlEncodedBody() { byte[] bodyBytes = Encoding.UTF8.GetBytes("foo=bar&a=b&empty=&city=%3c%22new%22%20york%20city%3e"); IByteBuffer content = Unpooled.DirectBuffer(bodyBytes.Length); content.WriteBytes(bodyBytes); IFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "/", content); HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(req); Assert.NotEmpty(decoder.GetBodyHttpDatas()); Assert.NotEmpty(decoder.GetBodyHttpDatas()); Assert.Equal(4, decoder.GetBodyHttpDatas().Count); IAttribute attr = (IAttribute)decoder.GetBodyHttpData("foo"); Assert.True(attr.GetByteBuffer().IsDirect); Assert.Equal("bar", attr.Value); attr = (IAttribute)decoder.GetBodyHttpData("a"); Assert.True(attr.GetByteBuffer().IsDirect); Assert.Equal("b", attr.Value); attr = (IAttribute)decoder.GetBodyHttpData("empty"); Assert.True(attr.GetByteBuffer().IsDirect); Assert.Equal("", attr.Value); attr = (IAttribute)decoder.GetBodyHttpData("city"); Assert.True(attr.GetByteBuffer().IsDirect); Assert.Equal("<\"new\" york city>", attr.Value); decoder.Destroy(); req.Release(); }
public async Task PerformHandshakeWithoutOriginHeader() { EmbeddedChannel ch = new EmbeddedChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); IFullHttpRequest req = new DefaultFullHttpRequest( Http11, HttpMethod.Get, "/chat", Unpooled.CopiedBuffer("^n:ds[4U", Encoding.ASCII)); req.Headers.Set(HttpHeaderNames.Host, "server.example.com"); req.Headers.Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); req.Headers.Set(HttpHeaderNames.Connection, "Upgrade"); req.Headers.Set(HttpHeaderNames.SecWebsocketKey1, "4 @1 46546xW%0l 1 5"); req.Headers.Set(HttpHeaderNames.SecWebsocketProtocol, "chat, superchat"); WebSocketServerHandshaker00 handshaker00 = new WebSocketServerHandshaker00( "ws://example.com/chat", "chat", int.MaxValue); try { await handshaker00.HandshakeAsync(ch, req); Assert.False(true, "Expecting WebSocketHandshakeException"); } catch (WebSocketHandshakeException e) { Assert.Equal("Missing origin header, got only " + "[host, upgrade, connection, sec-websocket-key1, sec-websocket-protocol]", e.Message); } finally { req.Release(); } }
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 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(); } } }
static void PerformOpeningHandshake0(bool subProtocol) { var ch = new EmbeddedChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); var req = new DefaultFullHttpRequest(Http11, HttpMethod.Get, "/chat", Unpooled.CopiedBuffer(Encoding.ASCII.GetBytes("^n:ds[4U"))); req.Headers.Set(HttpHeaderNames.Host, "server.example.com"); req.Headers.Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); req.Headers.Set(HttpHeaderNames.Connection, "Upgrade"); req.Headers.Set(HttpHeaderNames.Origin, "http://example.com"); req.Headers.Set(HttpHeaderNames.SecWebsocketKey1, "4 @1 46546xW%0l 1 5"); req.Headers.Set(HttpHeaderNames.SecWebsocketKey2, "12998 5 Y3 1 .P00"); req.Headers.Set(HttpHeaderNames.SecWebsocketProtocol, "chat, superchat"); WebSocketServerHandshaker00 handshaker; if (subProtocol) { handshaker = new WebSocketServerHandshaker00("ws://example.com/chat", "chat", int.MaxValue); } else { handshaker = new WebSocketServerHandshaker00("ws://example.com/chat", null, int.MaxValue); } Assert.True(handshaker.HandshakeAsync(ch, req).Wait(TimeSpan.FromSeconds(2))); var ch2 = new EmbeddedChannel(new HttpResponseDecoder()); ch2.WriteInbound(ch.ReadOutbound <IByteBuffer>()); var res = ch2.ReadInbound <IHttpResponse>(); Assert.True(res.Headers.TryGet(HttpHeaderNames.SecWebsocketLocation, out ICharSequence value)); Assert.Equal("ws://example.com/chat", value.ToString()); if (subProtocol) { Assert.True(res.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out value)); Assert.Equal("chat", value.ToString()); } else { Assert.False(res.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out value)); } var content = ch2.ReadInbound <ILastHttpContent>(); Assert.Equal("8jKS'y:G*Co,Wxa-", content.Content.ToString(Encoding.ASCII)); content.Release(); req.Release(); }
static void PerformOpeningHandshake0(bool subProtocol) { var ch = new EmbeddedChannel( new HttpObjectAggregator(42), new HttpRequestDecoder(), new HttpResponseEncoder()); var req = new DefaultFullHttpRequest(Http11, HttpMethod.Get, "/chat"); req.Headers.Set(HttpHeaderNames.Host, "server.example.com"); req.Headers.Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); req.Headers.Set(HttpHeaderNames.Connection, "Upgrade"); req.Headers.Set(HttpHeaderNames.SecWebsocketKey, "dGhlIHNhbXBsZSBub25jZQ=="); req.Headers.Set(HttpHeaderNames.SecWebsocketOrigin, "http://example.com"); req.Headers.Set(HttpHeaderNames.SecWebsocketProtocol, "chat, superchat"); req.Headers.Set(HttpHeaderNames.SecWebsocketVersion, "13"); WebSocketServerHandshaker13 handshaker; if (subProtocol) { handshaker = new WebSocketServerHandshaker13( "ws://example.com/chat", "chat", false, int.MaxValue, false); } else { handshaker = new WebSocketServerHandshaker13( "ws://example.com/chat", null, false, int.MaxValue, false); } Assert.True(handshaker.HandshakeAsync(ch, req).Wait(TimeSpan.FromSeconds(2))); var resBuf = ch.ReadOutbound <IByteBuffer>(); var ch2 = new EmbeddedChannel(new HttpResponseDecoder()); ch2.WriteInbound(resBuf); var res = ch2.ReadInbound <IHttpResponse>(); Assert.True(res.Headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence value)); Assert.Equal("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", value.ToString()); if (subProtocol) { Assert.True(res.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out value)); Assert.Equal("chat", value.ToString()); } else { Assert.False(res.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out value)); } ReferenceCountUtil.Release(res); req.Release(); }
private static void NotLeakWhenWrapIllegalArgumentException(IByteBuffer buf) { buf.WriteCharSequence((AsciiString)"a=b&foo=%22bar%22&==", Encoding.ASCII); IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "/", buf); try { new HttpPostStandardRequestDecoder(request); } finally { Assert.True(request.Release()); } }
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 NotLeak() { IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "/", Unpooled.CopiedBuffer("a=1&&b=2", Encoding.UTF8)); try { new HttpPostStandardRequestDecoder(request); Assert.False(true); } catch (Exception exc) { Assert.IsType <ErrorDataDecoderException>(exc); } finally { Assert.True(request.Release()); } }
public void MultipartRequest() { string BOUNDARY = "01f136d9282f"; byte[] bodyBytes = Encoding.UTF8.GetBytes("--" + BOUNDARY + "\n" + "Content-Disposition: form-data; name=\"msg_id\"\n" + "\n" + "15200\n" + "--" + BOUNDARY + "\n" + "Content-Disposition: form-data; name=\"msg\"\n" + "\n" + "test message\n" + "--" + BOUNDARY + "--"); IByteBuffer byteBuf = Unpooled.DirectBuffer(bodyBytes.Length); byteBuf.WriteBytes(bodyBytes); IFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http10, HttpMethod.Post, "/up", byteBuf); req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + BOUNDARY); HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MinSize), req, Encoding.UTF8); Assert.True(decoder.IsMultipart); Assert.NotEmpty(decoder.GetBodyHttpDatas()); Assert.Equal(2, decoder.GetBodyHttpDatas().Count); IAttribute attrMsg = (IAttribute)decoder.GetBodyHttpData("msg"); Assert.True(attrMsg.GetByteBuffer().IsDirect); Assert.Equal("test message", attrMsg.Value); IAttribute attrMsgId = (IAttribute)decoder.GetBodyHttpData("msg_id"); Assert.True(attrMsgId.GetByteBuffer().IsDirect); Assert.Equal("15200", attrMsgId.Value); decoder.Destroy(); Assert.True(req.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 DecodeFullHttpRequestWithUrlEncodedBodyWithInvalidHexNibbleLo() { byte[] bodyBytes = Encoding.UTF8.GetBytes("foo=bar&a=b&empty=%2g&city=london"); IByteBuffer content = Unpooled.DirectBuffer(bodyBytes.Length); content.WriteBytes(bodyBytes); IFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "/", content); try { new HttpPostRequestDecoder(req); Assert.False(true); // Was expecting an ErrorDataDecoderException } catch (ErrorDataDecoderException e) { Assert.Equal("Invalid hex byte at index '0' in string: '%2g'", e.Message); } finally { req.Release(); } }
public void DecodeMalformedNotEncodedContentDispositionFieldParameters() { const string Boundary = "74e78d11b0214bdcbc2f86491eeb4902"; const string Body = "--" + Boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename*=not-encoded\r\n" + "\r\n" + "foo\r\n" + "\r\n" + "--" + Boundary + "--"; var req = new DefaultFullHttpRequest( HttpVersion.Http11, HttpMethod.Post, "http://localhost", Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(Body))); req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + Boundary); var inMemoryFactory = new DefaultHttpDataFactory(false); Assert.Throws <ErrorDataDecoderException>(() => new HttpPostRequestDecoder(inMemoryFactory, req)); req.Release(); }
private static void Upgrade0(EmbeddedChannel ch, WebSocketServerHandshaker13 handshaker) { var req = new DefaultFullHttpRequest(Http11, HttpMethod.Get, "/chat"); req.Headers.Set(HttpHeaderNames.Host, "server.example.com"); req.Headers.Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); req.Headers.Set(HttpHeaderNames.Connection, "Upgrade"); req.Headers.Set(HttpHeaderNames.SecWebsocketKey, "dGhlIHNhbXBsZSBub25jZQ=="); req.Headers.Set(HttpHeaderNames.SecWebsocketOrigin, "http://example.com"); req.Headers.Set(HttpHeaderNames.SecWebsocketProtocol, "chat, superchat"); req.Headers.Set(HttpHeaderNames.SecWebsocketVersion, "13"); Assert.True(handshaker.HandshakeAsync(ch, req).Wait(TimeSpan.FromSeconds(2))); var resBuf = ch.ReadOutbound <IByteBuffer>(); var ch2 = new EmbeddedChannel(new HttpResponseDecoder()); ch2.WriteInbound(resBuf); var res = ch2.ReadInbound <IHttpResponse>(); Assert.True(res.Headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence value)); Assert.Equal("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", value.ToString()); var subProtocols = handshaker.Subprotocols(); if (subProtocols.Any()) { Assert.True(res.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out value)); Assert.Equal("chat", value.ToString()); } else { Assert.False(res.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out _)); } ReferenceCountUtil.Release(res); req.Release(); }
public void DecodeWithLanguageContentDispositionFieldParametersForFix() { string boundary = "952178786863262625034234"; string encoding = "UTF-8"; string filename = "测试test.txt"; string filenameEncoded = UrlEncoder.Default.Encode(filename /*, encoding*/); string body = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename*=\"" + encoding + "''" + filenameEncoded + "\"\r\n" + "\r\n" + "foo\r\n" + "\r\n" + "--" + boundary + "--"; DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost", Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(body))); req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + boundary); DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false); HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(inMemoryFactory, req); Assert.NotEmpty(decoder.GetBodyHttpDatas()); IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0]; Assert.True(part1 is IFileUpload); // "the item should be a FileUpload" IFileUpload fileUpload = (IFileUpload)part1; Assert.Equal(filename, fileUpload.FileName); // "the filename should be decoded" decoder.Destroy(); req.Release(); }
public void DecodeOtherMimeHeaderFields() { string boundary = "74e78d11b0214bdcbc2f86491eeb4902"; string filecontent = "123456"; string body = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=" + "\"" + "attached.txt" + "\"" + "\r\n" + "Content-Type: application/octet-stream" + "\r\n" + "Content-Encoding: gzip" + "\r\n" + "\r\n" + filecontent + "\r\n" + "--" + boundary + "--"; DefaultFullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Post, "http://localhost", Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(body))); req.Headers.Add(HttpHeaderNames.ContentType, "multipart/form-data; boundary=" + boundary); req.Headers.Add(HttpHeaderNames.TransferEncoding, HttpHeaderValues.Chunked); DefaultHttpDataFactory inMemoryFactory = new DefaultHttpDataFactory(false); HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(inMemoryFactory, req); Assert.False(decoder.GetBodyHttpDatas().Count == 0); IInterfaceHttpData part1 = decoder.GetBodyHttpDatas()[0]; Assert.True(part1 is IFileUpload, "the item should be a FileUpload"); IFileUpload fileUpload = (IFileUpload)part1; byte[] fileBytes = fileUpload.GetBytes(); Assert.True(filecontent.Equals(Encoding.UTF8.GetString(fileBytes)), "the filecontent should not be decoded"); decoder.Destroy(); req.Release(); }
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(); } }