using System; using System.IO; using System.Text; using System.Text.RegularExpressions; /// /// MultipartParser http://multipartparser.codeplex.com /// Reads a multipart form data stream and returns the filename, content type and contents as a stream. /// 2009 Anthony Super http://antscode.blogspot.com /// fixed by: Samuray /// namespace FastReport.Service { public class MultipartParser { public MultipartParser(Stream stream) { this.Parse(stream, Encoding.UTF8); } public MultipartParser(Stream stream, Encoding encoding) { this.Parse(stream, encoding); } private void Parse(Stream stream, Encoding encoding) { this.Success = false; // Read the stream into a byte array byte[] data = ToByteArray(stream); // Copy to a string for header parsing string content = encoding.GetString(data); // The first line should contain the delimiter int delimiterEndIndex = content.IndexOf("\r\n"); if (delimiterEndIndex > -1) { string delimiter = content.Substring(0, content.IndexOf("\r\n")); // Look for Content-Type //Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)"); // fixed by Samuray Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n)"); Match contentTypeMatch = re.Match(content); //Content-Transfer-Encoding // Look for filename re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")"); Match filenameMatch = re.Match(content); // Did we find the required values? if (contentTypeMatch.Success && filenameMatch.Success) { // Set properties this.ContentType = contentTypeMatch.Value.Trim(); this.Filename = filenameMatch.Value.Trim(); // Get the start & end indexes of the file contents //int startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length; // fixed by Samuray int startIndex = content.IndexOf("\r\n\r\n") + "\r\n\r\n".Length; byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter); int endIndex = IndexOf(data, delimiterBytes, startIndex); int contentLength = endIndex - startIndex; // Extract the file contents from the byte array byte[] fileData = new byte[contentLength]; Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength); this.FileContents = fileData; this.Success = true; } } } private int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex) { int index = 0; int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex); if (startPos != -1) { while ((startPos + index) < searchWithin.Length) { if (searchWithin[startPos + index] == serachFor[index]) { index++; if (index == serachFor.Length) { return startPos; } } else { startPos = Array.IndexOf(searchWithin, serachFor[0], startPos + index); if (startPos == -1) { return -1; } index = 0; } } } return -1; } private byte[] ToByteArray(Stream stream) { byte[] buffer = new byte[32768]; using (MemoryStream ms = new MemoryStream()) { stream.CopyTo(ms); return ms.ToArray(); } } public bool Success { get; private set; } public string ContentType { get; private set; } public string Filename { get; private set; } public byte[] FileContents { get; private set; } } }