267 lines
11 KiB
Diff
267 lines
11 KiB
Diff
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
|
|||
|
|
|