private static void MultipartWriteSegmentAsyncComplete(IAsyncResult result) { Contract.Assert(result != null, "result cannot be null."); MultipartAsyncContext context = (MultipartAsyncContext)result.AsyncState; Contract.Assert(context != null, "context cannot be null"); MimeBodyPart part = context.PartsEnumerator.Current; try { Stream output = context.PartsEnumerator.Current.GetOutputStream(); output.EndWrite(result); } catch (Exception e) { part.Dispose(); context.TaskCompletionSource.TrySetException(new IOException(Properties.Resources.ReadAsMimeMultipartErrorWriting, e)); } if (!MoveNextSegment(context)) { MoveNextPart(context); } }
public void GetOutputStream_ThrowsOnInvalidStreamProvider(MultipartStreamProvider streamProvider) { HttpContent parent = new StringContent("hello"); MimeBodyPart bodypart = new MimeBodyPart(streamProvider, 1024); Assert.Throws <InvalidOperationException>(() => bodypart.GetOutputStream(parent)); }
public async Task Dispose_ClosesOutputStreamOnNonMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock <Stream> mockStream = new Mock <Stream>() { CallBase = true }; mockStream.Setup(s => s.CanWrite).Returns(true); Mock <MultipartStreamProvider> mockStreamProvider = new Mock <MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny <HttpContent>(), It.IsAny <HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024, parent); bodypart.Segments.Add(new ArraySegment <byte>(new byte[] { 1 })); await bodypart.WriteSegment(bodypart.Segments[0], CancellationToken.None); bodypart.IsComplete = true; // Act bodypart.GetCompletedHttpContent(); bodypart.Dispose(); // Assert mockStream.Verify(s => s.Close(), Times.Once()); }
public void GetOutputStream_ThrowsOnInvalidStreamProvider(MultipartStreamProvider streamProvider) { // Arrange HttpContent parent = new StringContent("hello"); MimeBodyPart bodypart = new MimeBodyPart(streamProvider, 1024, parent); bodypart.Segments.Add(new ArraySegment<byte>(new byte[] { 1 })); // Act and Assert Assert.Throws<InvalidOperationException>(() => bodypart.WriteSegment(bodypart.Segments[0]).Wait()); }
public void GetOutputStream_ThrowsOnInvalidStreamProvider(MultipartStreamProvider streamProvider) { // Arrange HttpContent parent = new StringContent("hello"); MimeBodyPart bodypart = new MimeBodyPart(streamProvider, 1024, parent); bodypart.Segments.Add(new ArraySegment <byte>(new byte[] { 1 })); // Act and Assert Assert.Throws <InvalidOperationException>(() => bodypart.WriteSegment(bodypart.Segments[0]).Wait()); }
public async Task GetOutputStream_ThrowsOnInvalidStreamProvider(MultipartStreamProvider streamProvider) { // Arrange HttpContent parent = new StringContent("hello"); MimeBodyPart bodypart = new MimeBodyPart(streamProvider, 1024, parent); bodypart.Segments.Add(new ArraySegment <byte>(new byte[] { 1 })); // Act and Assert await Assert.ThrowsAsync <InvalidOperationException>(() => bodypart.WriteSegment(bodypart.Segments[0], CancellationToken.None)); }
public void Dispose_SetsPositionToZeroOnMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock<MemoryStream> mockStream = new Mock<MemoryStream> { CallBase = true }; Mock<MultipartStreamProvider> mockStreamProvider = new Mock<MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny<HttpContent>(), It.IsAny<HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024); // Act bodypart.GetOutputStream(parent); bodypart.Dispose(); // Assert mockStream.VerifySet(s => s.Position = 0); }
public void Dispose_ClosesOutputStreamOnNonMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock<Stream> mockStream = new Mock<Stream>(); mockStream.Setup(s => s.CanWrite).Returns(true); Mock<MultipartStreamProvider> mockStreamProvider = new Mock<MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny<HttpContent>(), It.IsAny<HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024); // Act bodypart.GetOutputStream(parent); bodypart.Dispose(); // Assert mockStream.Verify(s => s.Close(), Times.Once()); }
private static bool CheckPartCompletion(MimeBodyPart part, List <HttpContent> result) { Contract.Assert(part != null, "part cannot be null."); Contract.Assert(result != null, "result cannot be null."); if (part.IsComplete) { if (part.HttpContent != null) { result.Add(part.HttpContent); } bool isFinal = part.IsFinal; part.Dispose(); return(isFinal); } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="MimeMultipartBodyPartParser"/> class. /// </summary> /// <param name="content">An existing <see cref="HttpContent"/> instance to use for the object's content.</param> /// <param name="streamProvider">A stream provider providing output streams for where to write body parts as they are parsed.</param> /// <param name="maxMessageSize">The max length of the entire MIME multipart message.</param> /// <param name="maxBodyPartHeaderSize">The max length of the MIME header within each MIME body part.</param> public MimeMultipartBodyPartParser( HttpContent content, MultipartStreamProvider streamProvider, long maxMessageSize, int maxBodyPartHeaderSize) { Contract.Assert(content != null, "content cannot be null."); Contract.Assert(streamProvider != null, "streamProvider cannot be null."); string boundary = ValidateArguments(content, maxMessageSize, true); this._mimeParser = new MimeMultipartParser(boundary, maxMessageSize); this._currentBodyPart = new MimeBodyPart(streamProvider, maxBodyPartHeaderSize, content); this._content = content; this._maxBodyPartHeaderSize = maxBodyPartHeaderSize; this._streamProvider = streamProvider; }
public void Dispose_SetsPositionToZeroOnMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock<MemoryStream> mockStream = new Mock<MemoryStream> { CallBase = true }; Mock<MultipartStreamProvider> mockStreamProvider = new Mock<MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny<HttpContent>(), It.IsAny<HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024, parent); bodypart.Segments.Add(new ArraySegment<byte>(new byte[] { 1 })); bodypart.WriteSegment(bodypart.Segments[0]).Wait(); bodypart.IsComplete = true; // Act bodypart.GetCompletedHttpContent(); bodypart.Dispose(); // Assert mockStream.VerifySet(s => s.Position = 0); }
public void Dispose_ClosesOutputStreamOnNonMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock <Stream> mockStream = new Mock <Stream>(); mockStream.Setup(s => s.CanWrite).Returns(true); Mock <MultipartStreamProvider> mockStreamProvider = new Mock <MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny <HttpContent>(), It.IsAny <HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024); // Act bodypart.GetOutputStream(parent); bodypart.Dispose(); // Assert mockStream.Verify(s => s.Close(), Times.Once()); }
public void Dispose_SetsPositionToZeroOnMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock <MemoryStream> mockStream = new Mock <MemoryStream> { CallBase = true }; Mock <MultipartStreamProvider> mockStreamProvider = new Mock <MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny <HttpContent>(), It.IsAny <HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024); // Act bodypart.GetOutputStream(parent); bodypart.Dispose(); // Assert mockStream.VerifySet(s => s.Position = 0); }
public void Dispose_ClosesOutputStreamOnNonMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock<Stream> mockStream = new Mock<Stream>() { CallBase = true }; mockStream.Setup(s => s.CanWrite).Returns(true); Mock<MultipartStreamProvider> mockStreamProvider = new Mock<MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny<HttpContent>(), It.IsAny<HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024, parent); bodypart.Segments.Add(new ArraySegment<byte>(new byte[] { 1 })); bodypart.WriteSegment(bodypart.Segments[0], CancellationToken.None).Wait(); bodypart.IsComplete = true; // Act bodypart.GetCompletedHttpContent(); bodypart.Dispose(); // Assert mockStream.Verify(s => s.Close(), Times.Once()); }
public void Dispose_SetsPositionToZeroOnMemoryStream() { // Arrange HttpContent parent = new StringContent("hello"); Mock <MemoryStream> mockStream = new Mock <MemoryStream> { CallBase = true }; Mock <MultipartStreamProvider> mockStreamProvider = new Mock <MultipartStreamProvider>(); mockStreamProvider.Setup(sp => sp.GetStream(It.IsAny <HttpContent>(), It.IsAny <HttpContentHeaders>())).Returns(mockStream.Object); MimeBodyPart bodypart = new MimeBodyPart(mockStreamProvider.Object, 1024, parent); bodypart.Segments.Add(new ArraySegment <byte>(new byte[] { 1 })); bodypart.WriteSegment(bodypart.Segments[0], CancellationToken.None).Wait(); bodypart.IsComplete = true; // Act bodypart.GetCompletedHttpContent(); bodypart.Dispose(); // Assert mockStream.VerifySet(s => s.Position = 0); }
private static bool CheckPartCompletion(MimeBodyPart part, List<HttpContent> result) { Contract.Assert(part != null, "part cannot be null."); Contract.Assert(result != null, "result cannot be null."); if (part.IsComplete) { if (part.HttpContent != null) { result.Add(part.HttpContent); } bool isFinal = part.IsFinal; part.Dispose(); return isFinal; } return false; }
public void GetOutputStream_ThrowsOnInvalidStreamProvider(MultipartStreamProvider streamProvider) { HttpContent parent = new StringContent("hello"); MimeBodyPart bodypart = new MimeBodyPart(streamProvider, 1024); Assert.Throws<InvalidOperationException>(() => bodypart.GetOutputStream(parent)); }
private void CleanupCurrentBodyPart() { if (this._currentBodyPart != null) { this._currentBodyPart.Dispose(); this._currentBodyPart = null; } }
/// <summary> /// Parses the data provided and generates parsed MIME body part bodies in the form of <see cref="ArraySegment{T}"/> which are ready to /// write to the output stream. /// </summary> /// <param name="data">The data to parse</param> /// <param name="bytesRead">The number of bytes available in the input data</param> /// <returns>Parsed <see cref="MimeBodyPart"/> instances.</returns> public IEnumerable<MimeBodyPart> ParseBuffer(byte[] data, int bytesRead) { int bytesConsumed = 0; bool isFinal = false; // There's a special case here - if we've reached the end of the message and there's no optional // CRLF, then we're out of bytes to read, but we have finished the message. // // If IsWaitingForEndOfMessage is true and we're at the end of the stream, then we're going to // call into the parser again with an empty array as the buffer to signal the end of the parse. // Then the final boundary segment will be marked as complete. if (bytesRead == 0 && !this._mimeParser.IsWaitingForEndOfMessage) { this.CleanupCurrentBodyPart(); throw new IOException(Resources.ReadAsMimeMultipartUnexpectedTermination); } // Make sure we remove an old array segments. this._currentBodyPart.Segments.Clear(); while (this._mimeParser.CanParseMore(bytesRead, bytesConsumed)) { this._mimeStatus = this._mimeParser.ParseBuffer(data, bytesRead, ref bytesConsumed, out this._parsedBodyPart[0], out this._parsedBodyPart[1], out isFinal); if (this._mimeStatus != MimeMultipartParser.State.BodyPartCompleted && this._mimeStatus != MimeMultipartParser.State.NeedMoreData) { this.CleanupCurrentBodyPart(); throw Error.InvalidOperation(Resources.ReadAsMimeMultipartParseError, bytesConsumed, data); } // First body is empty preamble which we just ignore if (this._isFirst) { if (this._mimeStatus == MimeMultipartParser.State.BodyPartCompleted) { this._isFirst = false; } continue; } // Parse the two array segments containing parsed body parts that the MIME parser gave us foreach (ArraySegment<byte> part in this._parsedBodyPart) { if (part.Count == 0) { continue; } if (this._bodyPartHeaderStatus != ParserState.Done) { int headerConsumed = part.Offset; this._bodyPartHeaderStatus = this._currentBodyPart.HeaderParser.ParseBuffer(part.Array, part.Count + part.Offset, ref headerConsumed); if (this._bodyPartHeaderStatus == ParserState.Done) { // Add the remainder as body part content this._currentBodyPart.Segments.Add(new ArraySegment<byte>(part.Array, headerConsumed, part.Count + part.Offset - headerConsumed)); } else if (this._bodyPartHeaderStatus != ParserState.NeedMoreData) { this.CleanupCurrentBodyPart(); throw Error.InvalidOperation(Resources.ReadAsMimeMultipartHeaderParseError, headerConsumed, part.Array); } } else { // Add the data as body part content this._currentBodyPart.Segments.Add(part); } } if (this._mimeStatus == MimeMultipartParser.State.BodyPartCompleted) { // If body is completed then swap current body part MimeBodyPart completed = this._currentBodyPart; completed.IsComplete = true; completed.IsFinal = isFinal; this._currentBodyPart = new MimeBodyPart(this._streamProvider, this._maxBodyPartHeaderSize, this._content); this._mimeStatus = MimeMultipartParser.State.NeedMoreData; this._bodyPartHeaderStatus = ParserState.NeedMoreData; yield return completed; } else { // Otherwise return what we have yield return this._currentBodyPart; } } }