Fixed handling of multi-byte characters in both HttpServer and Duplicati.
This fixes issue #1085 and issue #1063.
This commit is contained in:
@@ -328,7 +328,7 @@ namespace Duplicati.Library.Utility
|
||||
/// <summary>
|
||||
/// The regular expression that matches %20 type values in a querystring
|
||||
/// </summary>
|
||||
private static System.Text.RegularExpressions.Regex RE_ESCAPECHAR = new System.Text.RegularExpressions.Regex(@"[^0-9a-zA-Z]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
private static System.Text.RegularExpressions.Regex RE_ESCAPECHAR = new System.Text.RegularExpressions.Regex(@"[^0-9a-zA-Z\-\_]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a URL, like System.Web.HttpUtility.UrlEncode
|
||||
@@ -356,9 +356,8 @@ namespace Duplicati.Library.Utility
|
||||
|
||||
var encoder = encoding.GetEncoder();
|
||||
var inbuf = new char[1];
|
||||
var outbuf = new byte[2];
|
||||
var shortout = new byte[1];
|
||||
|
||||
var outbuf = new byte[4];
|
||||
|
||||
return RE_ESCAPECHAR.Replace(value, (m) => {
|
||||
if (m.Value == " ")
|
||||
return spacevalue;
|
||||
@@ -368,13 +367,7 @@ namespace Duplicati.Library.Utility
|
||||
try
|
||||
{
|
||||
var len = encoder.GetBytes(inbuf, 0, 1, outbuf, 0, true);
|
||||
if (len == 1)
|
||||
{
|
||||
shortout[0] = outbuf[0];
|
||||
return "%" + Utility.ByteArrayAsHexString(shortout).ToLower();
|
||||
}
|
||||
else if (len == 2)
|
||||
return "%u" + Utility.ByteArrayAsHexString(outbuf).ToLower();
|
||||
return "%" + BitConverter.ToString(outbuf, 0, len).Replace("-", "%");
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -389,12 +382,7 @@ namespace Duplicati.Library.Utility
|
||||
/// <summary>
|
||||
/// The regular expression that matches %20 type values in a querystring
|
||||
/// </summary>
|
||||
private static System.Text.RegularExpressions.Regex RE_NUMBER = new System.Text.RegularExpressions.Regex(@"(\%(?<number>([0-9]|[a-z]|[A-Z]){2}))|(\+)|(\%u(?<number>([0-9]|[a-z]|[A-Z]){4}))", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// A helper for converting byte arrays to hex, vice versa
|
||||
/// </summary>
|
||||
private const string HEX_DIGITS_UPPER = "0123456789ABCDEF";
|
||||
private static System.Text.RegularExpressions.Regex RE_NUMBER = new System.Text.RegularExpressions.Regex(@"(\%(?<number>([0-9]|[a-f]|[A-F]){2}))|(\+)|(\%u(?<number>([0-9]|[a-f]|[A-F]){2,4,6,8}))", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a URL, like System.Web.HttpUtility.UrlEncode
|
||||
@@ -410,20 +398,20 @@ namespace Duplicati.Library.Utility
|
||||
encoding = encoding ?? System.Text.Encoding.UTF8;
|
||||
|
||||
var decoder = encoding.GetDecoder();
|
||||
var inbuf = new byte[2];
|
||||
var outbuf = new char[1];
|
||||
|
||||
return RE_NUMBER.Replace(value, (m) => {
|
||||
var inbuf = new byte[8];
|
||||
var outbuf = new char[8];
|
||||
|
||||
return RE_NUMBER.Replace(value, (m) => {
|
||||
if (m.Value == "+")
|
||||
return " ";
|
||||
|
||||
try
|
||||
{
|
||||
var hex = m.Groups["number"].Value;
|
||||
var bytelen = hex.Length / 2;
|
||||
Utility.HexStringAsByteArray(hex, inbuf);
|
||||
|
||||
decoder.GetChars(inbuf, 0, hex.Length / 2, outbuf, 0);
|
||||
return outbuf[0].ToString();
|
||||
var c = decoder.GetChars(inbuf, 0, bytelen, outbuf, 0);
|
||||
return new string(outbuf, 0, c);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -626,67 +626,29 @@ namespace Duplicati.Library.Utility
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A helper for converting byte arrays to hex, vice versa
|
||||
/// </summary>
|
||||
private const string HEX_DIGITS_UPPER = "0123456789ABCDEF";
|
||||
|
||||
/// <summary>
|
||||
/// Converts the byte array to hex digits
|
||||
/// Converts a sequence of bytes to a hex string
|
||||
/// </summary>
|
||||
/// <returns>The array as hex string.</returns>
|
||||
/// <param name="data">The data to convert</param>
|
||||
/// <returns>The data as a string of hex digits</returns>
|
||||
public static string ByteArrayAsHexString(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(byte b in data)
|
||||
{
|
||||
sb.Append(HEX_DIGITS_UPPER[(b >> 4) & 0xF]);
|
||||
sb.Append(HEX_DIGITS_UPPER[b & 0xF]);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
return BitConverter.ToString(data).Replace("-", string.Empty);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given hex string into a byte array
|
||||
/// Converts a hex string to a byte array
|
||||
/// </summary>
|
||||
/// <returns>The string as byte array.</returns>
|
||||
/// <param name="hex">The hex string</param>
|
||||
/// <param name="data">A pre-allocated output data array, or null</param>
|
||||
/// <returns>The byte array</returns>
|
||||
public static byte[] HexStringAsByteArray(string hex, byte[] data = null)
|
||||
/// <param name="data">The parsed data</param>
|
||||
public static byte[] HexStringAsByteArray(string hex, byte[] data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hex))
|
||||
return new byte[0];
|
||||
|
||||
hex = hex.Trim().ToUpper();
|
||||
|
||||
if (hex.Length % 2 != 0)
|
||||
throw new Exception(Strings.Utility.InvalidHexStringLengthError);
|
||||
|
||||
if (data == null)
|
||||
data = new byte[hex.Length / 2];
|
||||
else if (data.Length < hex.Length / 2)
|
||||
throw new ArgumentOutOfRangeException("data");
|
||||
|
||||
for(int i = 0; i < hex.Length; i+= 2)
|
||||
{
|
||||
int upper = HEX_DIGITS_UPPER.IndexOf(hex[i]);
|
||||
int lower = HEX_DIGITS_UPPER.IndexOf(hex[i + 1]);
|
||||
|
||||
if (upper < 0)
|
||||
throw new Exception(string.Format(Strings.Utility.InvalidHexDigitError, hex[i]));
|
||||
if (lower < 0)
|
||||
throw new Exception(string.Format(Strings.Utility.InvalidHexDigitError, hex[i + 1]));
|
||||
|
||||
data[i % 2] = (byte)((upper << 4) | lower);
|
||||
}
|
||||
for (var i = 0; i < hex.Length; i += 2)
|
||||
data[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static bool Which(string appname)
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Duplicati.Server.WebServer
|
||||
{
|
||||
response.Status = System.Net.HttpStatusCode.OK;
|
||||
response.Reason = "OK";
|
||||
response.ContentType = "text/html";
|
||||
response.ContentType = "text/html; charset=utf-8";
|
||||
|
||||
using (var fs = System.IO.File.OpenRead(m_defaultdoc))
|
||||
{
|
||||
|
||||
@@ -174,6 +174,8 @@ namespace Duplicati.Server.WebServer
|
||||
customized_files.MimeTypes.Add("htc", "text/x-component");
|
||||
customized_files.MimeTypes.Add("json", "application/json");
|
||||
customized_files.MimeTypes.Add("map", "application/json");
|
||||
customized_files.MimeTypes["htm"] = "text/html; charset=utf-8";
|
||||
customized_files.MimeTypes["html"] = "text/html; charset=utf-8";
|
||||
server.Add(customized_files);
|
||||
}
|
||||
|
||||
@@ -182,13 +184,14 @@ namespace Duplicati.Server.WebServer
|
||||
fh.MimeTypes.Add("htc", "text/x-component");
|
||||
fh.MimeTypes.Add("json", "application/json");
|
||||
fh.MimeTypes.Add("map", "application/json");
|
||||
fh.MimeTypes["htm"] = "text/html; charset=utf-8";
|
||||
fh.MimeTypes["html"] = "text/html; charset=utf-8";
|
||||
server.Add(fh);
|
||||
server.Add(new IndexHtmlHandler(System.IO.Path.Combine(webroot, "index.html")));
|
||||
#if DEBUG
|
||||
//For debugging, it is nice to know when we get a 404
|
||||
server.Add(new DebugReportHandler());
|
||||
#endif
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
http://webserver.codeplex.com/
|
||||
https://github.com/duplicati/httpserver
|
||||
Vendored
BIN
Binary file not shown.
-4
@@ -1,4 +0,0 @@
|
||||
The file HttpServer.dll has been patched from the tags/v1.1 version,
|
||||
to prevent a crash where multiple threads access the file collection on a form.
|
||||
|
||||
If you upgrade, make sure to apply the patch.
|
||||
@@ -1,31 +0,0 @@
|
||||
From 4ef5d02d06c5297469d814462daf6aa449628467 Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Skovhede <kenneth@hexad.dk>
|
||||
Date: Tue, 5 Aug 2014 10:06:31 +0200
|
||||
Subject: [PATCH] Fixed bug that causes FileModule to crash
|
||||
|
||||
---
|
||||
HttpServer/HttpModules/FileModule.cs | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/HttpServer/HttpModules/FileModule.cs b/HttpServer/HttpModules/FileModule.cs
|
||||
index 071fd01..8efa5a4 100755
|
||||
--- a/HttpServer/HttpModules/FileModule.cs
|
||||
+++ b/HttpServer/HttpModules/FileModule.cs
|
||||
@@ -120,10 +120,12 @@ namespace HttpServer.HttpModules
|
||||
{
|
||||
if (Contains(uri.AbsolutePath, _forbiddenChars))
|
||||
return false;
|
||||
-
|
||||
+
|
||||
+ if (!uri.AbsolutePath.StartsWith(_baseUri))
|
||||
+ return false;
|
||||
+
|
||||
string path = GetPath(uri);
|
||||
return
|
||||
- uri.AbsolutePath.StartsWith(_baseUri) && // Correct directory
|
||||
File.Exists(path) && // File exists
|
||||
(File.GetAttributes(path) & FileAttributes.ReparsePoint) == 0; // Not a symlink
|
||||
}
|
||||
--
|
||||
1.8.4.2
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "C# WebServer",
|
||||
"description": "A HTTP Compliant WebServer in C#",
|
||||
"link": "http://webserver.codeplex.com/",
|
||||
"link": "https://github.com/duplicati/httpserver",
|
||||
"license": "Apache 2.0",
|
||||
"notes": "Patched to fix a crash"
|
||||
"notes": "Patched from http://webserver.codeplex.com/"
|
||||
}
|
||||
-266
@@ -1,266 +0,0 @@
|
||||
From 4e4239cf74e23e13c3bee808104d8d213e40fe39 Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Skovhede <kenneth@hexad.dk>
|
||||
Date: Wed, 23 Jul 2014 15:04:20 +0200
|
||||
Subject: [PATCH] Removed usage of HttpUtility UrlEncode and
|
||||
HttpUtility.UrlDecode as these has issues on Mono.
|
||||
|
||||
---
|
||||
HttpServer/HttpHelper.cs | 2 +-
|
||||
HttpServer/HttpRequest.cs | 4 +-
|
||||
HttpServer/HttpServer.csproj | 1 +
|
||||
HttpServer/HttpUtilityHelper.cs | 171 ++++++++++++++++++++++++++++++++++++++++
|
||||
HttpServer/RequestCookie.cs | 2 +-
|
||||
HttpServer/ResponseCookie.cs | 2 +-
|
||||
6 files changed, 177 insertions(+), 5 deletions(-)
|
||||
create mode 100644 HttpServer/HttpUtilityHelper.cs
|
||||
|
||||
diff --git a/HttpServer/HttpHelper.cs b/HttpServer/HttpHelper.cs
|
||||
index 8d11daa..a0d286f 100755
|
||||
--- a/HttpServer/HttpHelper.cs
|
||||
+++ b/HttpServer/HttpHelper.cs
|
||||
@@ -165,7 +165,7 @@ namespace HttpServer
|
||||
|
||||
private static void Add(IHttpInput input, string name, string value)
|
||||
{
|
||||
- input.Add(HttpUtility.UrlDecode(name), HttpUtility.UrlDecode(value));
|
||||
+ input.Add(HttpUtilityHelper.UrlDecode(name), HttpUtilityHelper.UrlDecode(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/HttpServer/HttpRequest.cs b/HttpServer/HttpRequest.cs
|
||||
index a52dbed..cacbb7d 100755
|
||||
--- a/HttpServer/HttpRequest.cs
|
||||
+++ b/HttpServer/HttpRequest.cs
|
||||
@@ -54,12 +54,12 @@ namespace HttpServer
|
||||
_queryString = HttpHelper.ParseQueryString(_uriPath.Substring(pos + 1));
|
||||
_param.SetQueryString(_queryString);
|
||||
string path = _uriPath.Substring(0, pos);
|
||||
- _uriPath = System.Web.HttpUtility.UrlDecode(path) + "?" + _uriPath.Substring(pos + 1);
|
||||
+ _uriPath = HttpUtilityHelper.UrlDecode(path) + "?" + _uriPath.Substring(pos + 1);
|
||||
UriParts = value.Substring(0, pos).Split(UriSplitters, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
else
|
||||
{
|
||||
- _uriPath = System.Web.HttpUtility.UrlDecode(_uriPath);
|
||||
+ _uriPath = HttpUtilityHelper.UrlDecode(_uriPath);
|
||||
UriParts = value.Split(UriSplitters, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
diff --git a/HttpServer/HttpServer.csproj b/HttpServer/HttpServer.csproj
|
||||
index 81bb2eb..431c406 100644
|
||||
--- a/HttpServer/HttpServer.csproj
|
||||
+++ b/HttpServer/HttpServer.csproj
|
||||
@@ -134,6 +134,7 @@
|
||||
<Compile Include="Sessions\MemorySessionStore.cs" />
|
||||
<Compile Include="Templates\SmartyEngine.cs" />
|
||||
<Compile Include="Templates\TemplateEngine.cs" />
|
||||
+ <Compile Include="HttpUtilityHelper.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
diff --git a/HttpServer/HttpUtilityHelper.cs b/HttpServer/HttpUtilityHelper.cs
|
||||
new file mode 100644
|
||||
index 0000000..9f63b1c
|
||||
--- /dev/null
|
||||
+++ b/HttpServer/HttpUtilityHelper.cs
|
||||
@@ -0,0 +1,171 @@
|
||||
+using System;
|
||||
+using System.Collections.Specialized;
|
||||
+
|
||||
+namespace HttpServer
|
||||
+{
|
||||
+ public static class HttpUtilityHelper
|
||||
+ {
|
||||
+ /// <summary>
|
||||
+ /// The regular expression that matches %20 type values in a querystring
|
||||
+ /// </summary>
|
||||
+ private static System.Text.RegularExpressions.Regex RE_ESCAPECHAR = new System.Text.RegularExpressions.Regex(@"[^0-9a-zA-Z]", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Encodes a URL, like System.Web.HttpUtility.UrlEncode
|
||||
+ /// </summary>
|
||||
+ /// <returns>The encoded URL</returns>
|
||||
+ /// <param name="value">The URL fragment to encode</param>
|
||||
+ /// <param name="encoding">The encoding to use</param>
|
||||
+ public static string UrlPathEncode(string value, System.Text.Encoding encoding = null)
|
||||
+ {
|
||||
+ return UrlEncode(value, encoding, "%20");
|
||||
+ }
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Converts a sequence of bytes to a hex string
|
||||
+ /// </summary>
|
||||
+ /// <returns>The array as hex string.</returns>
|
||||
+ /// <param name="data">The data to convert</param>
|
||||
+ private static string ByteArrayAsHexString(byte[] data)
|
||||
+ {
|
||||
+ return BitConverter.ToString(data).Replace("-", string.Empty);
|
||||
+ }
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Converts a hex string to a byte array
|
||||
+ /// </summary>
|
||||
+ /// <returns>The string as byte array.</returns>
|
||||
+ /// <param name="hex">The hex string</param>
|
||||
+ /// <param name="data">The parsed data</param>
|
||||
+ public static byte[] HexStringAsByteArray(string hex, byte[] data)
|
||||
+ {
|
||||
+ for (var i = 0; i < hex.Length; i += 2)
|
||||
+ data[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
|
||||
+
|
||||
+ return data;
|
||||
+ }
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Encodes a URL, like System.Web.HttpUtility.UrlEncode
|
||||
+ /// </summary>
|
||||
+ /// <returns>The encoded URL</returns>
|
||||
+ /// <param name="value">The URL fragment to encode</param>
|
||||
+ /// <param name="encoding">The encoding to use</param>
|
||||
+ /// <param name="spacevalue">The value to encode a space as</param>
|
||||
+ public static string UrlEncode(string value, System.Text.Encoding encoding = null, string spacevalue = "+")
|
||||
+ {
|
||||
+ if (value == null)
|
||||
+ throw new ArgumentNullException("value");
|
||||
+
|
||||
+ encoding = encoding ?? System.Text.Encoding.UTF8;
|
||||
+
|
||||
+ var encoder = encoding.GetEncoder();
|
||||
+ var inbuf = new char[1];
|
||||
+ var outbuf = new byte[2];
|
||||
+ var shortout = new byte[1];
|
||||
+
|
||||
+ return RE_ESCAPECHAR.Replace(value, (m) => {
|
||||
+ if (m.Value == " ")
|
||||
+ return spacevalue;
|
||||
+
|
||||
+ inbuf[0] = m.Value[0];
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ var len = encoder.GetBytes(inbuf, 0, 1, outbuf, 0, true);
|
||||
+ if (len == 1)
|
||||
+ {
|
||||
+ shortout[0] = outbuf[0];
|
||||
+ return "%" + ByteArrayAsHexString(shortout).ToLower();
|
||||
+ }
|
||||
+ else if (len == 2)
|
||||
+ return "%u" + ByteArrayAsHexString(outbuf).ToLower();
|
||||
+ }
|
||||
+ catch
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ //Fallback
|
||||
+ return m.Value;
|
||||
+ });
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// The regular expression that matches %20 type values in a querystring
|
||||
+ /// </summary>
|
||||
+ private static System.Text.RegularExpressions.Regex RE_NUMBER = new System.Text.RegularExpressions.Regex(@"(\%(?<number>([0-9]|[a-z]|[A-Z]){2}))|(\+)|(\%u(?<number>([0-9]|[a-z]|[A-Z]){4}))", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// A helper for converting byte arrays to hex, vice versa
|
||||
+ /// </summary>
|
||||
+ private const string HEX_DIGITS_UPPER = "0123456789ABCDEF";
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Encodes a URL, like System.Web.HttpUtility.UrlEncode
|
||||
+ /// </summary>
|
||||
+ /// <returns>The decoded URL</returns>
|
||||
+ /// <param name="url">The URL fragment to decode</param>
|
||||
+ /// <param name="encoding">The encoding to use</param>
|
||||
+ public static string UrlDecode(string value, System.Text.Encoding encoding = null)
|
||||
+ {
|
||||
+ if (value == null)
|
||||
+ throw new ArgumentNullException("value");
|
||||
+
|
||||
+ encoding = encoding ?? System.Text.Encoding.UTF8;
|
||||
+
|
||||
+ var decoder = encoding.GetDecoder();
|
||||
+ var inbuf = new byte[2];
|
||||
+ var outbuf = new char[1];
|
||||
+
|
||||
+ return RE_NUMBER.Replace(value, (m) => {
|
||||
+ if (m.Value == "+")
|
||||
+ return " ";
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ var hex = m.Groups["number"].Value;
|
||||
+ HexStringAsByteArray(hex, inbuf);
|
||||
+
|
||||
+ decoder.GetChars(inbuf, 0, hex.Length / 2, outbuf, 0);
|
||||
+ return outbuf[0].ToString();
|
||||
+ }
|
||||
+ catch
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ //Fallback
|
||||
+ return m.Value;
|
||||
+ });
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// The regular expression that matches a=b type values in a querystring
|
||||
+ /// </summary>
|
||||
+ private static System.Text.RegularExpressions.Regex RE_URLPARAM = new System.Text.RegularExpressions.Regex(@"(?<key>[^\=\&]+)(\=(?<value>[^\&]*))?", System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Parses the query string.
|
||||
+ /// This is a duplicate of the System.Web.HttpUtility.ParseQueryString that does not work well on Mono
|
||||
+ /// </summary>
|
||||
+ /// <returns>The parsed query string</returns>
|
||||
+ /// <param name="query">The query to parse</param>
|
||||
+ public static NameValueCollection ParseQueryString(string query)
|
||||
+ {
|
||||
+ if (query == null)
|
||||
+ throw new ArgumentNullException("query");
|
||||
+ if (query.StartsWith("?"))
|
||||
+ query = query.Substring(1);
|
||||
+ if (string.IsNullOrEmpty(query))
|
||||
+ return new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);
|
||||
+
|
||||
+ var result = new NameValueCollection(StringComparer.InvariantCultureIgnoreCase);
|
||||
+ foreach(System.Text.RegularExpressions.Match m in RE_URLPARAM.Matches(query))
|
||||
+ result.Add(UrlDecode(m.Groups["key"].Value), UrlDecode(m.Groups["value"].Success ? m.Groups["value"].Value : ""));
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
diff --git a/HttpServer/RequestCookie.cs b/HttpServer/RequestCookie.cs
|
||||
index 5db5b3e..2deb448 100755
|
||||
--- a/HttpServer/RequestCookie.cs
|
||||
+++ b/HttpServer/RequestCookie.cs
|
||||
@@ -37,7 +37,7 @@ namespace HttpServer
|
||||
/// <returns>cookie string</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
- return string.Format("{0}={1}; ", HttpUtility.UrlEncode(_name), HttpUtility.UrlEncode(_value));
|
||||
+ return string.Format("{0}={1}; ", HttpUtilityHelper.UrlEncode(_name), HttpUtilityHelper.UrlEncode(_value));
|
||||
}
|
||||
|
||||
#endregion
|
||||
diff --git a/HttpServer/ResponseCookie.cs b/HttpServer/ResponseCookie.cs
|
||||
index 53c38aa..8fddee6 100755
|
||||
--- a/HttpServer/ResponseCookie.cs
|
||||
+++ b/HttpServer/ResponseCookie.cs
|
||||
@@ -70,7 +70,7 @@ namespace HttpServer
|
||||
/// <returns>cookie string</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
- string temp = string.Format("{0}={1}; ", HttpUtility.UrlEncode(Name), HttpUtility.UrlEncode(Value));
|
||||
+ string temp = string.Format("{0}={1}; ", HttpUtilityHelper.UrlEncode(Name), HttpUtilityHelper.UrlEncode(Value));
|
||||
if (_persistant)
|
||||
{
|
||||
// Fixed by Albert, Team MediaPortal
|
||||
--
|
||||
1.8.4.2
|
||||
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
From 5632607b6b15623849efb64ac2e93a62766c6ff3 Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Skovhede <kenneth@hexad.dk>
|
||||
Date: Wed, 23 Jul 2014 15:03:38 +0200
|
||||
Subject: [PATCH] Changed to use Duplicati key-file for signing
|
||||
|
||||
---
|
||||
HttpServer.sln | 10 +++++-----
|
||||
HttpServer/Duplicati.snk | Bin 0 -> 596 bytes
|
||||
HttpServer/HttpServer.csproj | 21 +++++++++++----------
|
||||
HttpServer/httpserver.pfx | Bin 1756 -> 0 bytes
|
||||
HttpServer/test.snk | Bin 596 -> 0 bytes
|
||||
5 files changed, 16 insertions(+), 15 deletions(-)
|
||||
create mode 100644 HttpServer/Duplicati.snk
|
||||
mode change 100755 => 100644 HttpServer/HttpServer.csproj
|
||||
delete mode 100755 HttpServer/httpserver.pfx
|
||||
delete mode 100755 HttpServer/test.snk
|
||||
|
||||
diff --git a/HttpServer.sln b/HttpServer.sln
|
||||
index c725924..a398e46 100644
|
||||
--- a/HttpServer.sln
|
||||
+++ b/HttpServer.sln
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
-Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
-# Visual Studio 2008
|
||||
+Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
+# Visual C# Express 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpServer", "HttpServer\HttpServer.csproj", "{455E7D70-1C85-4D7F-9F01-DC801B8B8C34}"
|
||||
EndProject
|
||||
Global
|
||||
@@ -17,10 +17,10 @@ Global
|
||||
{455E7D70-1C85-4D7F-9F01-DC801B8B8C34}.Test|Any CPU.ActiveCfg = Test|Any CPU
|
||||
{455E7D70-1C85-4D7F-9F01-DC801B8B8C34}.Test|Any CPU.Build.0 = Test|Any CPU
|
||||
EndGlobalSection
|
||||
- GlobalSection(MonoDevelopProperties) = preSolution
|
||||
- StartupItem = HttpServer\HttpServer.csproj
|
||||
- EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
+ GlobalSection(MonoDevelopProperties) = preSolution
|
||||
+ StartupItem = HttpServer\HttpServer.csproj
|
||||
+ EndGlobalSection
|
||||
EndGlobal
|
||||
diff --git a/HttpServer/Duplicati.snk b/HttpServer/Duplicati.snk
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e0c1e2dd86119728adaeefc5f14f2e597dabceeb
|
||||
GIT binary patch
|
||||
literal 596
|
||||
zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098e&YbeASI`aP2sa|^c*=Vgk~YB=15kLM
|
||||
z6B<YiWvwUE<(|pH%%wkswD9()^!1)?2<TO8%B4*tiA_O)JKtg3mYe#cEJRtAufRSd
|
||||
zp*O}dkA17H>le7?%rzf5lQi@8^2-|;@G9`<QW0-U-++qMA2UFqpl}*gRm+5<rR$#Y
|
||||
z`mC{oH`rBPm}y-b_=)eQ2xg6URklBIbvh;{sNYL`<5N!9%-k?#uBsQ+{OJEkI<Qwb
|
||||
z$|So|iI{;k686jCQ4Xb|;Kg7tg$P&|hZ52cQ8GHhE-`7YH<B}PJcp9|;2l9FD)bZm
|
||||
zXJ`R;(~ORzX0|XIrrQe+4<giBvUkU^;DeIXTj(<Trrrjq61ReBH|bqmNj^sJ@e7zu
|
||||
z3qYe`6@Gbj2toJ^pr#9(UP@|$CVA3uW~aDv8qPOSV(0-u0WeznB_NK-10qV7)e?Z|
|
||||
z@pRLiRcQW<BjMtoX%$E@W{Zn5E@K|AID>V-z=FMF_PcZSs*&!F`tUQUDaR;O!QV57
|
||||
zcL#UCLy6{4TM42#Sq8wU(0JEJwaKaO08k_-0(e*zaa9dM^Ns<3pXG+PwGl!LEd7mN
|
||||
zppXdDRR2f;AT-tHwTXQzHH^`&uIWnZ%w;A3xd8awj#n6GqmX}=Pk0ssHUW#6fQ#+z
|
||||
z_S|XnhcE>JGe7M>W()k5s}qyKQA=h=DrsUx<aA#JIm;D(`F7OE$J+;dTnocY;8v;M
|
||||
i+Wck*xKNK{xU`2iSPLjN<SzIp{9kbAxOXkZB3*11JsH9P
|
||||
|
||||
literal 0
|
||||
HcmV?d00001
|
||||
|
||||
diff --git a/HttpServer/HttpServer.csproj b/HttpServer/HttpServer.csproj
|
||||
old mode 100755
|
||||
new mode 100644
|
||||
index 576e62a..81bb2eb
|
||||
--- a/HttpServer/HttpServer.csproj
|
||||
+++ b/HttpServer/HttpServer.csproj
|
||||
@@ -1,23 +1,23 @@
|
||||
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="2.0">
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
- <ProductVersion>9.0.30729</ProductVersion>
|
||||
+ <ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{455E7D70-1C85-4D7F-9F01-DC801B8B8C34}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>HttpServer</RootNamespace>
|
||||
<AssemblyName>HttpServer</AssemblyName>
|
||||
- <StartupObject>
|
||||
- </StartupObject>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
- <AssemblyOriginatorKeyFile>test.snk</AssemblyOriginatorKeyFile>
|
||||
+ <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
- <OldToolsVersion>2.0</OldToolsVersion>
|
||||
+ <OldToolsVersion>3.5</OldToolsVersion>
|
||||
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -46,6 +46,8 @@
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
+ <WarningLevel>4</WarningLevel>
|
||||
+ <Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
@@ -133,10 +135,6 @@
|
||||
<Compile Include="Templates\SmartyEngine.cs" />
|
||||
<Compile Include="Templates\TemplateEngine.cs" />
|
||||
</ItemGroup>
|
||||
- <ItemGroup>
|
||||
- <None Include="httpserver.pfx" />
|
||||
- <None Include="test.snk" />
|
||||
- </ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
@@ -145,4 +143,7 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
+ <ItemGroup>
|
||||
+ <None Include="Duplicati.snk" />
|
||||
+ </ItemGroup>
|
||||
</Project>
|
||||
\ No newline at end of file
|
||||
diff --git a/HttpServer/httpserver.pfx b/HttpServer/httpserver.pfx
|
||||
deleted file mode 100755
|
||||
index 2ba33088b51785a8dbf88106abf0ec3dd7a54994..0000000000000000000000000000000000000000
|
||||
GIT binary patch
|
||||
literal 0
|
||||
HcmV?d00001
|
||||
|
||||
literal 1756
|
||||
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
|
||||
|
||||
diff --git a/HttpServer/test.snk b/HttpServer/test.snk
|
||||
deleted file mode 100755
|
||||
index 8da3182b4ebfb542507eb7ef48ffbfce2bf3995b..0000000000000000000000000000000000000000
|
||||
GIT binary patch
|
||||
literal 0
|
||||
HcmV?d00001
|
||||
|
||||
literal 596
|
||||
zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097bzgeh{8PZA&elL^}7m-6lG|{kbaa9P5
|
||||
z6e@YDGh=|GP9%|kZDq^AxDp8i8ol~tW*zyPCUH^Y0q!HZ`nqyF+b?rNIuOl6sJ%lW
|
||||
zlMb&1^h=-twO35$90By~P4G-7iifzzpVSD}Bs+gQv@iL2u8^ioiXa*UMGvLryokaD
|
||||
zUd}+4OdXNRIo<d9Psku(J*E_#SphiN7^Uo}%XJej*FLvAz~w@6Ba=e$`J_&=(mOtw
|
||||
z`_j<^FX;6A5~lOzA??rdf9H|oGE}qP%M{roR}vb-PiO8rA-NWirc`DaVe&@lqt6M0
|
||||
zNYTev1im3KTiiGLf_?ECRq8OoNM+0oKL+y@NhJxZ&|w*?*^T!;j>ng?<<6!9K$)!7
|
||||
zByqNO1qp1^_%$`#e+>@`pd;RK{7uWBj<2KCFZnO%#TTJDxSw+v(~D(u#{CaVH$Nxr
|
||||
zzyiIV;fL=Bs+Gq!@zn0M*%Ne)SNZFA@!M-ZJ$2Q%<cUXT9{m^1JbQUGTQkK}SAHIt
|
||||
zuVP~u36&u3fOR<Ec(#28TfDQ!b+a|eFU2`@f4)(wJ=UfqtnhiWMfz%!2n&+JO=N=4
|
||||
zRsK9!_0wHJqo`jldFP~oDN-(;rSGAEZ_fU(hUt$Zf%3o7<{(V?N>g3NUhR!8qA0#}
|
||||
zSJY#IGkNY<GBvgO-4-YSKpvY^NzV=oMVg+V=>v4L$XLA)9v59%3fY#qPdXYvdKy)H
|
||||
iTkg*w>*3ZPja^HsjVZRb<eow3IYN|8+vu9umTNsdQXNqM
|
||||
|
||||
--
|
||||
1.8.4.2
|
||||
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
From e7be6967b6d14b5cca67018dd1a30e4fc302001a Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Skovhede <kenneth@hexad.dk>
|
||||
Date: Sat, 28 Jun 2014 16:52:33 +0200
|
||||
Subject: [PATCH] Fixed Tempfolder to use the system tempfolder instead of
|
||||
hardcoded /var/tmp
|
||||
|
||||
---
|
||||
HttpServer/FormDecoders/MultipartDecoder.cs | 12 +++++++-----
|
||||
HttpServer/HttpServer.cs | 10 ++++++----
|
||||
2 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/HttpServer/FormDecoders/MultipartDecoder.cs b/HttpServer/FormDecoders/MultipartDecoder.cs
|
||||
index b4a6dbb..6da4967 100755
|
||||
--- a/HttpServer/FormDecoders/MultipartDecoder.cs
|
||||
+++ b/HttpServer/FormDecoders/MultipartDecoder.cs
|
||||
@@ -22,6 +22,12 @@ namespace HttpServer.FormDecoders
|
||||
/// form-data
|
||||
/// </summary>
|
||||
public const string FormData = "form-data";
|
||||
+
|
||||
+ /// <summary>
|
||||
+ /// Gets the temp folder used to store multi-part uploads
|
||||
+ /// </summary>
|
||||
+ public static readonly string Tempfolder = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "HttpServer");
|
||||
+
|
||||
#region IFormDecoder Members
|
||||
|
||||
/// <summary>
|
||||
@@ -73,11 +79,7 @@ namespace HttpServer.FormDecoders
|
||||
|
||||
// Generate a filename
|
||||
string filename = element.Filename;
|
||||
- string internetCache = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
|
||||
- // if the internet path doesn't exist, assume mono and /var/tmp
|
||||
- string path = string.IsNullOrEmpty(internetCache)
|
||||
- ? Path.Combine("var", "tmp")
|
||||
- : Path.Combine(internetCache.Replace("\\\\", "\\"), "tmp");
|
||||
+ string path = Tempfolder;
|
||||
element.Filename = Path.Combine(path, Math.Abs(element.Filename.GetHashCode()) + ".tmp");
|
||||
|
||||
// If the file exists generate a new filename
|
||||
diff --git a/HttpServer/HttpServer.cs b/HttpServer/HttpServer.cs
|
||||
index 9dd4215..4ecf16a 100755
|
||||
--- a/HttpServer/HttpServer.cs
|
||||
+++ b/HttpServer/HttpServer.cs
|
||||
@@ -476,15 +476,17 @@ namespace HttpServer
|
||||
_components.AddInstance<IHttpContextFactory>(new HttpContextFactory(LogWriter, 16384,
|
||||
_components.Get<IRequestParserFactory>()));
|
||||
|
||||
- // the special folder does not exist on mono
|
||||
- string tempPath = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
|
||||
- if (string.IsNullOrEmpty(tempPath))
|
||||
- tempPath = "/var/tmp/";
|
||||
+ string tempPath = System.IO.Path.GetTempPath();
|
||||
if (!Directory.Exists(tempPath))
|
||||
{
|
||||
WriteLog(this, LogPrio.Warning, "Temp path do not exist: " + tempPath);
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ tempPath = MultipartDecoder.Tempfolder;
|
||||
+ if (!Directory.Exists(tempPath))
|
||||
+ Directory.CreateDirectory(tempPath);
|
||||
+
|
||||
DirectoryInfo info = new DirectoryInfo(tempPath);
|
||||
foreach (FileInfo file in info.GetFiles("*.tmp"))
|
||||
file.Delete();
|
||||
--
|
||||
1.8.4.2
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
diff -urN webserver-clean/HttpServer/HttpForm.cs webserver-modified/HttpServer/HttpForm.cs
|
||||
--- webserver-clean/HttpServer/HttpForm.cs 2014-01-10 12:08:32.000000000 +0100
|
||||
+++ webserver-modified/HttpServer/HttpForm.cs 2014-01-18 23:32:04.000000000 +0100
|
||||
@@ -10,6 +10,9 @@
|
||||
public static readonly HttpForm EmptyForm = new HttpForm("EmptyForm", true);
|
||||
|
||||
private readonly Dictionary<string, HttpFile> _files = new Dictionary<string, HttpFile>();
|
||||
+
|
||||
+ // A lock to prevent concurrent access to the _files dict
|
||||
+ private object _lock = new object();
|
||||
|
||||
/// <summary>Initializes a form container with the specified name</summary>
|
||||
public HttpForm() : base("form")
|
||||
@@ -45,7 +48,8 @@
|
||||
if(_files.ContainsKey(file.Name))
|
||||
throw new ArgumentException("File named '" + file.Name + "' already exists!");
|
||||
|
||||
- _files.Add(file.Name, file);
|
||||
+ lock(_lock)
|
||||
+ _files.Add(file.Name, file);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,16 +76,19 @@
|
||||
/// <exception cref="ArgumentNullException">If name is null or empty</exception>
|
||||
/// <exception cref="InvalidOperationException">If the instance is HttpForm.EmptyForm which cannot be modified</exception>
|
||||
public HttpFile GetFile(string name)
|
||||
- {
|
||||
- if (_ignoreChanges)
|
||||
- throw new InvalidOperationException("Cannot retrieve files from instance HttpForm.EmptyForm.");
|
||||
- if(string.IsNullOrEmpty(name))
|
||||
- throw new ArgumentNullException("name");
|
||||
+ {
|
||||
+ if (_ignoreChanges)
|
||||
+ throw new InvalidOperationException("Cannot retrieve files from instance HttpForm.EmptyForm.");
|
||||
+ if (string.IsNullOrEmpty(name))
|
||||
+ throw new ArgumentNullException("name");
|
||||
|
||||
- if(!_files.ContainsKey(name))
|
||||
- return null;
|
||||
+ lock(_lock)
|
||||
+ {
|
||||
+ if (!_files.ContainsKey(name))
|
||||
+ return null;
|
||||
|
||||
- return _files[name];
|
||||
+ return _files[name];
|
||||
+ }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -95,10 +102,13 @@
|
||||
if (_files.Count == 0)
|
||||
return EmptyFileCollection;
|
||||
|
||||
- List<HttpFile> files = new List<HttpFile>();
|
||||
- foreach (HttpFile file in _files.Values)
|
||||
- files.Add(file);
|
||||
- return files.AsReadOnly();
|
||||
+ lock(_lock)
|
||||
+ {
|
||||
+ List<HttpFile> files = new List<HttpFile>();
|
||||
+ foreach(HttpFile file in _files.Values)
|
||||
+ files.Add(file);
|
||||
+ return files.AsReadOnly();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,13 +116,16 @@
|
||||
|
||||
/// <summary>Disposes all held HttpFile's and resets values</summary>
|
||||
public override void Clear()
|
||||
- {
|
||||
- base.Clear();
|
||||
+ {
|
||||
+ base.Clear();
|
||||
|
||||
- foreach (KeyValuePair<string, HttpFile> pair in _files)
|
||||
- pair.Value.Dispose();
|
||||
+ lock(_lock)
|
||||
+ {
|
||||
+ foreach(KeyValuePair<string, HttpFile> pair in _files)
|
||||
+ pair.Value.Dispose();
|
||||
|
||||
- _files.Clear();
|
||||
+ _files.Clear();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user