private static bool ParseMultipartFile(Stream stream, FormData form, string fieldName, string fileName, byte[] boundaryBytes) { string contentType = null; string headerLine; while ((headerLine = stream.ReadLine(Encoding.UTF8)) != string.Empty) { // parse 'Content-" headers var match = ContentTypeFileRegex.Match(headerLine); if (match.Success) { contentType = match.Groups[1].Value.Trim(); } } if (contentType == null) { //todo: infer from file type (extension) contentType = "application/octet-stream"; } byte[] data; if (!stream.ReadTo(boundaryBytes, out data)) { return(false); } form.Files.Add(new PostedFile(fieldName, fileName, data, contentType)); return(true); }
/// <summary>从数据流中读取字节数组,直到遇到指定字节数组</summary> /// <param name="stream">数据流</param> /// <param name="str"></param> /// <param name="encoding"></param> /// <returns></returns> public static Byte[] ReadTo(this Stream stream, String str, Encoding encoding = null) { if (encoding == null) { encoding = Encoding.UTF8; } return(stream.ReadTo(encoding.GetBytes(str))); }
/// <summary>从数据流中读取一行,直到遇到换行</summary> /// <param name="stream">数据流</param> /// <param name="encoding"></param> /// <returns>未找到返回null,0位置返回String.Empty</returns> public static String ReadLine(this Stream stream, Encoding encoding = null) { var bts = stream.ReadTo(Environment.NewLine, encoding); //if (bts == null || bts.Length < 1) return null; if (bts == null) { return(null); } stream.Seek(encoding.GetByteCount(Environment.NewLine), SeekOrigin.Current); if (bts.Length == 0) { return(String.Empty); } return(encoding.GetString(bts)); }
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); }
private static bool ParseMultipartFile(Stream stream, FormData form, string fieldName, string fileName, byte[] boundaryBytes) { string contentType = null; string headerLine; while ((headerLine = stream.ReadLine(Encoding.UTF8)) != string.Empty) { // parse 'Content-" headers var match = ContentTypeFileRegex.Match(headerLine); if (match.Success) { contentType = match.Groups[1].Value.Trim(); } } if (contentType == null) { //todo: infer from file type (extension) contentType = "application/octet-stream"; } byte[] data; if (!stream.ReadTo(boundaryBytes, out data)) { return false; } form.Files.Add(new PostedFile(fieldName, fileName, data, contentType)); return true; }
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; }