Example #1
0
        public static Task <FormData> ParseMultipart(Stream stream, string boundary)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (boundary == null)
            {
                throw new ArgumentNullException("boundary");
            }
            if (boundary.Length == 0)
            {
                throw new ArgumentException("Boundary cannot be empty", "boundary");
            }
            var form = new FormData();

            boundary = "--" + boundary;
            var boundaryBytes = Encoding.UTF8.GetBytes("\r\n" + boundary);

            string currentLine = stream.ReadLine(Encoding.UTF8);

            if (currentLine != boundary)
            {
                form.IsValid = false;
                return(OwinConstants.TaskHelper.Completed(form));
            }
            while (true)
            {
                currentLine = stream.ReadLine(Encoding.UTF8);
                // parse ContentDisposition line
                var match = ContentDispositionFormDataRegex.Match(currentLine);
                if (!match.Success)
                {
                    form.IsValid = false;
                    return(OwinConstants.TaskHelper.Completed(form));
                }
                string fieldName = match.Groups[1].Value;
                string fileName  = match.Groups[2].Success ? match.Groups[3].Value : null;

                if (fileName != null)
                {
                    if (!ParseMultipartFile(stream, form, fieldName, fileName, boundaryBytes))
                    {
                        form.IsValid = false;
                        return(OwinConstants.TaskHelper.Completed(form));
                    }
                }
                else
                {
                    if (!ParseMultipartField(stream, form, fieldName, boundaryBytes))
                    {
                        form.IsValid = false;
                        return(OwinConstants.TaskHelper.Completed(form));
                    }
                }

                // check end or next
                currentLine = stream.ReadLine(Encoding.UTF8);
                // --boundary-- end
                if (currentLine == "--")
                {
                    break;
                }
                // --boundary between
                if (currentLine != string.Empty)
                {
                    form.IsValid = false;
                    return(OwinConstants.TaskHelper.Completed(form));
                }
            }
            return(OwinConstants.TaskHelper.Completed(form));
        }
Example #2
0
        private static bool ParseMultipartField(Stream stream, FormData form, string fieldName, byte[] boundaryBytes)
        {
            string contentType = null;
            string headerLine;
            Match  match;

            while ((headerLine = stream.ReadLine(Encoding.UTF8)) != string.Empty)
            {
                // parse 'Content-" headers
                match = ContentTypeFormDataRegex.Match(headerLine);
                if (match.Success)
                {
                    // nested: Content-Type: multipart/mixed; boundary=BbC04y
                    contentType = match.Groups[1].Value.Trim();
                    if (match.Groups[2].Success)
                    {
                        string fileBoundary      = match.Groups[4].Value;
                        byte[] fileBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + fileBoundary);
                        byte[] temp;
                        if (!stream.ReadTo(fileBoundaryBytes, out temp))
                        {
                            return(false);
                        }
                        if (stream.ReadLine(Encoding.UTF8) != string.Empty)
                        {
                            return(false);
                        }
                        bool moreFiles = true;
                        while (moreFiles)
                        {
                            string line = stream.ReadLine(Encoding.UTF8);
                            match = ContentDispositionFileRegex.Match(line);
                            if (!match.Success)
                            {
                                return(false);
                            }
                            string filename = match.Groups[1].Value;
                            if (!ParseMultipartFile(stream, form, fieldName, filename, fileBoundaryBytes))
                            {
                                return(false);
                            }
                            line = stream.ReadLine(Encoding.UTF8);
                            if (line == "--")
                            {
                                moreFiles = false;
                            }
                            else if (line != string.Empty)
                            {
                                return(false);
                            }
                        }
                        // NB: CrLf already ripped here
                        var boundaryNoCrLf = new byte[boundaryBytes.Length - 2];
                        Array.Copy(boundaryBytes, 2, boundaryNoCrLf, 0, boundaryBytes.Length - 2);
                        if (!stream.ReadTo(boundaryNoCrLf, out temp))
                        {
                            return(false);
                        }
                        if (temp.Length != 0)
                        {
                            return(false);
                        }
                        return(true);
                    }
                }
            }
            if (contentType == null)
            {
                contentType = "text/plain";
            }

            byte[] value;
            if (!stream.ReadTo(boundaryBytes, out value))
            {
                return(false);
            }
            // handle charset: content-type: text/plain;charset=windows-1250
            match = CharsetRegex.Match(contentType);
            Encoding encoding = match.Success ? Encoding.GetEncoding(match.Groups[2].Value) : Encoding.UTF8;

            form[fieldName] = encoding.GetString(value);

            return(true);
        }