示例#1
0
        public override void Write(ResponseHead head)
        {
            ThrowIfEnded();
            StringBuilder builder = new StringBuilder();

            builder.Append(head.Version.ToString() + WHITESPACE + head.StatusCode + WHITESPACE + head.StatusDescription + CRLF);
            foreach (Header header in head.Headers.AsCollection())
            {
                builder.Append(header.Name + COLON + WHITESPACE + header.Value + CRLF);
            }
            builder.Append(CRLF);
            Readable.Write(Encoding.ASCII.GetBytes(builder.ToString()));
        }
        public override void Write(RequestHead head)
        {
            ThrowIfEnded();
            StringBuilder builder = new StringBuilder();

            builder.Append(head.Method + WHITESPACE + head.Query + WHITESPACE + head.Version + CRLF);
            foreach (Header header in head.Headers.AsCollection())
            {
                builder.Append(header.Name + COLON + WHITESPACE + header.Value + CRLF);
            }
            builder.Append(CRLF);
            Readable.Write(Encoding.ASCII.GetBytes(builder.ToString()));
        }
示例#3
0
 internal void WriteIncoming(byte[] data)
 {
     LastActivityTime = DateTime.UtcNow;
     CalledTimeout    = false;
     Readable.Write(data);
 }
示例#4
0
        private int ProcessData(byte[] data, bool writeExcess)
        {
            ThrowIfEnded();
            if (!IsSet)
            {
                throw new InvalidOperationException("Not set");
            }
            int i = 0, len; char c; byte[] sliced;

            for (; i < data.Length;)
            {
                switch (State)
                {
                case BodyParserState.RawRead:
                    len    = ContentLength == -1 ? data.Length - i : Math.Min(data.Length - i, ContentLength - CurrentReadBytes);
                    sliced = new byte[len];
                    Buffer.BlockCopy(data, i, sliced, 0, len);
                    i += len;
                    CurrentReadBytes += len;
                    ContentTransform.Write(data);
                    if (ContentTransform.Buffered > 0)
                    {
                        Readable.Write(ContentTransform.Read());
                    }
                    if (CurrentReadBytes == ContentLength)
                    {
                        State = BodyParserState.Dormant;
                        OnEnd?.Invoke();
                        break;
                    }
                    break;

                case BodyParserState.Chunked_Length:
                    c = (char)data[i++];
                    if (c != CR)
                    {
                        StringQueue.Append(c);
                    }
                    else
                    {
                        if (!int.TryParse(StringQueue.Next(), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out int result))
                        {
                            End(); return(-1);
                        }
                        chunkLen = result;
                        State    = BodyParserState.Chunked_LenLf;
                    }
                    break;

                case BodyParserState.Chunked_LenLf:
                    c = (char)data[i++];
                    if (c != LF)
                    {
                        End(); return(-1);
                    }
                    if (chunkLen == 0)
                    {
                        State = BodyParserState.Chunked_Trailer;
                    }
                    else
                    {
                        State = BodyParserState.Chunked_ChunkData;
                    }
                    break;

                case BodyParserState.Chunked_ChunkData:
                    len    = Math.Min(data.Length - i, chunkLen - chunkIndex);
                    sliced = new byte[len];
                    Buffer.BlockCopy(data, i, sliced, 0, len);
                    i += len;
                    CurrentReadBytes += len;
                    chunkIndex       += len;
                    ContentTransform.Write(sliced);
                    Readable.Write(ContentTransform.Read());
                    if (chunkLen == chunkIndex)
                    {
                        State = BodyParserState.Chunked_ChunkCr;
                    }
                    break;

                case BodyParserState.Chunked_ChunkCr:
                    c = (char)data[i++];
                    if (c != CR)
                    {
                        End(); return(-1);
                    }
                    State = BodyParserState.Chunked_ChunkLf;
                    break;

                case BodyParserState.Chunked_ChunkLf:
                    c = (char)data[i++];
                    if (c != LF)
                    {
                        End(); return(-1);
                    }
                    State    = BodyParserState.Chunked_Length;
                    chunkLen = chunkIndex = 0;
                    StringQueue.New();
                    break;

                case BodyParserState.Chunked_Trailer:
                    c = (char)data[i++];
                    if (c != CR)
                    {
                        chunkIndex++;
                    }
                    else
                    {
                        if (chunkIndex == 0)
                        {
                            State = BodyParserState.Chunked_Lf;
                        }
                        else
                        {
                            chunkIndex = -1;      // LF will be added
                        }
                    }
                    break;

                case BodyParserState.Chunked_Lf:
                    c = (char)data[i++];
                    if (c != LF)
                    {
                        End(); return(-1);
                    }
                    State = BodyParserState.Dormant;
                    OnEnd?.Invoke();
                    ContentLength = CurrentReadBytes;
                    break;

                default: throw new InvalidOperationException("ProcessData cannot execute on Dormant state");
                }
            }
            if (writeExcess)
            {
                len    = data.Length - i;
                sliced = new byte[len];
                Buffer.BlockCopy(data, i, sliced, 0, len);
                Writable.Write(sliced);
            }
            return(i);
        }