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); }