public override void Parse() { try { MimeReaderState state = MimeReaderState.ReadingHeaders; MimeHeaderReader headerReader = new MimeHeaderReader(_encoding); // Read the first chunk int read = _stream.Read(_buffer, 0, _buffer.Length); // Skip past the first boundary int position = IndexOf(0, read) + _boundary.Length; // If the end is here, we're done (empty request) if (_encoding.GetString(_buffer, position, 2) == "--" && (char)_buffer[position + 3] == '\r' || (char)_buffer[position + 3] == '\n') { return; } // Skip past the end line if ((char)_buffer[position] == '\r') { position += 2; } else if ((char)_buffer[position] == '\n') { position += 1; } int zeroReads = 0; while (state != MimeReaderState.Finished) { switch (state) { case MimeReaderState.ReadingHeaders: position += headerReader.Read(_buffer, position); if (headerReader.HeaderComplete) { state = MimeReaderState.ReadingBody; _handler.BeginPart(headerReader.Headers); headerReader.Reset(); } break; case MimeReaderState.ReadingBody: int boundaryPos = IndexOf(position, read); // If block ends with \r or \n or a combo, consider that a boundary start if (boundaryPos == -1) { if (read > 1 && _buffer[read - 2] == '\r') { boundaryPos = read - 2; } else if (read > 0 && (_buffer[read - 1] == '\r' || _buffer[read - 1] == '\n')) { boundaryPos = read - 1; } } // If boundary not found if (boundaryPos == -1) { _handler.PartData(ref _buffer, position, read - position); position += read - position; } else { int actualLength; actualLength = boundaryPos - position; if (actualLength >= 2) { if ((char)_buffer[boundaryPos - 2] == '\r') { actualLength -= 2; } else if ((char)_buffer[boundaryPos - 2] == '\n') { actualLength -= 1; } } _handler.PartData(ref _buffer, position, actualLength); // Check for end if (boundaryPos <= read - (_boundary.Length + 2)) { // Check for "--" which means last part bool isLast = (_encoding.GetString(_buffer, boundaryPos + _boundary.Length, 2) == "--"); if (isLast) { state = MimeReaderState.Finished; } else { state = MimeReaderState.ReadingHeaders; } _handler.EndPart(isLast, true); position += (boundaryPos + _boundary.Length - position + 2); } // Boundary laps over else { // Also take the possible cr/lf combo removed above boundaryPos -= ((boundaryPos - position) - actualLength); int boundaryFragmentLength = read - boundaryPos; // Move the boundary data to the front of the buffer Buffer.BlockCopy(_buffer, boundaryPos, _buffer, 0, boundaryFragmentLength); // Load in more data read = _stream.Read(_buffer, boundaryFragmentLength, _buffer.Length - boundaryFragmentLength); // Reset position position = 0; // Adjust read count because of existing data in buffer read += boundaryFragmentLength; } } break; } // Get more data if we need it if (state != MimeReaderState.Finished) { if (position >= read) { read = _stream.Read(_buffer, 0, _buffer.Length); position = 0; if (read == 0) { if (zeroReads == 10) { throw new UploadDisconnectedException(); } zeroReads++; System.Threading.Thread.Sleep(100); } else { zeroReads = 0; } } } } } catch (UploadCancelledException) { throw; } catch { _handler.EndPart(false, false); throw; } }
public void Parse() { MimeReaderState readingHeaders = MimeReaderState.ReadingHeaders; MimeHeaderReader reader = new MimeHeaderReader(this.encoding); byte[] buffer = new byte[0x2000]; int end = this.stream.Read(buffer, 0, 0x2000); int index = this.IndexOf(buffer, this.boundary, 0, end) + this.boundary.Length; if (buffer[index] == 13) { index += 2; } else if (buffer[index] == 10) { index++; } while ((end > 0) && (readingHeaders != MimeReaderState.Finished)) { int num4; int num5; switch (readingHeaders) { case MimeReaderState.ReadingHeaders: { int num3 = reader.Read(buffer, index); index += num3; if (reader.HeaderComplete) { readingHeaders = MimeReaderState.ReadingBody; this.handler.BeginPart(reader.Headers); reader.Reset(); } goto Label_0299; } case MimeReaderState.ReadingBody: num4 = this.IndexOf(buffer, this.boundary, index, end); if (num4 != -1) { goto Label_0124; } if (index != 0) { break; } this.handler.PartData(ref buffer); goto Label_0116; case MimeReaderState.CheckingEnd: if (!(this.encoding.GetString(buffer, 0, 2) == "--")) { goto Label_0282; } readingHeaders = MimeReaderState.Finished; goto Label_028A; default: goto Label_0299; } byte[] dst = new byte[end - index]; Buffer.BlockCopy(buffer, index, dst, 0, dst.Length); this.handler.PartData(ref dst); Label_0116: index += end - index; goto Label_0299; Label_0124: num5 = num4 - index; if (buffer[num4 - 2] == 13) { num5 -= 2; } else if (buffer[num4 - 2] == 10) { num5--; } byte[] buffer3 = new byte[num5]; Buffer.BlockCopy(buffer, index, buffer3, 0, buffer3.Length); this.handler.PartData(ref buffer3); if (num4 < (buffer.Length - this.boundary.Length)) { if (num4 < (buffer.Length - (this.boundary.Length + 2))) { bool isLast = this.encoding.GetString(buffer, num4 + this.boundary.Length, 2) == "--"; if (isLast) { readingHeaders = MimeReaderState.Finished; } else { readingHeaders = MimeReaderState.ReadingHeaders; } this.handler.EndPart(isLast); index += ((num4 + this.boundary.Length) - index) + 2; } else { readingHeaders = MimeReaderState.CheckingEnd; if (((num4 + 2) - buffer.Length) == 1) { num4 = 1; buffer[0] = buffer[buffer.Length - 1]; } else { num4 = 0; } end = this.stream.Read(buffer, num4, buffer.Length - num4); index = 0; } } else { num4 -= (num4 - index) - num5; Buffer.BlockCopy(buffer, num4, buffer, 0, buffer.Length - num4); end = this.stream.Read(buffer, buffer.Length - num4, buffer.Length - (buffer.Length - num4)); index = 0; } goto Label_0299; Label_0282: index += 2; readingHeaders = MimeReaderState.ReadingHeaders; Label_028A: this.handler.EndPart(readingHeaders == MimeReaderState.Finished); Label_0299: if ((readingHeaders != MimeReaderState.Finished) && ((index >= buffer.Length) || (index >= end))) { end = this.stream.Read(buffer, 0, buffer.Length); index = 0; } } }