/// <summary>
        /// Process message
        /// </summary>
        /// <param name="context"></param>
        /// <param name="message"></param>
        /// <remarks>
        /// Should always call either <see cref="IPipelineHandlerContext.SendDownstream"/> or <see cref="IPipelineHandlerContext.SendUpstream"/>
        /// unless the handler really wants to stop the processing.
        /// </remarks>
        public void HandleDownstream(IPipelineHandlerContext context, IPipelineMessage message)
        {
            var msg =  message as SendResponse;
            if (msg == null)
            {
                context.SendDownstream(message);
                return;
            }

            var buffer = _bufferPool.PopSlice();
            var stream = new BufferPoolStream(_bufferPool, buffer);
            _encoder.Encode(msg.Response, stream);
            stream.Position = 0;

            // send header
            var header = new byte[6];
            header[0] = 1;
            header[1] = _mapper.GetContentId(msg.Response);
            var lengthBuffer = BitConverter.GetBytes(buffer.Count);
            Buffer.BlockCopy(lengthBuffer, 0, header, 2, lengthBuffer.Length);
            context.SendDownstream(new SendBuffer(header, 0, 6));

            // send body
            context.SendDownstream(new SendStream(stream));
        }
        /// <summary>
        /// Send all headers to the client
        /// </summary>
        /// <param name="response">Response containing call headers.</param>
        public Stream SerializeHeaders(IResponse response)
        {
            var stream = new BufferPoolStream(_pool, _pool.PopSlice());
            var writer = new StreamWriter(stream);

            writer.WriteLine("{0} {1} {2}", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription);

            var contentType = response.ContentType ?? "text/html";
            if (response.ContentEncoding != null)
                contentType += ";charset=" + response.ContentEncoding.WebName;

            // go through all property headers.
            writer.WriteLine("Content-Type: {0}", contentType);
            writer.WriteLine("Content-Length: {0}", response.ContentLength);
            //writer.WriteLine(response.KeepAlive ? "Connection: Keep-Alive" : "Connection: Close");

            if (response.Cookies != null && response.Cookies.Count > 0)
            {
                SerializeCookies(response, writer);
            }

            foreach (var header in response.Headers)
                writer.WriteLine("{0}: {1}", header.Name, header.Value);

            writer.WriteLine();
            writer.Flush();
            return stream;
        }
 public void PartialBuffeR()
 {
     var buffer = new byte[512];
     var stream = new BufferPoolStream(new BufferSlice(buffer, 256, 256, 0));
 }
        private void HandleHeader(IPipelineHandlerContext context, IPipelineMessage message, ReceivedHeader headerMsg)
        {
            _packetType = _mapper.GetPacketType(_header.ContentId);
            if (_packetType == null)
            {
                // not supported, let the rest of the pipeline
                // handle the packet.
                context.SendUpstream(message);
            }
            else
            {
                _header = headerMsg.Header;
                var buffer = _bufferPool.PopSlice();
                if (_header.ContentLength > buffer.Capacity)
                    throw new InvalidOperationException(
                        string.Format(
                            "Buffer ({0} bytes) is less than the packet content ({1} bytes). Sorry, that's not possible in the current version.",
                            buffer.Capacity, _header.ContentLength));

                _bytesLeft = _header.ContentLength;
                _stream = new BufferPoolStream(_bufferPool, buffer);
            }
        }
 private void Clear()
 {
     _stream.Dispose();
     _stream = null;
     _packetType = null;
     _header = null;
 }