/// <summary>
            /// Handles an incoming raw HTTP response.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            private void HandleIncomingResponse(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer data = (ChunkedBuffer)obj;

                if (currentIncoming == null)
                {
                    currentIncoming = new HttpResponse(channel.BufferPool);
                }

                if (currentIncoming.Parse(data.Stream, channel.IsActive))
                {
                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received HTTP Response: Command Line: [{0}], Body Size [{1}]", currentIncoming.CommandLine, currentIncoming.BodySize);
                    }

                    obj             = currentIncoming;
                    currentIncoming = null;
                }
            }
Exemplo n.º 2
0
        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());
            }
        }
Exemplo n.º 3
0
        public void TestSimpleClosed()
        {
            string sampleRequest = "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";

            using (ChunkedBuffer buffer = new ChunkedBuffer(pool))
            {
                buffer.Write(Encoding.ASCII.GetBytes(sampleRequest), 0, Encoding.ASCII.GetByteCount(sampleRequest));

                using (HttpRequest request = new HttpRequest(pool))
                {
                    Assert.IsTrue(request.Parse(buffer.Stream, true));

                    Assert.AreEqual("GET", request.Action);
                    Assert.AreEqual("/", request.Path);
                    Assert.AreEqual("HTTP/1.0", request.Version);
                    Assert.AreEqual("GET / HTTP/1.0", request.CommandLine);
                    Assert.AreEqual("localhost", request.Header["Host"]);
                    Assert.AreEqual(0, request.BodySize);
                    Assert.AreEqual(0, request.Body.WritePosition);

                    MemoryStream stream = new MemoryStream();
                    request.Write(stream, false);
                    stream.Position = 0;

                    using (StreamReader reader = new StreamReader(stream))
                    {
                        Assert.AreEqual(sampleRequest, reader.ReadToEnd());
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Callback for the queued write.
        /// </summary>
        /// <param name="value"></param>
        /// <param name="error"></param>
        /// <param name="promise"></param>
        private void QueueWriteCallback(ChunkedBuffer buffer, Exception error, Promise <ChunkedBuffer> promise)
        {
            SendQueueState state = (SendQueueState)promise.State;

            try
            {
                SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, (stream is SslStream ? "[SSL] " : "") + "Sent data to [{0}].", RemoteEndpoint);

                // if the receive buffer was being sent don't close it
                if (buffer != chunkedBuffer)
                {
                    buffer.Close();
                }
            }
            catch (Exception e)
            {
                SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to close the given buffer", e);
            }
            finally
            {
                Interlocked.CompareExchange(ref sendState, 0, 1);

                try
                {
                    state.promise.CreateFulfiller().Fulfill(this);
                }
                finally
                {
                    NotifySendQueue();
                }
            }
        }
Exemplo n.º 5
0
        public void TestContentLengthNotClosed()
        {
            string sampleContent       = "<test><val>hello</val></test>";
            int    sampleContentLength = Encoding.UTF8.GetByteCount(sampleContent);
            string sampleRequest       = "POST / HTTP/1.0\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));

            HttpRequest request = new HttpRequest(pool);

            Assert.IsTrue(request.Parse(buffer.Stream, false));

            Assert.AreEqual("POST", request.Action);
            Assert.AreEqual("/", request.Path);
            Assert.AreEqual("HTTP/1.0", request.Version);
            Assert.AreEqual("POST / HTTP/1.0", request.CommandLine);
            Assert.AreEqual("localhost", request.Header["Host"]);
            Assert.AreEqual(sampleContentLength, request.BodySize);
            Assert.AreEqual(sampleContentLength, request.Body.WritePosition);

            MemoryStream stream = new MemoryStream();

            request.Write(stream, false);
            stream.Position = 0;

            using (StreamReader reader = new StreamReader(stream))
            {
                Assert.AreEqual(sampleRequest, reader.ReadToEnd());
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates a HTTP payload.
        /// </summary>
        public HttpPayload(ObjectPool <byte[]> bufferPool)
        {
            _multiValueHeaderView  = new MultiValueHeaderView(this);
            _singleValueHeaderView = new SingleValueHeaderView(this);

            IsChunked = false;
            Body      = new ChunkedBuffer(bufferPool);
        }
        public ChunkedBuffer ToBuffer(GdsFrame frame)
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            ChunkedBuffer buffer = new ChunkedBuffer(pool);

            frame.Write(buffer.Stream);
            return(buffer);
        }
Exemplo n.º 8
0
        public void TestFullCompressed()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            Random rand = new Random(this.GetHashCode() ^ DateTime.Now.Millisecond);

            uint streamId = (uint)rand.Next(0, (int)(Math.Pow(2, 24) - 1));

            string header1Key = "the first key";

            byte[] header1Value = new byte[rand.Next(32, 1024 * 64)];
            rand.NextBytes(header1Value);

            string header2Key = "the second key";

            byte[] header2Value = new byte[rand.Next(32, 1024 * 64)];
            rand.NextBytes(header2Value);

            byte[] bodyBuffer = new byte[rand.Next(1024, 1024 * 64)];
            rand.NextBytes(bodyBuffer);
            ChunkedBuffer body = new ChunkedBuffer(pool);

            body.OfferRaw(bodyBuffer, 0, bodyBuffer.Length);

            GdsFrame frame = GdsFrame.NewContentFrame(streamId, new Dictionary <string, byte[]>()
            {
                { header1Key, header1Value },
                { header2Key, header2Value }
            }, true, body, true);

            Assert.AreEqual(true, frame.IsComplete);
            Assert.AreEqual(GdsFrame.GdsFrameType.Full, frame.Type);
            Assert.AreEqual(streamId, frame.StreamId);
            Assert.AreEqual(2, frame.Headers.Count);

            MemoryStream stream = new MemoryStream();

            frame.Write(stream);

            stream.Position = 0;

            GdsFrame readFrame = GdsFrame.ParseFrame(stream, pool);

            Assert.AreEqual(true, readFrame.IsComplete);
            Assert.AreEqual(GdsFrame.GdsFrameType.Full, readFrame.Type);
            Assert.AreEqual(streamId, readFrame.StreamId);
            Assert.AreEqual(2, readFrame.Headers.Count);

            byte[] readBodyBuffer = new byte[readFrame.Body.AvailableBytesToRead];
            readFrame.Body.Read(readBodyBuffer, 0, readBodyBuffer.Length);

            AssertEquals(bodyBuffer, readBodyBuffer);

            frame.Dispose();
            readFrame.Dispose();
        }
Exemplo n.º 9
0
        /// <summary>
        /// Queues the given buffer to the send queue and notifies it.
        /// </summary>
        /// <param name="buffer"></param>
        private void EnqueueToSendQueueAndNotify(ChunkedBuffer buffer, Promise <ISockNetChannel> promise)
        {
            sendQueue.Enqueue(new SendQueueState()
            {
                buffer  = buffer,
                promise = promise
            });

            NotifySendQueue();
        }
Exemplo n.º 10
0
            /// <summary>
            /// Updates the given chunked frame with a new frame.
            /// </summary>
            /// <param name="frame"></param>
            private static void UpdateChunk(ref GdsFrame chunkedFrame, GdsFrame frame, ISockNetChannel channel)
            {
                if (chunkedFrame == null)
                {
                    chunkedFrame = frame;  // set initial frame
                }
                else
                {
                    if (frame.Type == GdsFrame.GdsFrameType.Ping || frame.Type == GdsFrame.GdsFrameType.Pong || frame.Type == GdsFrame.GdsFrameType.Close)
                    {
                        chunkedFrame = frame;
                    }

                    GdsFrame.GdsFrameType type = chunkedFrame.Type;

                    ChunkedBuffer body = null;

                    if (frame.Type == GdsFrame.GdsFrameType.BodyOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.HeadersOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        body = new ChunkedBuffer(channel.BufferPool);
                        chunkedFrame.Body.DrainToStreamSync(body.Stream).Close();
                        frame.Body.DrainToStreamSync(body.Stream).Close();
                    }

                    Dictionary <string, byte[]> headers = null;

                    if (frame.Type == GdsFrame.GdsFrameType.HeadersOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.BodyOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        headers = new Dictionary <string, byte[]>(StringComparer.OrdinalIgnoreCase);
                        foreach (KeyValuePair <string, byte[]> kvp in chunkedFrame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                        foreach (KeyValuePair <string, byte[]> kvp in frame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                    }

                    chunkedFrame.Dispose();
                    frame.Dispose();

                    chunkedFrame = GdsFrame.NewContentFrame(frame.StreamId, headers, false, body, frame.IsComplete);
                }
            }
            /// <summary>
            /// Handles incoming raw frames and translates them into WebSocketFrame(s)
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleIncomingFrames(ISockNetChannel channel, ref object data)
            {
                if (!(data is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer stream           = (ChunkedBuffer)data;
                long          startingPosition = stream.ReadPosition;

                try
                {
                    WebSocketFrame frame = WebSocketFrame.ParseFrame(stream.Stream);

                    if (combineContinuations)
                    {
                        if (frame.IsFinished)
                        {
                            UpdateContinuation(ref continuationFrame, frame);

                            data = continuationFrame;
                            continuationFrame = null;
                        }
                        else
                        {
                            UpdateContinuation(ref continuationFrame, frame);
                        }
                    }
                    else
                    {
                        data = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received WebSocket message. Size: {0}, Type: {1}, IsFinished: {2}", frame.Data.Length, Enum.GetName(typeof(WebSocketFrame.WebSocketFrameOperation), frame.Operation), frame.IsFinished);
                    }
                }
                catch (EndOfStreamException)
                {
                    // websocket frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // websocket frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse web-socket request", e);

                    channel.Close();
                }
            }
Exemplo n.º 12
0
            /// <summary>
            /// Handles an incomming raw Gds message.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleIncoming(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer stream           = (ChunkedBuffer)obj;
                long          startingPosition = stream.ReadPosition;

                try
                {
                    GdsFrame frame = GdsFrame.ParseFrame(stream.Stream, channel.BufferPool);

                    if (combineChunks)
                    {
                        if (frame.IsComplete)
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);

                            obj          = chunkedFrame;
                            chunkedFrame = null;
                        }
                        else
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);
                        }
                    }
                    else
                    {
                        obj = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received Gds message. Body Size: {0}, Type: {1}, IsComplete: {2}", frame.Body.AvailableBytesToRead, Enum.GetName(typeof(GdsFrame.GdsFrameType), frame.Type), frame.IsComplete);
                    }
                }
                catch (EndOfStreamException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse Gds message", e);
                }
            }
            /// <summary>
            /// Handles WebSocketFrame(s) and translates them into raw frames.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleOutgoingFrames(ISockNetChannel channel, ref object data)
            {
                if (!(data is WebSocketFrame))
                {
                    return;
                }

                WebSocketFrame webSocketFrame = (WebSocketFrame)data;
                ChunkedBuffer  buffer         = new ChunkedBuffer(channel.BufferPool);

                webSocketFrame.Write(buffer.Stream);
                data = buffer;
            }
Exemplo n.º 14
0
        public void TestBodyOnly()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            Random rand = new Random(this.GetHashCode() ^ DateTime.Now.Millisecond);

            uint streamId = (uint)rand.Next(0, (int)(Math.Pow(2, 24) - 1));

            byte[] bodyBuffer = new byte[rand.Next(1024, 1024 * 64)];
            rand.NextBytes(bodyBuffer);
            ChunkedBuffer body = new ChunkedBuffer(pool);

            body.OfferRaw(bodyBuffer, 0, bodyBuffer.Length);

            GdsFrame frame = GdsFrame.NewContentFrame(streamId, null, false, body, true);

            Assert.AreEqual(true, frame.IsComplete);
            Assert.AreEqual(GdsFrame.GdsFrameType.BodyOnly, frame.Type);
            Assert.AreEqual(streamId, frame.StreamId);
            Assert.AreEqual(0, frame.Headers.Count);

            MemoryStream stream = new MemoryStream();

            frame.Write(stream);

            Assert.AreEqual(
                4           // frame definition
                + 4         // body definition
                + bodyBuffer.Length
                , stream.Position);

            stream.Position = 0;

            GdsFrame readFrame = GdsFrame.ParseFrame(stream, pool);

            Assert.AreEqual(true, readFrame.IsComplete);
            Assert.AreEqual(GdsFrame.GdsFrameType.BodyOnly, readFrame.Type);
            Assert.AreEqual(streamId, readFrame.StreamId);
            Assert.AreEqual(0, readFrame.Headers.Count);

            byte[] readBodyBuffer = new byte[readFrame.Body.AvailableBytesToRead];
            readFrame.Body.Read(readBodyBuffer, 0, readBodyBuffer.Length);

            AssertEquals(bodyBuffer, readBodyBuffer);

            frame.Dispose();
            readFrame.Dispose();
        }
Exemplo n.º 15
0
            /// <summary>
            /// Handles an outgoing HttpRequest and converts it to a raw buffer.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleOutgoing(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is GdsFrame))
                {
                    return;
                }

                GdsFrame      gdsFrame = (GdsFrame)obj;
                ChunkedBuffer buffer   = new ChunkedBuffer(channel.BufferPool);

                gdsFrame.Write(buffer.Stream);

                gdsFrame.Dispose();

                obj = buffer;
            }
Exemplo n.º 16
0
            public void Start(bool isTls = false, string body = "")
            {
                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"
                        };

                        response.Body = ChunkedBuffer.Wrap(body, Encoding.UTF8);

                        response.Header["Content-Length"] = "" + response.BodySize;

                        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();
                }
            }
Exemplo n.º 17
0
        public void TestContentLengthPartial()
        {
            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;

            int    partialSize    = sampleRequest.Length / 3;
            string sampleRequest1 = sampleRequest.Substring(0, partialSize);
            string sampleRequest2 = sampleRequest.Substring(partialSize, partialSize);
            string sampleRequest3 = sampleRequest.Substring(partialSize * 2, sampleRequest.Length - (partialSize * 2));

            ChunkedBuffer buffer = new ChunkedBuffer(pool);

            buffer.Write(Encoding.ASCII.GetBytes(sampleRequest1), 0, Encoding.ASCII.GetByteCount(sampleRequest1));

            HttpResponse response = new HttpResponse(pool);

            Assert.IsFalse(response.Parse(buffer.Stream, false));

            buffer.Write(Encoding.ASCII.GetBytes(sampleRequest2), 0, Encoding.ASCII.GetByteCount(sampleRequest2));
            Assert.IsFalse(response.Parse(buffer.Stream, false));

            buffer.Write(Encoding.ASCII.GetBytes(sampleRequest3), 0, Encoding.ASCII.GetByteCount(sampleRequest3));
            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());
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Creates a base socknet channel given a socket and a buffer pool.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="bufferPool"></param>
        protected BaseSockNetChannel(Socket socket, ObjectPool <byte[]> bufferPool)
        {
            this.Socket = socket;

            if (socket.ProtocolType == ProtocolType.Tcp)
            {
                Protocol = SockNetChannelProtocol.Tcp;
            }
            else if (socket.ProtocolType == ProtocolType.Udp)
            {
                Protocol = SockNetChannelProtocol.Udp;
            }

            this.Pipe = new SockNetChannelPipe(this);

            this.bufferPool    = bufferPool;
            this.chunkedBuffer = new ChunkedBuffer(bufferPool);

            this.stateValues = Enum.GetValues(typeof(S));
        }
        public void TestSimpleSslContent()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            GdsEchoServer server = new GdsEchoServer(pool);

            try
            {
                server.Start(true);

                BlockingCollection <object> blockingCollection = new BlockingCollection <object>();

                ClientSockNetChannel client = (ClientSockNetChannel)SockNetClient.Create(server.Endpoint, ClientSockNetChannel.DefaultNoDelay, ClientSockNetChannel.DefaultTtl, pool)
                                              .AddModule(new GdsSockNetChannelModule(true));

                client.ConnectWithTLS((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => { return(true); })
                .WaitForValue(TimeSpan.FromSeconds(5));

                object currentObject;

                client.Pipe.AddIncomingLast <GdsFrame>((ISockNetChannel sockNetClient, ref GdsFrame data) => { blockingCollection.Add(data); });

                ChunkedBuffer body = new ChunkedBuffer(pool);
                body.OfferRaw(Encoding.UTF8.GetBytes("some test"), 0, Encoding.UTF8.GetByteCount("some test"));

                client.Send(GdsFrame.NewContentFrame(1, null, false, body, true));

                Assert.IsTrue(blockingCollection.TryTake(out currentObject, 5000));
                Assert.IsTrue(currentObject is GdsFrame);

                Assert.AreEqual("some test", ((GdsFrame)currentObject).Body.ToString(Encoding.UTF8));

                Console.WriteLine("Got response: \n" + ((GdsFrame)currentObject).Body);

                client.Disconnect().WaitForValue(TimeSpan.FromSeconds(5));
            }
            finally
            {
                server.Stop();
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Sets the given message to the IPEndpoint.
        /// </summary>
        /// <param name="data"></param>
        public Promise <ISockNetChannel> Send(object data)
        {
            Promise <ISockNetChannel> promise = new Promise <ISockNetChannel>();

            object obj = data;

            try
            {
                Pipe.HandleOutgoingData(ref obj);
            }
            catch (Exception ex)
            {
                SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, ex.Message);
            }
            finally
            {
                if (obj is byte[])
                {
                    byte[] rawSendableData = (byte[])obj;

                    SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, (IsConnectionEncrypted ? "[SSL] " : "") + "Sending [{0}] bytes to [{1}]...", rawSendableData.Length, RemoteEndpoint);

                    EnqueueToSendQueueAndNotify(new ChunkedBuffer(bufferPool).OfferRaw(rawSendableData, 0, rawSendableData.Length), promise);
                }
                else if (obj is ChunkedBuffer)
                {
                    ChunkedBuffer sendableStream = ((ChunkedBuffer)obj);

                    SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, (IsConnectionEncrypted ? "[SSL] " : "") + "Sending [{0}] bytes to [{1}]...", sendableStream.AvailableBytesToRead, RemoteEndpoint);

                    EnqueueToSendQueueAndNotify(sendableStream, promise);
                }
                else
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to send object: {0}", obj);
                }
            }
            return(promise);
        }
            /// <summary>
            /// Handles an outgoing HttpRequest and converts it to a raw buffer.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            private void HandleOutgoingRequest(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is HttpRequest))
                {
                    return;
                }

                HttpRequest data = (HttpRequest)obj;

                if (SockNetLogger.DebugEnabled)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Sending HTTP Request: Command Line: [{0}], Body Size [{1}]", data.CommandLine, data.BodySize);
                }

                ChunkedBuffer buffer = new ChunkedBuffer(channel.BufferPool);

                data.Write(buffer.Stream);

                data.Dispose();

                obj = buffer;
            }
Exemplo n.º 22
0
            public void Start(bool isTls = false)
            {
                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 chunk1HttpContent = "HTTP/1.0 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n" + string.Format("{0:X}", chunk1ContentLength) + "\r\n" + chunk1Content + "\r\n";
                string chunk2HttpContent = string.Format("{0:X}", chunk2ContentLength) + "\r\n" + chunk2Content + "\r\n";
                string chunk3HttpContent = string.Format("{0:X}", chunk3ContentLength) + "\r\n" + chunk3Content + "\r\n";
                string chunk4HttpContent = "0\r\n\r\n";

                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) =>
                    {
                        ChunkedBuffer buffer1 = new ChunkedBuffer(channel.BufferPool);
                        buffer1.Write(Encoding.ASCII.GetBytes(chunk1HttpContent), 0, Encoding.ASCII.GetByteCount(chunk1HttpContent));
                        channel.Send(buffer1);

                        ChunkedBuffer buffer2 = new ChunkedBuffer(channel.BufferPool);
                        buffer2.Write(Encoding.ASCII.GetBytes(chunk2HttpContent), 0, Encoding.ASCII.GetByteCount(chunk2HttpContent));
                        channel.Send(buffer2);

                        ChunkedBuffer buffer3 = new ChunkedBuffer(channel.BufferPool);
                        buffer3.Write(Encoding.ASCII.GetBytes(chunk3HttpContent), 0, Encoding.ASCII.GetByteCount(chunk3HttpContent));
                        channel.Send(buffer3);

                        ChunkedBuffer buffer4 = new ChunkedBuffer(channel.BufferPool);
                        buffer4.Write(Encoding.ASCII.GetBytes(chunk4HttpContent), 0, Encoding.ASCII.GetByteCount(chunk4HttpContent));
                        channel.Send(buffer4);
                    });

                    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 TestChunks()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            DummySockNetChannel channel = new DummySockNetChannel()
            {
                State      = null,
                IsActive   = true,
                BufferPool = pool
            };

            channel.Pipe = new SockNetChannelPipe(channel);

            GdsSockNetChannelModule module = new GdsSockNetChannelModule(true);

            channel.AddModule(module);
            channel.Connect();

            uint streamId = 1;

            ChunkedBuffer body = new ChunkedBuffer(pool);

            body.OfferRaw(Encoding.UTF8.GetBytes("This "), 0, Encoding.UTF8.GetByteCount("This "));

            GdsFrame chunk1 = GdsFrame.NewContentFrame(streamId, new Dictionary <string, byte[]>()
            {
                { "test1", new byte[] { 1 } },
                { "test", new byte[] { 1 } },
            },
                                                       false, body, false);
            ChunkedBuffer buffer          = ToBuffer(chunk1);
            object        receiveResponse = buffer;

            channel.Receive(ref receiveResponse);
            buffer.Close();

            Assert.IsTrue(receiveResponse is ChunkedBuffer);

            body = new ChunkedBuffer(pool);
            body.OfferRaw(Encoding.UTF8.GetBytes("is "), 0, Encoding.UTF8.GetByteCount("is "));

            GdsFrame chunk2 = GdsFrame.NewContentFrame(streamId, new Dictionary <string, byte[]>()
            {
                { "test2", new byte[] { 2 } },
                { "test", new byte[] { 2 } },
            },
                                                       false, body, false);

            buffer          = ToBuffer(chunk2);
            receiveResponse = buffer;
            channel.Receive(ref receiveResponse);
            buffer.Close();

            Assert.IsTrue(receiveResponse is ChunkedBuffer);

            body = new ChunkedBuffer(pool);
            body.OfferRaw(Encoding.UTF8.GetBytes("awesome!"), 0, Encoding.UTF8.GetByteCount("awesome!"));

            GdsFrame chunk3 = GdsFrame.NewContentFrame(streamId, new Dictionary <string, byte[]>()
            {
                { "test3", new byte[] { 3 } },
                { "test", new byte[] { 3 } },
            },
                                                       false, body, true);

            buffer          = ToBuffer(chunk3);
            receiveResponse = buffer;
            channel.Receive(ref receiveResponse);
            buffer.Close();

            Assert.IsTrue(receiveResponse is GdsFrame);
            Assert.AreEqual("This is awesome!", ((GdsFrame)receiveResponse).Body.ToString(Encoding.UTF8));
            Assert.AreEqual(1, ((GdsFrame)receiveResponse).Headers["test1"][0]);
            Assert.AreEqual(2, ((GdsFrame)receiveResponse).Headers["test2"][0]);
            Assert.AreEqual(3, ((GdsFrame)receiveResponse).Headers["test3"][0]);
            Assert.AreEqual(3, ((GdsFrame)receiveResponse).Headers["test"][0]);

            body.Dispose();
            chunk1.Dispose();
            chunk2.Dispose();
            chunk3.Dispose();

            Console.WriteLine("Pool stats: " + pool.ObjectsInPool + "/" + pool.TotalNumberOfObjects);
        }
Exemplo n.º 24
0
        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 = "POST / HTTP/1.0\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));

            HttpRequest request = new HttpRequest(pool);

            Assert.IsFalse(request.IsChunked);
            Assert.IsFalse(request.Parse(buffer1.Stream, false));
            Assert.IsTrue(request.IsChunked);
            Assert.IsFalse(request.Parse(buffer2.Stream, false));
            Assert.IsTrue(request.IsChunked);
            Assert.IsFalse(request.Parse(buffer3.Stream, false));
            Assert.IsTrue(request.IsChunked);
            Assert.IsTrue(request.Parse(buffer4.Stream, false));
            Assert.IsTrue(request.IsChunked);

            Assert.AreEqual("POST", request.Action);
            Assert.AreEqual("/", request.Path);
            Assert.AreEqual("HTTP/1.0", request.Version);
            Assert.AreEqual("POST / HTTP/1.0", request.CommandLine);
            Assert.AreEqual("localhost", request.Header["Host"]);
            Assert.AreEqual(sampleContentLength, request.BodySize);
            Assert.AreEqual(sampleContentLength, request.Body.WritePosition);

            MemoryStream stream = new MemoryStream();

            request.Write(stream, false);
            stream.Position = 0;

            using (StreamReader reader = new StreamReader(stream))
            {
                Assert.AreEqual("POST / HTTP/1.0\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n" + sampleContent, reader.ReadToEnd());
            }

            buffer1.Dispose();
            buffer2.Dispose();
            buffer3.Dispose();
            buffer4.Dispose();
            request.Dispose();
        }
        public void TestContinuation()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            DummySockNetChannel channel = new DummySockNetChannel()
            {
                State      = null,
                IsActive   = true,
                BufferPool = pool
            };

            channel.Pipe = new SockNetChannelPipe(channel);

            WebSocketClientSockNetChannelModule module = new WebSocketClientSockNetChannelModule("/test", "test", null);

            channel.AddModule(module);
            channel.Connect();

            object sent = null;

            channel.outgoing.TryTake(out sent, 5000);
            Assert.IsTrue(sent is HttpRequest);

            HttpRequest request = (HttpRequest)sent;

            HttpResponse handshakeResponse = new HttpResponse(channel.BufferPool)
            {
                Code = "200", Reason = "OK", Version = "HTTP/1.1"
            };

            handshakeResponse.Header[WebSocketUtil.WebSocketAcceptHeader] = WebSocketUtil.GenerateAccept(request.Header[WebSocketUtil.WebSocketKeyHeader]);
            object receiveResponse = handshakeResponse;

            channel.Receive(ref receiveResponse);

            WebSocketFrame continuation1 = WebSocketFrame.CreateTextFrame("This ", false, false, false);
            ChunkedBuffer  buffer        = ToBuffer(continuation1);

            receiveResponse = buffer;
            channel.Receive(ref receiveResponse);
            buffer.Close();

            Assert.IsTrue(receiveResponse is ChunkedBuffer);

            WebSocketFrame continuation2 = WebSocketFrame.CreateTextFrame("is ", false, true, false);

            buffer          = ToBuffer(continuation2);
            receiveResponse = buffer;
            channel.Receive(ref receiveResponse);
            buffer.Close();

            Assert.IsTrue(receiveResponse is ChunkedBuffer);

            WebSocketFrame continuation3 = WebSocketFrame.CreateTextFrame("awesome!", false, true, true);

            buffer          = ToBuffer(continuation3);
            receiveResponse = buffer;
            channel.Receive(ref receiveResponse);
            buffer.Close();

            Assert.IsTrue(receiveResponse is WebSocketFrame);
            Assert.AreEqual("This is awesome!", ((WebSocketFrame)receiveResponse).DataAsString);

            Console.WriteLine("Pool stats: " + pool.ObjectsInPool + "/" + pool.TotalNumberOfObjects);
        }
        public void TestLargeMessage()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            DummySockNetChannel channel = new DummySockNetChannel()
            {
                State      = null,
                IsActive   = true,
                BufferPool = pool
            };

            channel.Pipe = new SockNetChannelPipe(channel);

            WebSocketClientSockNetChannelModule module = new WebSocketClientSockNetChannelModule("/test", "test", null);

            channel.AddModule(module);
            channel.Connect();

            object sent = null;

            channel.outgoing.TryTake(out sent, 5000);
            Assert.IsTrue(sent is HttpRequest);

            HttpResponse handshakeResponse = null;

            using (HttpRequest request = (HttpRequest)sent)
            {
                handshakeResponse = new HttpResponse(null)
                {
                    Code = "200", Reason = "OK", Version = "HTTP/1.1"
                };
                handshakeResponse.Header[WebSocketUtil.WebSocketAcceptHeader] = WebSocketUtil.GenerateAccept(request.Header[WebSocketUtil.WebSocketKeyHeader]);
            }

            object receiveResponse = handshakeResponse;

            channel.Receive(ref receiveResponse);

            Random random = new Random(this.GetHashCode() ^ (int)DateTime.Now.Subtract(new DateTime(2000, 1, 1)).TotalMilliseconds);

            for (int n = 0; n < 100; n++)
            {
                byte[] data = new byte[random.Next(50000, 150000)];
                random.NextBytes(data);

                WebSocketFrame frame = WebSocketFrame.CreateBinaryFrame(data, false);
                using (ChunkedBuffer buffer = ToBuffer(frame))
                {
                    receiveResponse = buffer;
                    channel.Receive(ref receiveResponse);

                    Assert.IsTrue(receiveResponse is WebSocketFrame);
                    Assert.AreEqual(data.Length, ((WebSocketFrame)receiveResponse).Data.Length);
                    for (int i = 0; i < data.Length; i++)
                    {
                        Assert.AreEqual(data[i], ((WebSocketFrame)receiveResponse).Data[i]);
                    }
                    buffer.Close();
                }
            }

            Console.WriteLine("Pool stats: " + pool.ObjectsInPool + "/" + pool.TotalNumberOfObjects);
        }
Exemplo n.º 27
0
        /// <summary>
        /// Creates a new content frame where the frame is a headers only, body only, or a full frame.
        /// </summary>
        /// <param name="streamId"></param>
        /// <param name="headers"></param>
        /// <param name="areHeadersCompressed"></param>
        /// <param name="body"></param>
        /// <param name="isComplete"></param>
        /// <returns></returns>
        public static GdsFrame NewContentFrame(uint streamId, Dictionary <string, byte[]> headers = null, bool areHeadersCompressed = false, ChunkedBuffer body = null, bool isComplete = true)
        {
            GdsFrameType type = GdsFrameType.Full;

            if (body == null)
            {
                type = GdsFrameType.HeadersOnly;
            }
            else if (headers == null)
            {
                type = GdsFrameType.BodyOnly;
            }

            GdsFrame frame = new GdsFrame(null)
            {
                IsComplete           = isComplete,
                Type                 = type,
                StreamId             = streamId,
                AreHeadersCompressed = areHeadersCompressed
            };

            if (headers != null)
            {
                foreach (KeyValuePair <string, byte[]> kvp in headers)
                {
                    frame.Headers[kvp.Key] = kvp.Value;
                }
            }

            if (body != null)
            {
                frame.Body = body;
            }

            return(frame);
        }