Exemple #1
0
        public bool Proccess(ref ServerAsyncEventArgs e, out bool closeConnection)
        {
            //  ----------------------------------------------------------
            //  |           | 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  |
            //  ----------------------------------------------------------
            //  |         e | H  | HC |    |    |    |    |    |    |    |
            //  |        e1 |    |    | H  | HC | H  | H  |    |    |    |
            //  |   Buffer1 |    |    |    |    |  C |    | H  | HC | H  |
            //  |   Buffer2 |    |    |    |    |    |  C |    |    |  C |
            //  ----------------------------------------------------------

            closeConnection = false;

            switch (state)
            {
            case StreamState.WaitingHeaders:
            {
                int oldBytesProccessed = bytesProccessed;

                var data = new ArraySegment <byte>(e.Buffer, e.Offset + bytesProccessed, e.BytesTransferred - bytesProccessed);

                PreProcessRaw(data);
                var result = Parse(data);

                switch (result.ParseCode)
                {
                case ParseCode.NotEnoughData:
                {
                    bytesProccessed += data.Count;

                    ResetParser(ResetReason.NotEnoughData);

                    Buffer1.Resize(MaximumHeadersSize);
                    Buffer1.CopyTransferredFrom(e, oldBytesProccessed);
                    state = StreamState.WaitingHeadersContinue;
                }
                break;

                case ParseCode.Error:
                {
                    closeConnection = true;
                }
                break;

                case ParseCode.Skip:
                {
                    bytesProccessed += result.Count;
                }
                break;

                case ParseCode.HeaderDone:
                {
                    bytesProccessed += result.HeaderLength;

                    SetReaderStorage(Storage.E, e.Buffer, e.Offset + oldBytesProccessed, result.HeaderLength);

                    expectedContentLength = result.ContentLength;

                    if (expectedContentLength <= 0)
                    {
                        SetReady();
                    }
                    else
                    {
                        int bytesLeft = e.BytesTransferred - bytesProccessed;

                        if (bytesLeft >= expectedContentLength)
                        {
                            SetReady(Storage.E, e.Buffer, e.Offset + bytesProccessed, expectedContentLength);
                            bytesProccessed += expectedContentLength;
                        }
                        else
                        {
                            if (expectedContentLength <= e.Count - e.BytesTransferred)
                            {
                                state = StreamState.WaitingMicroBody;
                            }
                            else if (expectedContentLength < MaximumHeadersSize)
                            {
                                if (Buffer1.IsInvalid || Buffer1.Capacity < expectedContentLength)
                                {
                                    if (Buffer1.Resize(Math.Max(expectedContentLength, MinimumBuffer1Size)) == false)
                                    {
                                        closeConnection = true;
                                    }
                                }

                                if (closeConnection == false)
                                {
                                    Buffer1.CopyTransferredFrom(e, bytesProccessed);
                                    state = StreamState.WaitingSmallBody;
                                }
                            }
                            else
                            {
                                if (Buffer2.Resize(expectedContentLength) == false)
                                {
                                    closeConnection = true;
                                }
                                else
                                {
                                    Buffer2.CopyTransferredFrom(e, bytesProccessed);
                                    state = StreamState.WaitingBigBody;
                                }
                            }

                            if (closeConnection == false)
                            {
                                e1            = e;
                                e             = null;
                                readerStorage = Storage.E1;
                            }

                            bytesProccessed       += bytesLeft;
                            receivedContentLength += bytesLeft;
                        }
                    }
                }
                break;
                }
            }
            break;

            case StreamState.WaitingHeadersContinue:
            {
                int count = Math.Min(e.BytesTransferred - bytesProccessed, Buffer1.FreeSize);

                PreProcessRaw(new ArraySegment <byte>(e.Buffer, e.Offset, e.BytesTransferred - bytesProccessed));

                System.Buffer.BlockCopy(e.Buffer, e.Offset, Buffer1.Array, Buffer1.Offset + Buffer1.Count, count);

                var data   = new ArraySegment <byte>(Buffer1.Array, Buffer1.Offset, Buffer1.Count + count);
                var result = Parse(data);

                switch (result.ParseCode)
                {
                case ParseCode.NotEnoughData:
                {
                    ResetParser(ResetReason.NotEnoughData);

                    if (data.Count < Buffer1.Capacity)
                    {
                        Buffer1.AddCount(count);
                        bytesProccessed += count;
                    }
                    else
                    {
                        closeConnection = true;
                    }
                }
                break;

                case ParseCode.Error:
                {
                    closeConnection = true;
                }
                break;

                case ParseCode.Skip:
                    throw new NotImplementedException();

                case ParseCode.HeaderDone:
                {
                    int delta = result.HeaderLength - Buffer1.Count;
                    Buffer1.AddCount(delta);
                    bytesProccessed += delta;

                    SetReaderStorage(Storage.Buffer1, Buffer1.Array, Buffer1.Offset, result.HeaderLength);

                    expectedContentLength = result.ContentLength;

                    if (expectedContentLength <= 0)
                    {
                        SetReady();
                    }
                    else
                    {
                        int bytesLeft = e.BytesTransferred - bytesProccessed;

                        if (bytesLeft >= expectedContentLength)
                        {
                            SetReady(Storage.E, e.Buffer, e.Offset + bytesProccessed, expectedContentLength);
                            bytesProccessed += expectedContentLength;
                        }
                        else
                        {
                            if (expectedContentLength < Buffer1.FreeSize)
                            {
                                Buffer1.AddCount(bytesLeft);
                                state = StreamState.WaitingSmallBody;
                            }
                            else
                            {
                                if (Buffer2.Resize(expectedContentLength) == false)
                                {
                                    closeConnection = true;
                                }
                                Buffer2.CopyTransferredFrom(e, bytesProccessed);
                                state = StreamState.WaitingBigBody;
                            }

                            bytesProccessed       += bytesLeft;
                            receivedContentLength += bytesLeft;
                        }
                    }
                }
                break;
                }
            }
            break;

            case StreamState.WaitingMicroBody:
            {
                int count = Math.Min(e.BytesTransferred - bytesProccessed,
                                     expectedContentLength - receivedContentLength);

                var data = new ArraySegment <byte>(e.Buffer, e.Offset + bytesProccessed, count);

                PreProcessRaw(data);
                System.Buffer.BlockCopy(data.Array, data.Offset, e1.Buffer, e1.Offset + e1.BytesTransferred, data.Count);

                //System.Buffer.BlockCopy(e.Buffer, e.Offset + bytesProccessed,
                //    e1.Buffer, e1.Offset + e1.BytesTransferred, count);

                e1.BytesTransferred += count;

                receivedContentLength += count;
                bytesProccessed       += count;

                if (receivedContentLength == expectedContentLength)
                {
                    SetReady(Storage.E1, e1.Buffer, e1.Offset + e1.BytesTransferred - receivedContentLength, receivedContentLength);
                }
            }
            break;

            case StreamState.WaitingSmallBody:
            {
                int count = Math.Min(e.BytesTransferred - bytesProccessed,
                                     expectedContentLength - receivedContentLength);

                var data = new ArraySegment <byte>(e.Buffer, e.Offset + bytesProccessed, count);

                PreProcessRaw(data);
                Buffer1.CopyFrom(data);
                //Buffer1.CopyFrom(e.Buffer, e.Offset + bytesProccessed, count);

                receivedContentLength += count;
                bytesProccessed       += count;

                if (receivedContentLength == expectedContentLength)
                {
                    SetReady(Storage.Buffer1, Buffer1.Array, Buffer1.Offset + Buffer1.Count - receivedContentLength, receivedContentLength);
                }
            }
            break;

            case StreamState.WaitingBigBody:
            {
                int count = Math.Min(e.BytesTransferred - bytesProccessed,
                                     expectedContentLength - receivedContentLength);

                var data = new ArraySegment <byte>(e.Buffer, e.Offset + bytesProccessed, count);

                PreProcessRaw(data);
                Buffer2.CopyFrom(data);
                //Buffer2.CopyFrom(e.Buffer, e.Offset + bytesProccessed, count);

                receivedContentLength += count;
                bytesProccessed       += count;

                if (receivedContentLength == expectedContentLength)
                {
                    SetReady(Storage.Buffer2, Buffer2.Array, Buffer2.Offset + Buffer2.Count - receivedContentLength, receivedContentLength);
                }
            }
            break;
            }

            bool continueProccessing = closeConnection == false &&
                                       e != null && bytesProccessed < e.BytesTransferred;

            if (continueProccessing == false)
            {
                bytesProccessed = 0;
            }

            return(continueProccessing);
        }