public void HttpHeaderValueToStringShouldPutAllHttpHeaderValueElementsInString() { HttpHeaderValueElement e1 = new HttpHeaderValueElement("e1", null, new KeyValuePair <string, string> [0]); HttpHeaderValueElement e2 = new HttpHeaderValueElement("e2", "token", new KeyValuePair <string, string> [0]); HttpHeaderValueElement e3 = new HttpHeaderValueElement("e3", "\"quoted-string\"", new KeyValuePair <string, string> [0]); HttpHeaderValueElement e4 = new HttpHeaderValueElement("e4", null, new[] { new KeyValuePair <string, string>("p1", "v1"), new KeyValuePair <string, string>("p2", null) }); HttpHeaderValueElement e5 = new HttpHeaderValueElement("e5", "token", new[] { new KeyValuePair <string, string>("p1", null), new KeyValuePair <string, string>("p2", "\"v2\"") }); HttpHeaderValueElement e6 = new HttpHeaderValueElement("e6", "\"quoted-string\"", new[] { new KeyValuePair <string, string>("p1", null), new KeyValuePair <string, string>("p2", null), new KeyValuePair <string, string>("p3", "v3"), new KeyValuePair <string, string>("p4", "\"v4\"") }); const string eStr1 = "e1"; const string eStr2 = "e2=token"; const string eStr3 = "e3=\"quoted-string\""; const string eStr4 = "e4;p1=v1;p2"; const string eStr5 = "e5=token;p1;p2=\"v2\""; const string eStr6 = "e6=\"quoted-string\";p1;p2;p3=v3;p4=\"v4\""; HttpHeaderValue elements = new HttpHeaderValue { { "e1", e1 }, { "e2", e2 }, { "e3", e3 }, { "e4", e4 }, { "e5", e5 }, { "e6", e6 }, }; var items = elements.ToString().Split(new[] { ',' }); Assert.Contains(eStr1, items); Assert.Contains(eStr2, items); Assert.Contains(eStr3, items); Assert.Contains(eStr4, items); Assert.Contains(eStr5, items); Assert.Contains(eStr6, items); }
public HttpHeader Parse(Memory <char> rawContent, Memory <char> headerName, Memory <char> headerValue) { if (_parametersParser == null) { return(new HttpHeader(rawContent, headerName, new HttpHeaderValue[] { new HttpHeaderValue(headerValue) })); } else { var valueSpan = headerValue.Span; int index = valueSpan.IndexOf(';'); if (index == -1) { return(new HttpHeader(rawContent, headerName, new HttpHeaderValue[] { new HttpHeaderValue(headerValue) })); } else { var rawParamContent = headerValue.Slice(index + 1); var parameters = _parametersParser.Parse(rawParamContent, ';'); HttpHeaderValue[] values = new HttpHeaderValue[parameters.Length + 1]; values[0] = new HttpHeaderValue(headerValue.Slice(0, index)); for (int i = 1; i < values.Length; i++) { values[i] = parameters[i - 1]; } return(new HttpHeader(rawContent, headerName, values)); } } }
public void HttpHeaderValueToStringShouldPutAllHttpHeaderValueElementsInString() { HttpHeaderValueElement e1 = new HttpHeaderValueElement("e1", null, new KeyValuePair<string, string>[0]); HttpHeaderValueElement e2 = new HttpHeaderValueElement("e2", "token", new KeyValuePair<string, string>[0]); HttpHeaderValueElement e3 = new HttpHeaderValueElement("e3", "\"quoted-string\"", new KeyValuePair<string, string>[0]); HttpHeaderValueElement e4 = new HttpHeaderValueElement("e4", null, new[] { new KeyValuePair<string, string>("p1", "v1"), new KeyValuePair<string, string>("p2", null) }); HttpHeaderValueElement e5 = new HttpHeaderValueElement("e5", "token", new[] { new KeyValuePair<string, string>("p1", null), new KeyValuePair<string, string>("p2", "\"v2\"") }); HttpHeaderValueElement e6 = new HttpHeaderValueElement("e6", "\"quoted-string\"", new[] { new KeyValuePair<string, string>("p1", null), new KeyValuePair<string, string>("p2", null), new KeyValuePair<string, string>("p3", "v3"), new KeyValuePair<string, string>("p4", "\"v4\"") }); const string eStr1 = "e1"; const string eStr2 = "e2=token"; const string eStr3 = "e3=\"quoted-string\""; const string eStr4 = "e4;p1=v1;p2"; const string eStr5 = "e5=token;p1;p2=\"v2\""; const string eStr6 = "e6=\"quoted-string\";p1;p2;p3=v3;p4=\"v4\""; HttpHeaderValue elements = new HttpHeaderValue {{"e1", e1}, {"e2", e2}, {"e3", e3}, {"e4", e4}, {"e5", e5}, {"e6", e6},}; elements.ToString().Split(new[] {','}).Should().Contain(eStr1).And.Contain(eStr2).And.Contain(eStr3).And.Contain(eStr4).And.Contain(eStr5).And.Contain(eStr6); }
/// <summary> /// Deserialize the content from the stream. /// </summary> /// <param name="contentType">Used to identify the object which is about to be deserialized. Specified by the /// <c>Serialize()</c> method when invoked in the other end point.</param> /// <param name="source">Stream that contains the object to deserialize.</param> /// <returns> /// Created object /// </returns> /// <exception cref="System.ArgumentNullException">contentType</exception> /// <exception cref="System.FormatException">Failed to build a type from ' + contentType + '.</exception> public object Deserialize(string contentType, Stream source) { if (contentType == null) { throw new ArgumentNullException("contentType"); } var header = new HttpHeaderValue(contentType); // to be backwards compatible. Type type; var typeArgument = header.Parameters["type"]; if (typeArgument == null) { var pos = contentType.IndexOf(';'); if (pos == -1) { type = Type.GetType(contentType, false, true); } else { type = Type.GetType(contentType.Substring(pos + 1), false, true); } } else { var typeName = header.Parameters["type"].Replace("-", ","); type = Type.GetType(typeName, true); } if (type == null) { throw new FormatException("Failed to build a type from '" + contentType + "'."); } var serializer = new DataContractSerializer(type); return(serializer.ReadObject(source)); }
/// <summary> /// Deserialize the content from the stream. /// </summary> /// <param name="contentType">Used to identify the object which is about to be deserialized. Specified by the <c>Serialize()</c> method when invoked in the other end point.</param> /// <param name="source">Stream that contains the object to deserialize.</param> /// <returns>Created object</returns> /// <exception cref="SerializationException">Deserialization failed</exception> public object Deserialize(string contentType, Stream source) { if (contentType == null) { throw new ArgumentNullException("contentType"); } if (source == null) { throw new ArgumentNullException("source"); } if (!contentType.StartsWith(MimeType, StringComparison.OrdinalIgnoreCase)) { return(null); } var result = new FormAndFilesResult() { Form = new ParameterCollection(), Files = new HttpFileCollection() }; var contentTypeHeader = new HttpHeaderValue(contentType); var encodingStr = contentTypeHeader.Parameters["charset"]; var encoding = encodingStr != null?Encoding.GetEncoding(encodingStr) : Encoding.UTF8; //multipart/form-data, boundary=AaB03x var boundary = contentTypeHeader.Parameters.Get("boundary"); if (boundary == null) { throw new DecoderFailureException("Missing boundary in content type: " + contentType); } var multipart = new HttpMultipart(source, boundary.Value, encoding); HttpMultipart.Element element; while ((element = multipart.ReadNextElement()) != null) { if (string.IsNullOrEmpty(element.Name)) { throw new DecoderFailureException(string.Format("Missing value name.\nElement: {0}", element)); } if (!string.IsNullOrEmpty(element.Filename)) { if (string.IsNullOrEmpty(element.ContentType)) { throw new DecoderFailureException(string.Format("Value '{0}' lacks a content type.", element.Name)); } // Read the file data var buffer = new byte[element.Length]; source.Seek(element.Start, SeekOrigin.Begin); source.Read(buffer, 0, (int)element.Length); // Generate a filename var applicationData = Windows.Storage.ApplicationData.Current; var temporaryFolder = applicationData.LocalCacheFolder; var originalFileName = element.Filename; // if the internet path doesn't exist, assume mono and /var/tmp var path = string.IsNullOrEmpty(temporaryFolder.Path) ? Path.Combine("var", "tmp") : Path.Combine(temporaryFolder.Path.Replace("\\\\", "\\"), "tmp"); element.Filename = Path.Combine(path, Math.Abs(element.Filename.GetHashCode()) + ".tmp"); // If the file exists generate a new filename while (File.Exists(element.Filename)) { element.Filename = Path.Combine(path, Math.Abs(element.Filename.GetHashCode() + 1) + ".tmp"); } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } File.WriteAllBytes(element.Filename, buffer); var file = new HttpFile { Name = element.Name, OriginalFileName = originalFileName, ContentType = element.ContentType, TempFileName = element.Filename }; result.Files.Add(file); } else { var buffer = new byte[element.Length]; source.Seek(element.Start, SeekOrigin.Begin); source.Read(buffer, 0, (int)element.Length); result.Form.Add(Uri.UnescapeDataString(element.Name), encoding.GetString(buffer)); } } return(result); }
public void EmptyHttpHeaderValueToStringShouldReturnNull() { HttpHeaderValue elements = new HttpHeaderValue(); elements.ToString().Should().BeNull(); }
/// <summary> /// Decode body stream /// </summary> /// <param name="message">Contains the body to decode. Expectes the body to be in format <c>multipart/form-data</c></param> /// <returns> /// <c>true</c> if the body was decoded; otherwise <c>false</c>. /// </returns> /// <exception cref="System.NotSupportedException">MultipartDecoder expects requests of type 'HttpRequest'.</exception> /// <exception cref="DecoderFailureException"> /// Missing boundary in content type: + contentType /// or /// or /// </exception> /// <exception cref="System.FormatException">Missing boundary in content type.</exception> public bool Decode(IHttpRequest message) { if (!message.ContentType.StartsWith(MimeType)) { return(false); } var msg = message as HttpRequest; if (msg == null) { throw new NotSupportedException("MultipartDecoder expects requests of type 'HttpRequest'."); } var contentType = new HttpHeaderValue(message.Headers["Content-Type"]); //multipart/form-data, boundary=AaB03x var boundry = contentType.Parameters.Get("boundary"); if (boundry == null) { throw new DecoderFailureException("Missing boundary in content type: " + contentType); } var multipart = new HttpMultipart(message.Body, boundry.Value, message.ContentCharset); var form = msg.Form; /* * FileStream stream1 = new FileStream("C:\\temp\\mimebody.tmp", FileMode.Create); * byte[] bytes = new byte[stream.Length]; * stream.Read(bytes, 0, bytes.Length); * stream1.Write(bytes, 0, bytes.Length); * stream1.Flush(); * stream1.Close(); */ HttpMultipart.Element element; while ((element = multipart.ReadNextElement()) != null) { if (string.IsNullOrEmpty(element.Name)) { throw new DecoderFailureException(string.Format("Missing value name.\nElement: {0}", element)); } if (!string.IsNullOrEmpty(element.Filename)) { if (string.IsNullOrEmpty(element.ContentType)) { throw new DecoderFailureException(string.Format("Value '{0}' lacks a content type.", element.Name)); } // Read the file data var buffer = new byte[element.Length]; message.Body.Seek(element.Start, SeekOrigin.Begin); message.Body.Read(buffer, 0, (int)element.Length); // Generate a filename var originalFileName = element.Filename; var internetCache = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); // if the internet path doesn't exist, assume mono and /var/tmp var path = string.IsNullOrEmpty(internetCache) ? Path.Combine("var", "tmp") : Path.Combine(internetCache.Replace("\\\\", "\\"), "tmp"); element.Filename = Path.Combine(path, Math.Abs(element.Filename.GetHashCode()) + ".tmp"); // If the file exists generate a new filename while (File.Exists(element.Filename)) { element.Filename = Path.Combine(path, Math.Abs(element.Filename.GetHashCode() + 1) + ".tmp"); } if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } File.WriteAllBytes(element.Filename, buffer); var file = new HttpFile { Name = element.Name, OriginalFileName = originalFileName, ContentType = element.ContentType, TempFileName = element.Filename }; msg.Files.Add(file); } else { var buffer = new byte[element.Length]; message.Body.Seek(element.Start, SeekOrigin.Begin); message.Body.Read(buffer, 0, (int)element.Length); form.Add(Uri.UnescapeDataString(element.Name), message.ContentCharset.GetString(buffer)); } } return(true); }
public void EmptyHttpHeaderValueToStringShouldReturnNull() { HttpHeaderValue elements = new HttpHeaderValue(); Assert.Null(elements.ToString()); }
/// <summary> /// Reads the content of a HTTP header from this <see cref="HttpHeaderValueLexer"/> instance to a new <see cref="HttpHeaderValue"/> instance. /// </summary> /// <returns>A new <see cref="HttpHeaderValue"/> instance populated with the content from this <see cref="HttpHeaderValueLexer"/> instance.</returns> internal HttpHeaderValue ToHttpHeaderValue() { HttpHeaderValueLexer lexer = this; Debug.Assert( lexer.Type == HttpHeaderValueItemType.Start, "lexer.Type == HttpHeaderValueItemType.Start -- Should only call this method on a lexer that's not yet been read."); HttpHeaderValue headerValue = new HttpHeaderValue(); // header = "header-name" ":" 1#element // element = token [ BWS "=" BWS (token | quoted-string) ] // *( OWS ";" [ OWS parameter ] ) // parameter = token [ BWS "=" BWS (token | quoted-string) ] while (true) { if (lexer.Type == HttpHeaderValueItemType.End) { break; } Debug.Assert( lexer.Type == HttpHeaderValueItemType.Start || lexer.Type == HttpHeaderValueItemType.ElementSeparator, "lexer.Type == HttpHeaderValueItemType.Start || lexer.Type == HttpHeaderValueItemType.ElementSeparator"); lexer = lexer.ReadNext(); Debug.Assert( lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.End, "lexer.Type == HttpHeaderValueItemType.Token || lexer.Type == HttpHeaderValueItemType.End"); if (lexer.Type == HttpHeaderValueItemType.Token) { var element = ReadHttpHeaderValueElement(ref lexer); // If multiple elements with the same name encountered, the first one wins. if (!headerValue.ContainsKey(element.Name)) { headerValue.Add(element.Name, element); } } } return headerValue; }