-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Klaus Vancamelbeke <[email protected]> Co-authored-by: Laurent Ellerbach <[email protected]>
- Loading branch information
1 parent
2f831ad
commit 9e8b4d1
Showing
20 changed files
with
1,187 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.IO; | ||
using System.Net; | ||
using System.Threading; | ||
using nanoFramework.WebServer.HttpMultipartParser; | ||
|
||
namespace nanoFramework.WebServer | ||
{ | ||
/// <summary>Contains extension methods for HttpListenerRequest</summary> | ||
public static class HttpListenerRequestExtensions | ||
{ | ||
/// <summary> | ||
/// Reads a Multipart form from the request | ||
/// </summary> | ||
/// <param name="httpListenerRequest">The request to read the form from</param> | ||
/// <returns>A <see cref="MultipartFormDataParser">MultipartFormDataParser</see> containing a collection of the parameters and files in the form.</returns> | ||
public static MultipartFormDataParser ReadForm(this HttpListenerRequest httpListenerRequest) => | ||
MultipartFormDataParser.Parse(httpListenerRequest.InputStream); | ||
|
||
/// <summary> | ||
/// Reads a body from the HttpListenerRequest inputstream | ||
/// </summary> | ||
/// <param name="httpListenerRequest">The request to read the body from</param> | ||
/// <returns>A byte[] containing the body of the request</returns> | ||
public static byte[] ReadBody(this HttpListenerRequest httpListenerRequest) | ||
{ | ||
byte[] body = new byte[httpListenerRequest.ContentLength64]; | ||
byte[] buffer = new byte[4096]; | ||
Stream stream = httpListenerRequest.InputStream; | ||
|
||
int position = 0; | ||
|
||
while (true) | ||
{ | ||
// The stream is (should be) a NetworkStream which might still be receiving data while | ||
// we're already processing. Give the stream a chance to receive more data or we might | ||
// end up with "zero bytes read" too soon... | ||
Thread.Sleep(1); | ||
|
||
long length = stream.Length; | ||
|
||
if (length > buffer.Length) | ||
{ | ||
length = buffer.Length; | ||
} | ||
|
||
int bytesRead = stream.Read(buffer, 0, (int)length); | ||
|
||
if (bytesRead == 0) | ||
{ | ||
break; | ||
} | ||
|
||
Array.Copy(buffer, 0, body, position, bytesRead); | ||
|
||
position += bytesRead; | ||
} | ||
|
||
return body; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections; | ||
using System.IO; | ||
|
||
namespace nanoFramework.WebServer.HttpMultipartParser | ||
{ | ||
/// <summary>Represents a single file extracted from a multipart/form-data stream.</summary> | ||
public class FilePart | ||
{ | ||
/// <summary>Initializes a new instance of the <see cref="FilePart" /> class.</summary> | ||
/// <param name="name">The name of the input field used for the upload.</param> | ||
/// <param name="fileName">The name of the file.</param> | ||
/// <param name="data">The file data.</param> | ||
/// <param name="additionalProperties">Additional properties associated with this file.</param> | ||
/// <param name="contentType">The content type.</param> | ||
/// <param name="contentDisposition">The content disposition.</param> | ||
public FilePart(string name, string fileName, Stream data, Hashtable additionalProperties, string contentType, string contentDisposition) | ||
{ | ||
string[] parts = fileName?.Split(GetInvalidFileNameChars()); | ||
|
||
Name = name; | ||
FileName = parts != null && parts.Length > 0 ? parts[parts.Length - 1] : string.Empty; | ||
Data = data; | ||
ContentType = contentType; | ||
ContentDisposition = contentDisposition; | ||
AdditionalProperties = additionalProperties; | ||
} | ||
|
||
/// <summary>Gets the data.</summary> | ||
public Stream Data | ||
{ | ||
get; | ||
} | ||
|
||
/// <summary>Gets the file name.</summary> | ||
public string FileName | ||
{ | ||
get; | ||
} | ||
|
||
/// <summary>Gets the name.</summary> | ||
public string Name | ||
{ | ||
get; | ||
} | ||
|
||
/// <summary>Gets the content-type. Defaults to text/plain if unspecified.</summary> | ||
public string ContentType | ||
{ | ||
get; | ||
} | ||
|
||
/// <summary>Gets the content-disposition. Defaults to form-data if unspecified.</summary> | ||
public string ContentDisposition | ||
{ | ||
get; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the additional properties associated with this file. | ||
/// An additional property is any property other than the "well known" ones such as name, filename, content-type, etc. | ||
/// </summary> | ||
public Hashtable AdditionalProperties | ||
{ | ||
get; | ||
private set; | ||
} | ||
|
||
private static char[] GetInvalidFileNameChars() => new char[] | ||
{ | ||
'\"', '<', '>', '|', '\0', | ||
(char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, | ||
(char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, | ||
(char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, | ||
(char)31, ':', '*', '?', '\\', '/' | ||
}; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
nanoFramework.WebServer/HttpMultipartParser/HashtableUtility.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections; | ||
|
||
namespace nanoFramework.WebServer.HttpMultipartParser | ||
{ | ||
internal static class HashtableUtility | ||
{ | ||
public static bool TryGetValue(this Hashtable hashtable, string key, out string value) | ||
{ | ||
if (hashtable != null && hashtable.Contains(key)) | ||
{ | ||
var obj = hashtable[key]; | ||
value = obj == null ? string.Empty : obj.ToString(); | ||
return true; | ||
} | ||
|
||
value = null; | ||
return false; | ||
} | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
nanoFramework.WebServer/HttpMultipartParser/HeaderUtility.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections; | ||
using System.Text; | ||
|
||
namespace nanoFramework.WebServer.HttpMultipartParser | ||
{ | ||
/// <summary> | ||
/// Provides parsing headers from a Http Multipart Form | ||
/// </summary> | ||
public static class HeaderUtility | ||
{ | ||
/// <summary> | ||
/// Reads headers from a line of text. | ||
/// Headers are delimited by a semi-colon ';' | ||
/// Key-value pairs are separated by colon ':' or equals '=' | ||
/// Values can be delimited by quotes '"' or not | ||
/// </summary> | ||
/// <param name="text">The line of text containing one or more headers</param> | ||
/// <param name="headers"> | ||
/// The hashtable that will receive the key values. | ||
/// Passed in since a Multipart Part can contain multiple lines of headers | ||
/// </param> | ||
public static void ParseHeaders(string text, Hashtable headers) | ||
{ | ||
bool inQuotes = false; | ||
bool inKey = true; | ||
StringBuilder key = new(); | ||
StringBuilder value = new(); | ||
|
||
foreach (char c in text) | ||
{ | ||
if (c == '"') | ||
{ | ||
inQuotes = !inQuotes; | ||
} | ||
else if (inQuotes) | ||
{ | ||
value.Append(c); | ||
} | ||
else if (c == ';') | ||
{ | ||
headers[key.ToString().ToLower()] = value.ToString(); | ||
key.Clear(); | ||
inKey = true; | ||
} | ||
else if (c == '=' || c == ':') | ||
{ | ||
value = value.Clear(); | ||
inKey = false; | ||
} | ||
else if (c != ' ') | ||
{ | ||
if (inKey) | ||
{ | ||
key.Append(c); | ||
} | ||
else | ||
{ | ||
value.Append(c); | ||
} | ||
} | ||
} | ||
|
||
if (key.Length > 0) | ||
{ | ||
headers.Add(key.ToString().ToLower(), value.ToString()); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.