public int Find(byte[] boundary) { int position = StreamingMultiPartParser.findSequence( buffer, Position, EndPosition, boundary, 0, boundary.Length); return(position); }
public bool StartsWith(byte[] prefix, int position = 0) { if (position < Position || position > EndPosition - prefix.Length) { return(false); } bool result = StreamingMultiPartParser.startsWith( buffer, position, EndPosition, prefix, 0, prefix.Length); return(result); }
private async Task parseSection() { // read headers NameValueCollection headers = new NameValueCollection(); await buffer.Fill(bodyStream); while (!buffer.IsEmpty && !buffer.StartsWith(newLine)) { string header = await parseHeader(); string[] parts = header.Split(new char[] { ':' }, 2); if (parts.Length == 2) { headers.Add(parts[0].Trim(), parts[1].Trim()); } } if (buffer.IsEmpty) { return; } // read content buffer.Shift(newLine.Length); string subBoundary = getSubBoundary(headers); if (subBoundary == null) { MemoryStream content = await parseContent(boundary, newLine); if (SectionFound != null) { SectionFound(this, new MultiPartSection() { Headers = headers, Content = content }); } } else { StreamingMultiPartParser subParser = new StreamingMultiPartParser(bodyStream, encoding, subBoundary, boundary, buffer); if (SectionFound != null) { subParser.SectionFound += (o, e) => SectionFound(o, e); } await subParser.parseInternal(); } }
public void ShouldParseMultiPartFile() { Encoding encoding = Encoding.UTF8; byte[] binaryContent = encoding.GetBytes(getMultiPartContents()); MemoryStream bodyStream = new MemoryStream(binaryContent); List<MultiPartSection> sections = new List<MultiPartSection>(); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, boundary); string parsedPreamble = null; string parsedEpilogue = null; parser.PreambleFound += (o, e) => parsedPreamble = toString(encoding, e); parser.SectionFound += (o, e) => sections.Add(e); parser.EpilogueFound += (o, e) => parsedEpilogue = toString(encoding, e); parser.Parse().Wait(); Assert.AreEqual(preamble, parsedPreamble, "The preample was not read correctly."); Assert.AreEqual(2, sections.Count, "Two sections should have been parsed from the body."); var section1 = sections[0]; Assert.AreEqual(formDataHeaderValue1, section1.Headers[formDataHeaderName1], "The first header was not parsed."); string parsedFormData = toString(encoding, section1.Content); Assert.AreEqual(formData, parsedFormData, "The form data was not read correctly."); var section2 = sections[1]; Assert.AreEqual(formDataHeaderValue2, section2.Headers[formDataHeaderName2], "The second header was not parsed."); Assert.AreEqual(formDataHeaderValue3, section2.Headers[formDataHeaderName3], "The third header was not parsed."); string parsedFileData = toString(encoding, section2.Content); Assert.AreEqual(fileData, parsedFileData, "The file data was not read correctly."); Assert.AreEqual(epilogue, parsedEpilogue, "The epilogue was not parsed."); }
public void ShouldHandlePreambleWithStartBoundary() { Encoding encoding = Encoding.UTF8; const string boundary = "ABC123abc456"; const string thisPreamble = "This is an invalid message containing only a preamble."; const string contents = thisPreamble + @" --" + boundary; byte[] binaryContent = encoding.GetBytes(contents); MemoryStream bodyStream = new MemoryStream(binaryContent); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, boundary); parser.PreambleFound += (o, e) => Assert.AreEqual(thisPreamble, toString(encoding, e)); parser.SectionFound += (o, e) => Assert.Fail("No sections should be returned because the message ends prematurely."); parser.EpilogueFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.Parse().Wait(); }
public void ShouldHandlePreambleOnly() { Encoding encoding = Encoding.UTF8; const string preamble = "This is an invalid message containing only a preamble."; byte[] binaryContent = encoding.GetBytes(preamble); MemoryStream bodyStream = new MemoryStream(binaryContent); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, "AaB03x"); parser.PreambleFound += (o, e) => Assert.AreEqual(preamble, toString(encoding, e)); parser.SectionFound += (o, e) => Assert.Fail("No sections should be found if the contents are empty."); parser.EpilogueFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.Parse().Wait(); }
public void ShouldHandlePartialSection() { Encoding encoding = Encoding.UTF8; const string contents = "--" + boundary + @" " + formDataHeaderName1 + ": " + formDataHeaderValue1 + @" "; byte[] binaryContent = encoding.GetBytes(contents); MemoryStream bodyStream = new MemoryStream(binaryContent); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, boundary); parser.PreambleFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.SectionFound += (o, e) => Assert.Fail("No sections should be returned if the content is just the end boundary."); parser.EpilogueFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.Parse().Wait(); }
public void ShouldHandleMultiPartMixedContent() { Encoding encoding = Encoding.UTF8; byte[] binaryContent = encoding.GetBytes(getMultiPartMixedContents()); MemoryStream bodyStream = new MemoryStream(binaryContent); List<MultiPartSection> sections = new List<MultiPartSection>(); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, "AaB03x"); parser.PreambleFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.SectionFound += (o, e) => sections.Add(e); parser.EpilogueFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.Parse().Wait(); Assert.AreEqual(3, sections.Count, "The wrong number of sections were found."); Assert.AreEqual("Larry", toString(encoding, sections[0].Content), "The first section content was wrong."); Assert.AreEqual("... contents of file1.txt ...", toString(encoding, sections[1].Content), "The second section content was wrong."); Assert.AreEqual("...contents of file2.gif...", toString(encoding, sections[2].Content), "The third section content was wrong."); }
public void ShouldHandleEndBoundaryWithEpilogue() { Encoding encoding = Encoding.UTF8; const string boundary = "ABC123abc456"; const string epilogue = "This is an epilogue. It comes after the end-boundary."; const string contents = "--" + boundary + @"-- " + epilogue; byte[] binaryContent = encoding.GetBytes(contents); MemoryStream bodyStream = new MemoryStream(binaryContent); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, boundary); parser.PreambleFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.SectionFound += (o, e) => Assert.Fail("No sections should be returned if the content is just the end boundary."); parser.EpilogueFound += (o, e) => Assert.AreEqual(epilogue, toString(encoding, e)); parser.Parse().Wait(); }
public void ShouldHandleEmptyContent() { Encoding encoding = Encoding.UTF8; byte[] binaryContent = encoding.GetBytes(String.Empty); MemoryStream bodyStream = new MemoryStream(binaryContent); StreamingMultiPartParser parser = new StreamingMultiPartParser(bodyStream, encoding, "AaB03x"); parser.PreambleFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.SectionFound += (o, e) => Assert.Fail("No sections should be found if the contents are empty."); parser.EpilogueFound += (o, e) => Assert.AreEqual(String.Empty, toString(encoding, e)); parser.Parse().Wait(); }
private async Task parseSection() { // read headers NameValueCollection headers = new NameValueCollection(); await buffer.Fill(bodyStream); while (!buffer.IsEmpty && !buffer.StartsWith(newLine)) { string header = await parseHeader(); string[] parts = header.Split(new char[] { ':' }, 2); if (parts.Length == 2) { headers.Add(parts[0].Trim(), parts[1].Trim()); } } if (buffer.IsEmpty) { return; } // read content buffer.Shift(newLine.Length); string subBoundary = getSubBoundary(headers); if (subBoundary == null) { MemoryStream content = await parseContent(boundary, newLine); if (SectionFound != null) { SectionFound(this, new MultiPartSection() { Headers = headers, Content = content }); } } else { StreamingMultiPartParser subParser = new StreamingMultiPartParser(bodyStream, encoding, subBoundary, boundary, buffer); if (SectionFound != null) { subParser.SectionFound += (o, e) => SectionFound(o, e); } await subParser.parseInternal(); } }
public static MultiPartResponse FromMultiPart(this IWebResponse response) { if (response == null) { throw new ArgumentNullException("response"); } // Make sure it is a multi-part request string[] parts = response.Response.ContentType.Split(';').Select(s => s.Trim()).ToArray(); if (!parts[0].Equals(ContentTypePrefix, StringComparison.InvariantCultureIgnoreCase)) { return new MultiPartResponse() { Files = new MultiPartFileLookup(), FormData = new NameValueCollection() }; } // Parse the content type parameters var contentTypeParameters = parts .Skip(1) .Select(p => p.Split(new char[] { '=' }, 2)) .Where(p => p.Length == 2) .ToLookup(p => p[0], p => p[1], StringComparer.InvariantCultureIgnoreCase); // Check the boundary is specified, and only once if (contentTypeParameters["boundary"].Count() != 1) { return new MultiPartResponse() { Files = new MultiPartFileLookup(), FormData = new NameValueCollection() }; } string boundary = contentTypeParameters["boundary"].First(); using (Stream responseStream = response.Response.GetResponseStream()) { Encoding encoding = response.Response.ContentEncoding == null ? Encoding.UTF8 : Encoding.GetEncoding(response.Response.ContentEncoding); StreamingMultiPartParser parser = new StreamingMultiPartParser(responseStream, encoding, boundary); MultiPartFileLookup fileLookup = new MultiPartFileLookup(); NameValueCollection collection = new NameValueCollection(); parser.SectionFound += (o, e) => { var data = getSectionData(e); if (data == null) { return; } if (String.IsNullOrWhiteSpace(data.FileName)) { string value = encoding.GetString(data.Contents); collection.Add(data.Name, value); } else { var file = new MultiPartFile() { Name = data.Name, FileName = data.FileName, ContentType = data.ContentType, Contents = data.Contents }; fileLookup.Add(file.Name, file); } }; return new MultiPartResponse() { Files = fileLookup, FormData = collection }; } }
public static MultiPartResponse FromMultiPart(this IWebResponse response) { if (response == null) { throw new ArgumentNullException("response"); } // Make sure it is a multi-part request string[] parts = response.Response.ContentType.Split(';').Select(s => s.Trim()).ToArray(); if (!parts[0].Equals(ContentTypePrefix, StringComparison.InvariantCultureIgnoreCase)) { return(new MultiPartResponse() { Files = new MultiPartFileLookup(), FormData = new NameValueCollection() }); } // Parse the content type parameters var contentTypeParameters = parts .Skip(1) .Select(p => p.Split(new char[] { '=' }, 2)) .Where(p => p.Length == 2) .ToLookup(p => p[0], p => p[1], StringComparer.InvariantCultureIgnoreCase); // Check the boundary is specified, and only once if (contentTypeParameters["boundary"].Count() != 1) { return(new MultiPartResponse() { Files = new MultiPartFileLookup(), FormData = new NameValueCollection() }); } string boundary = contentTypeParameters["boundary"].First(); using (Stream responseStream = response.Response.GetResponseStream()) { Encoding encoding = response.Response.ContentEncoding == null ? Encoding.UTF8 : Encoding.GetEncoding(response.Response.ContentEncoding); StreamingMultiPartParser parser = new StreamingMultiPartParser(responseStream, encoding, boundary); MultiPartFileLookup fileLookup = new MultiPartFileLookup(); NameValueCollection collection = new NameValueCollection(); parser.SectionFound += (o, e) => { var data = getSectionData(e); if (data == null) { return; } if (String.IsNullOrWhiteSpace(data.FileName)) { string value = encoding.GetString(data.Contents); collection.Add(data.Name, value); } else { var file = new MultiPartFile() { Name = data.Name, FileName = data.FileName, ContentType = data.ContentType, Contents = data.Contents }; fileLookup.Add(file.Name, file); } }; return(new MultiPartResponse() { Files = fileLookup, FormData = collection }); } }