/// <summary>Decodes the form data.</summary> /// <param name="contentType">Type of the content.</param> /// <param name="reader">The reader.</param> /// <exception cref="WebServerException">0 - MultiPart boundary missing!.</exception> public void DecodeMultiPartFormData(string contentType, DataReader reader) { string boundary = contentType.AfterFirst("boundary").AfterFirst('"').BeforeFirst('"'); if (boundary == null || boundary.HasInvalidChars(ASCII.Strings.Printable)) { throw new WebServerException(WebError.UnknownContent, 0, "MultiPart boundary missing!"); } MultiPartFormData = WebMultiPart.Parse(reader, boundary.Trim()); }
/// <summary>Parses from the specified reader.</summary> /// <param name="reader">The reader.</param> /// <param name="boundary">The boundary.</param> /// <returns></returns> /// <exception cref="InvalidDataException"> /// Invalid header in multi part content! /// or /// Invalid data after multi part content!. /// </exception> public static WebMultiPart Parse(DataReader reader, string boundary) { boundary = "--" + boundary; byte[] binaryBoundary = Encoding.UTF8.GetBytes(boundary); var result = new WebMultiPart(); // first part is main content, we do not have addition headers there bool inHeader = true; var part = new WebSinglePart(); while (true) { if (inHeader) { string line = reader.ReadLine(); // end of header ? if (line.Length == 0) { inHeader = false; continue; } // boundary ? if (line.StartsWith("--")) { // end of data ? // if (line == "--") break; // next part ? if (line == boundary) { part = new WebSinglePart(); continue; } throw new WebServerException(WebError.UnknownContent, 0, "Invalid header in multi part content!"); } // read header value string[] kv = line.Split(new char[] { ':' }, 2); if (kv.Length < 2) { throw new WebServerException(WebError.UnknownContent, 0, "Invalid header in multi part content!"); } part.Headers.Add(kv[0].Trim().ToLower(), kv[1].Trim()); } else { // content byte[] buffer = new byte[1024 * 1024]; int offset = 0; reader.ReadUntil(buffer, ref offset, false, binaryBoundary); Array.Resize(ref buffer, offset); part.Content = buffer; result.Parts.Add(part); part = new WebSinglePart(); inHeader = true; string endOfData = reader.ReadLine(); // end of data ? if (endOfData == "--") { // var empty = reader.ReadLine(); // if (empty != "") throw new CaveWebException(CaveWebError.UnknownContent, "Invalid data after end of multi part content!"); break; } if (endOfData.Length != 0) { throw new WebServerException(WebError.UnknownContent, 0, "Invalid data after multi part content!"); } } } return(result); }