public void basic_response()
        {
            var frame    = new HttpResponse(404, "Failed to find it dude", "HTTP/1.1");
            var expected = "HTTP/1.1 404 Failed to find it dude\r\n";
            var buffer   = new SocketBufferFake();

            var encoder = new HttpMessageEncoder();

            encoder.Prepare(frame);
            encoder.Send(buffer);
            var actual = Encoding.ASCII.GetString(buffer.Buffer, 0, buffer.Count);

            actual.Substring(0, expected.Length).Should().Be(expected);
        }
        public void request_in_its_simplest_form()
        {
            var frame    = new HttpRequest("POST", "/", "HTTP/1.1");
            var expected = "POST / HTTP/1.1\r\nContent-Length: 0\r\n\r\n";
            var buffer   = new SocketBufferFake();

            var encoder = new HttpMessageEncoder();

            encoder.Prepare(frame);
            encoder.Send(buffer);
            var actual = Encoding.ASCII.GetString(buffer.Buffer, 0, buffer.Count);

            actual.Should().Be(expected);
        }
        public void response_with_body()
        {
            var frame = new HttpResponse(HttpStatusCode.NotFound, "Failed to find it dude", "HTTP/1.1");

            frame.AddHeader("X-Requested-With", "XHttpRequest");
            frame.ContentType = "text/plain";
            frame.Body        = new MemoryStream(Encoding.ASCII.GetBytes("hello queue a"));
            var expected = string.Format("HTTP/1.1 404 Failed to find it dude\r\nServer: griffinframework.net\r\nDate: {0}\r\nContent-Type: text/plain\r\nX-Requested-With: XHttpRequest\r\nContent-Length: 13\r\n\r\nhello queue a",
                                         DateTime.UtcNow.ToString("R"));
            var buffer = new SocketBufferFake();

            var encoder = new HttpMessageEncoder();

            encoder.Prepare(frame);
            encoder.Send(buffer);
            var actual = Encoding.ASCII.GetString(buffer.Buffer, 0, buffer.Count);

            actual.Should().Be(expected);
        }
        public void request_with_body()
        {
            var frame = new HttpRequest("POST", "/?abc", "HTTP/1.1");

            frame.AddHeader("server", "Griffin.Networking");
            frame.AddHeader("X-Requested-With", "XHttpRequest");
            frame.ContentType = "text/plain";
            frame.Body        = new MemoryStream(Encoding.ASCII.GetBytes("hello queue a"));
            var expected = "POST /?abc HTTP/1.1\r\nserver: Griffin.Networking\r\nX-Requested-With: XHttpRequest\r\nContent-Type: text/plain\r\nContent-Length: 13\r\n\r\nhello queue a";
            var buffer   = new SocketBufferFake();

            var encoder = new HttpMessageEncoder();

            encoder.Prepare(frame);
            encoder.Send(buffer);
            var actual = Encoding.ASCII.GetString(buffer.Buffer, 0, buffer.Count);

            actual.Should().Be(expected);
        }
        /// <summary>
        ///     Buffer structure used for socket send operations.
        /// </summary>
        /// <param name="buffer">
        ///     Do note that there are not buffer attached to the structure, you have to assign one yourself using
        ///     <see cref="ISocketBuffer.SetBuffer(int,int)" />. This choice was made
        ///     to prevent unnecessary copy operations.
        /// </param>
        public void Send(ISocketBuffer buffer)
        {
            if (_message == null)
            {
                _httpMessageEncoder.Send(buffer);
            }
            else
            {
                // last send operation did not send all bytes enqueued in the buffer
                // so let's just continue until doing next message
                if (_bytesToSend > 0)
                {
                    buffer.SetBuffer(_buffer, _offset, _bytesToSend);
                    return;
                }

                var offset      = (int)_message.Payload.Position;
                var length      = (int)_message.Payload.Length;
                var frameLength = length - offset;

                var fin = WebSocketFin.Final;
                if (frameLength > WebSocketFrame.FragmentLength)
                {
                    frameLength = WebSocketFrame.FragmentLength;
                    fin         = WebSocketFin.More;
                }
                var opcode = WebSocketOpcode.Continuation;
                if (offset == 0) // first frame
                {
                    opcode = _message.Opcode;
                }

                var buff = new byte[frameLength];
                _message.Payload.Read(buff, 0, buff.Length);
                var payload = new MemoryStream(buff);

                WebSocketFrame frame = new WebSocketFrame(fin, opcode, (_handshake is IHttpRequest) ? WebSocketMask.Mask : WebSocketMask.Unmask, payload);

                using (var stream = new MemoryStream())
                {
                    var header = (int)frame.Fin;
                    header = (header << 1) + (int)frame.Rsv1;
                    header = (header << 1) + (int)frame.Rsv2;
                    header = (header << 1) + (int)frame.Rsv3;
                    header = (header << 4) + (int)frame.Opcode;
                    header = (header << 1) + (int)frame.Mask;
                    header = (header << 7) + (int)frame.PayloadLength;

                    stream.Write(WebSocketUtils.GetBigEndianBytes((ushort)header), 0, 2);

                    if (frame.PayloadLength > 125)
                    {
                        stream.Write(frame.ExtPayloadLength, 0, frame.ExtPayloadLength.Length);
                    }

                    if (frame.Mask == WebSocketMask.Mask)
                    {
                        stream.Write(frame.MaskingKey, 0, frame.MaskingKey.Length);
                        frame.Unmask();
                    }

                    _totalAmountToSend += (int)stream.Length;

                    if (frame.PayloadLength > 0)
                    {
                        frame.Payload.CopyTo(stream);
                    }

                    buffer.UserToken = _message;

                    _buffer      = stream.ToArray();
                    _bytesToSend = _buffer.Length;

                    buffer.SetBuffer(_buffer, 0, _bytesToSend);
                }
            }
        }