예제 #1
0
        /// <summary>
        /// 对multipart/form-data数据流进行解析
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static FrameDLRObject ParseMultipartFormData(Stream stream, Encoding encoding)
        {
            FrameDLRObject rtn = FrameDLRObject.CreateInstance(FrameDLRFlags.SensitiveCase);

            stream.Seek(0, SeekOrigin.Begin);
            // Read the stream into a byte array
            byte[] data = new byte[stream.Length];
            stream.Read(data, 0, data.Length);
            string str = encoding.GetString(data);
            // 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"));
                int    delimiterByteLength = encoding.GetByteCount(delimiter);

                string[] sections = content.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);

                var splitindexs = ComFunc.BytesSplit(data, delimiter, Encoding.UTF8);
                var i           = 0;

                foreach (string s in sections)
                {
                    //搜索分隔喘在byte[]中所在的位置

                    if (s.Contains("Content-Disposition"))
                    {
                        // If we find "Content-Disposition", this is a valid multi-part section
                        // Now, look for the "name" parameter
                        Match  nameMatch = new Regex(@"(?<=name\=\"")(.*?)(?=\"")").Match(s);
                        string name      = nameMatch.Value.Trim().ToLower();

                        // Look for Content-Type
                        Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)");
                        Match contentTypeMatch = re.Match(s);

                        // Look for filename
                        re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
                        Match filenameMatch = re.Match(s);

                        if (contentTypeMatch.Success || filenameMatch.Success)
                        {
                            // Set properties
                            var contentype = contentTypeMatch.Value.Trim();
                            var filename   = filenameMatch.Value.Trim();

                            // Get the start & end indexes of the file contents
                            int startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length;
                            var prestr     = s.Substring(0, startIndex);
                            startIndex = encoding.GetByteCount(prestr) + splitindexs[i] + delimiterByteLength;
                            var endIndex = (i + 1) < splitindexs.Length ? splitindexs[i + 1] : data.Length - 1;
                            //清除首位的换行符
                            for (int j = 0; j < 2; j++)
                            {
                                if (data[startIndex] == 10 || data[startIndex] == 13)
                                {
                                    startIndex += 1;
                                }
                                if (data[endIndex - 1] == 10 || data[endIndex - 1] == 13)
                                {
                                    endIndex -= 1;
                                }
                            }

                            var contentLength = endIndex - startIndex;
                            var fileData      = new byte[contentLength];
                            Array.Copy(data, startIndex, fileData, 0, fileData.Length);



                            var ms = new MemoryStream();
                            ms.Write(fileData, 0, fileData.Length);

                            var fuf = new FrameUploadFile(filename, contentype, ms, encoding);
                            rtn.SetValue(name, fuf);
                        }
                        else if (!string.IsNullOrWhiteSpace(name))
                        {
                            // Get the start & end indexes of the file contents
                            int startIndex = nameMatch.Index + nameMatch.Length + "\r\n\r\n".Length;
                            rtn.SetValue(name, s.Substring(startIndex).TrimEnd(new char[] { '\r', '\n' }).Trim());
                        }
                    }
                    i++;
                }
            }

            return(rtn);
        }