public void TestContentLengthNotClosed() { string sampleContent = "<test><val>hello</val></test>"; int sampleContentLength = Encoding.UTF8.GetByteCount(sampleContent); string sampleRequest = "HTTP/1.0 200 OK\r\nHost: localhost\r\nContent-Length: " + sampleContentLength + "\r\n\r\n" + sampleContent; ChunkedBuffer buffer = new ChunkedBuffer(pool); buffer.Write(Encoding.ASCII.GetBytes(sampleRequest), 0, Encoding.ASCII.GetByteCount(sampleRequest)); HttpResponse response = new HttpResponse(pool); Assert.IsTrue(response.Parse(buffer.Stream, false)); Assert.AreEqual("HTTP/1.0", response.Version); Assert.AreEqual("200", response.Code); Assert.AreEqual("OK", response.Reason); Assert.AreEqual("HTTP/1.0 200 OK", response.CommandLine); Assert.AreEqual("localhost", response.Header["Host"]); Assert.AreEqual(sampleContentLength, response.BodySize); Assert.AreEqual(sampleContentLength, response.Body.WritePosition); MemoryStream stream = new MemoryStream(); response.Write(stream, false); stream.Position = 0; using (StreamReader reader = new StreamReader(stream)) { Assert.AreEqual(sampleRequest, reader.ReadToEnd()); } }
public void TestSimpleClosed() { string sampleRequest = "HTTP/1.0 200 OK\r\nHost: localhost\r\n\r\n"; ChunkedBuffer buffer = new ChunkedBuffer(pool); buffer.Write(Encoding.ASCII.GetBytes(sampleRequest), 0, Encoding.ASCII.GetByteCount(sampleRequest)); HttpResponse response = new HttpResponse(pool); Assert.IsTrue(response.Parse(buffer.Stream, true)); Assert.AreEqual("HTTP/1.0", response.Version); Assert.AreEqual("200", response.Code); Assert.AreEqual("OK", response.Reason); Assert.AreEqual("HTTP/1.0 200 OK", response.CommandLine); Assert.AreEqual("localhost", response.Header["Host"]); Assert.AreEqual(0, response.BodySize); Assert.AreEqual(0, response.Body.WritePosition); MemoryStream stream = new MemoryStream(); response.Write(stream, false); stream.Position = 0; using (StreamReader reader = new StreamReader(stream)) { Assert.AreEqual(sampleRequest, reader.ReadToEnd()); } }
/// <summary> /// Handles the WebSocket handshake. /// </summary> /// <param name="channel"></param> /// <param name="request"></param> private void HandleHandshake(ISockNetChannel channel, ref HttpResponse data) { if (expectedAccept.Equals(data.Header[WebSocketUtil.WebSocketAcceptHeader])) { SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Established Web-Socket connection."); channel.Pipe.RemoveIncoming<HttpResponse>(HandleHandshake); channel.Pipe.AddIncomingFirst<object>(HandleIncomingFrames); channel.Pipe.AddOutgoingLast<object>(HandleOutgoingFrames); channel.RemoveModule(httpModule); if (onWebSocketEstablished != null) { onWebSocketEstablished(channel); } } else { SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Web-Socket handshake incomplete."); channel.Close(); } }
public void TestServer() { ObjectPool<byte[]> pool = new ObjectPool<byte[]>(() => { return new byte[1024]; }); const String testString = "what a great test!"; ServerSockNetChannel server = (ServerSockNetChannel)SockNetServer.Create(GetLocalIpAddress(), 0, ServerSockNetChannel.DefaultBacklog, pool) .AddModule(new HttpSockNetChannelModule(HttpSockNetChannelModule.ParsingMode.Server)); try { Assert.IsNotNull(server.Bind().WaitForValue(TimeSpan.FromSeconds(5))); server.Pipe.AddIncomingLast<HttpRequest>((ISockNetChannel channel, ref HttpRequest data) => { HttpResponse response = new HttpResponse(channel.BufferPool) { Version = data.Version, Code = "200", Reason = "OK" }; response.Header["Content-Length"] = "" + data.BodySize; Copy(data.Body.Stream, response.Body.Stream, data.BodySize); Promise<ISockNetChannel> sendPromise = channel.Send(response); if (("http/1.0".Equals(data.Version) && !"keep-alive".Equals(data.Header["connection"], StringComparison.CurrentCultureIgnoreCase)) || "close".Equals(data.Header["connection"], StringComparison.CurrentCultureIgnoreCase)) { sendPromise.OnFulfilled = (ISockNetChannel value, Exception e, Promise<ISockNetChannel> promise) => { value.Close(); }; } }); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://" + GetLocalIpAddress() + ":" + server.LocalEndpoint.Port); request.KeepAlive = false; request.Timeout = 5000; request.Method = "POST"; using (StreamWriter writer = new StreamWriter(request.GetRequestStream(), Encoding.Default)) { writer.Write(testString); } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { Assert.AreEqual(200, (int)response.StatusCode); Assert.AreEqual("OK", response.StatusDescription); Assert.AreEqual(Encoding.Default.GetByteCount(testString), response.ContentLength); using (StreamReader responseReader = new StreamReader(response.GetResponseStream(), Encoding.Default)) { Assert.AreEqual(testString, responseReader.ReadToEnd()); } } } finally { server.Close(); } }
public void Start(bool isTls = false) { server = SockNetServer.Create(GetLocalIpAddress(), 0, ServerSockNetChannel.DefaultBacklog, pool); try { server.AddModule(new HttpSockNetChannelModule(HttpSockNetChannelModule.ParsingMode.Server)); server.Pipe.AddIncomingLast<HttpRequest>((ISockNetChannel channel, ref HttpRequest data) => { HttpResponse response = new HttpResponse(channel.BufferPool) { Version = data.Version, Code = "200", Reason = "OK" }; foreach (string headerName in data.Headers.Names) { response.Headers[headerName] = data.Headers[headerName]; } response.Body = data.Body; channel.Send(response); }); if (isTls) { byte[] rawCert = CertificateUtil.CreateSelfSignCertificatePfx("CN=\"test\"; C=\"USA\"", DateTime.Today.AddDays(-10), DateTime.Today.AddDays(+10)); server.BindWithTLS(new X509Certificate2(rawCert), (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => { return true; }).WaitForValue(TimeSpan.FromSeconds(5)); } else { server.Bind().WaitForValue(TimeSpan.FromSeconds(5)); } Assert.IsTrue(server.IsActive); } catch (Exception) { Stop(); } }
public void TestChunked() { string sampleContent = "<test><val>hello</val></test>"; int sampleContentLength = Encoding.UTF8.GetByteCount(sampleContent); string chunk1Content = "<test><val>"; string chunk2Content = "hello</val>"; string chunk3Content = "</test>"; int chunk1ContentLength = Encoding.UTF8.GetByteCount(chunk1Content); int chunk2ContentLength = Encoding.UTF8.GetByteCount(chunk2Content); int chunk3ContentLength = Encoding.UTF8.GetByteCount(chunk3Content); string chunk1Request = "HTTP/1.0 200 OK\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n" + string.Format("{0:X}", chunk1ContentLength) + "\r\n" + chunk1Content + "\r\n"; string chunk2Request = string.Format("{0:X}", chunk2ContentLength) + "\r\n" + chunk2Content + "\r\n"; string chunk3Request = string.Format("{0:X}", chunk3ContentLength) + "\r\n" + chunk3Content + "\r\n"; string chunk4Request = "0\r\n\r\n"; ChunkedBuffer buffer1 = new ChunkedBuffer(pool); buffer1.Write(Encoding.ASCII.GetBytes(chunk1Request), 0, Encoding.ASCII.GetByteCount(chunk1Request)); ChunkedBuffer buffer2 = new ChunkedBuffer(pool); buffer2.Write(Encoding.ASCII.GetBytes(chunk2Request), 0, Encoding.ASCII.GetByteCount(chunk2Request)); ChunkedBuffer buffer3 = new ChunkedBuffer(pool); buffer3.Write(Encoding.ASCII.GetBytes(chunk3Request), 0, Encoding.ASCII.GetByteCount(chunk3Request)); ChunkedBuffer buffer4 = new ChunkedBuffer(pool); buffer4.Write(Encoding.ASCII.GetBytes(chunk4Request), 0, Encoding.ASCII.GetByteCount(chunk4Request)); HttpResponse response = new HttpResponse(pool); Assert.IsFalse(response.IsChunked); Assert.IsFalse(response.Parse(buffer1.Stream, false)); Assert.IsTrue(response.IsChunked); Assert.IsFalse(response.Parse(buffer2.Stream, false)); Assert.IsTrue(response.IsChunked); Assert.IsFalse(response.Parse(buffer3.Stream, false)); Assert.IsTrue(response.IsChunked); Assert.IsTrue(response.Parse(buffer4.Stream, false)); Assert.IsTrue(response.IsChunked); Assert.AreEqual("HTTP/1.0", response.Version); Assert.AreEqual("200", response.Code); Assert.AreEqual("OK", response.Reason); Assert.AreEqual("HTTP/1.0 200 OK", response.CommandLine); Assert.AreEqual("localhost", response.Header["Host"]); Assert.AreEqual(sampleContentLength, response.BodySize); Assert.AreEqual(sampleContentLength, response.Body.WritePosition); MemoryStream stream = new MemoryStream(); response.Write(stream, false); stream.Position = 0; using (StreamReader reader = new StreamReader(stream)) { Assert.AreEqual("HTTP/1.0 200 OK\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n" + sampleContent, reader.ReadToEnd()); } }
/// <summary> /// Handles the WebSocket handshake. /// </summary> /// <param name="channel"></param> /// <param name="request"></param> private void HandleHandshake(ISockNetChannel channel, ref HttpRequest request) { string connection = request.Header["Connection"]; string upgrade = request.Header["Upgrade"]; string securityKey = request.Header[WebSocketUtil.WebSocketKeyHeader]; if (connection != null && upgrade != null && securityKey != null && "websocket".Equals(upgrade.Trim().ToLower()) && "upgrade".Equals(connection.Trim().ToLower())) { string[] requestProtocols = request.Headers[WebSocketUtil.WebSocketProtocolHeader]; List<string> handledProtocols = new List<string>(); if (requestProtocols != null && protocolDelegate != null) { for (int i = 0; i < requestProtocols.Length; i++) { if (protocolDelegate(channel, requestProtocols[i])) { handledProtocols.Add(requestProtocols[i]); } } } HttpResponse response = new HttpResponse(channel.BufferPool) { Version = "HTTP/1.1", Code = "101", Reason = "Switching Protocols" }; response.Header["Upgrade"] = "websocket"; response.Header["Connection"] = "Upgrade"; response.Header[WebSocketUtil.WebSocketAcceptHeader] = WebSocketUtil.GenerateAccept(securityKey); response.Header[WebSocketUtil.WebSocketProtocolHeader] = string.Join(",", handledProtocols.ToArray()); channel.Send(response); channel.RemoveModule(httpModule); channel.Pipe.AddIncomingFirst<object>(HandleIncomingFrames); channel.Pipe.AddOutgoingLast<object>(HandleOutgoingFrames); } else { SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Expecting upgrade request."); channel.Close(); } }