|
|
|
@ -5,31 +5,11 @@ using System.Globalization; |
|
|
|
using System.IO; |
|
|
|
using System.Security.Permissions; |
|
|
|
using System.Text; |
|
|
|
using System.Web.Util; |
|
|
|
|
|
|
|
namespace Avalonia.Shared.PlatformSupport |
|
|
|
{ |
|
|
|
public sealed class HttpUtility |
|
|
|
{ |
|
|
|
sealed class HttpQSCollection : NameValueCollection |
|
|
|
{ |
|
|
|
public override string ToString() |
|
|
|
{ |
|
|
|
int count = Count; |
|
|
|
if (count == 0) |
|
|
|
return ""; |
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
string[] keys = AllKeys; |
|
|
|
for (int i = 0; i < count; i++) |
|
|
|
{ |
|
|
|
sb.AppendFormat("{0}={1}&", keys[i], UrlEncode(this[keys[i]])); |
|
|
|
} |
|
|
|
if (sb.Length > 0) |
|
|
|
sb.Length--; |
|
|
|
return sb.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#region Constructors
|
|
|
|
|
|
|
|
public HttpUtility() |
|
|
|
@ -40,27 +20,6 @@ namespace Avalonia.Shared.PlatformSupport |
|
|
|
|
|
|
|
#region Methods
|
|
|
|
|
|
|
|
public static void HtmlAttributeEncode(string s, TextWriter output) |
|
|
|
{ |
|
|
|
if (output == null) |
|
|
|
{ |
|
|
|
throw new ArgumentNullException("output"); |
|
|
|
} |
|
|
|
HttpEncoder.Current.HtmlAttributeEncode(s, output); |
|
|
|
} |
|
|
|
|
|
|
|
public static string HtmlAttributeEncode(string s) |
|
|
|
{ |
|
|
|
if (s == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
using (var sw = new StringWriter()) |
|
|
|
{ |
|
|
|
HttpEncoder.Current.HtmlAttributeEncode(s, sw); |
|
|
|
return sw.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static string UrlDecode(string str) |
|
|
|
{ |
|
|
|
return UrlDecode(str, Encoding.UTF8); |
|
|
|
@ -330,364 +289,6 @@ namespace Avalonia.Shared.PlatformSupport |
|
|
|
|
|
|
|
return result.ToArray(); |
|
|
|
} |
|
|
|
|
|
|
|
public static string UrlEncode(string str) |
|
|
|
{ |
|
|
|
return UrlEncode(str, Encoding.UTF8); |
|
|
|
} |
|
|
|
|
|
|
|
public static string UrlEncode(string str, Encoding e) |
|
|
|
{ |
|
|
|
if (str == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
if (str == String.Empty) |
|
|
|
return String.Empty; |
|
|
|
|
|
|
|
bool needEncode = false; |
|
|
|
int len = str.Length; |
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
char c = str[i]; |
|
|
|
if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) |
|
|
|
{ |
|
|
|
if (HttpEncoder.NotEncoded(c)) |
|
|
|
continue; |
|
|
|
|
|
|
|
needEncode = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!needEncode) |
|
|
|
return str; |
|
|
|
|
|
|
|
// avoided GetByteCount call
|
|
|
|
byte[] bytes = new byte[e.GetMaxByteCount(str.Length)]; |
|
|
|
int realLen = e.GetBytes(str, 0, str.Length, bytes, 0); |
|
|
|
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, realLen)); |
|
|
|
} |
|
|
|
|
|
|
|
public static string UrlEncode(byte[] bytes) |
|
|
|
{ |
|
|
|
if (bytes == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
if (bytes.Length == 0) |
|
|
|
return String.Empty; |
|
|
|
|
|
|
|
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, bytes.Length)); |
|
|
|
} |
|
|
|
|
|
|
|
public static string UrlEncode(byte[] bytes, int offset, int count) |
|
|
|
{ |
|
|
|
if (bytes == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
if (bytes.Length == 0) |
|
|
|
return String.Empty; |
|
|
|
|
|
|
|
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count)); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] UrlEncodeToBytes(string str) |
|
|
|
{ |
|
|
|
return UrlEncodeToBytes(str, Encoding.UTF8); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] UrlEncodeToBytes(string str, Encoding e) |
|
|
|
{ |
|
|
|
if (str == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
if (str.Length == 0) |
|
|
|
return new byte[0]; |
|
|
|
|
|
|
|
byte[] bytes = e.GetBytes(str); |
|
|
|
return UrlEncodeToBytes(bytes, 0, bytes.Length); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] UrlEncodeToBytes(byte[] bytes) |
|
|
|
{ |
|
|
|
if (bytes == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
if (bytes.Length == 0) |
|
|
|
return new byte[0]; |
|
|
|
|
|
|
|
return UrlEncodeToBytes(bytes, 0, bytes.Length); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) |
|
|
|
{ |
|
|
|
if (bytes == null) |
|
|
|
return null; |
|
|
|
return HttpEncoder.Current.UrlEncode(bytes, offset, count); |
|
|
|
} |
|
|
|
|
|
|
|
public static string UrlEncodeUnicode(string str) |
|
|
|
{ |
|
|
|
if (str == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
return Encoding.ASCII.GetString(UrlEncodeUnicodeToBytes(str)); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] UrlEncodeUnicodeToBytes(string str) |
|
|
|
{ |
|
|
|
if (str == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
if (str.Length == 0) |
|
|
|
return new byte[0]; |
|
|
|
|
|
|
|
MemoryStream result = new MemoryStream(str.Length); |
|
|
|
foreach (char c in str) |
|
|
|
{ |
|
|
|
HttpEncoder.UrlEncodeChar(c, result, true); |
|
|
|
} |
|
|
|
return result.ToArray(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Decodes an HTML-encoded string and returns the decoded string.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="s">The HTML string to decode. </param>
|
|
|
|
/// <returns>The decoded text.</returns>
|
|
|
|
public static string HtmlDecode(string s) |
|
|
|
{ |
|
|
|
if (s == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
using (var sw = new StringWriter()) |
|
|
|
{ |
|
|
|
HttpEncoder.Current.HtmlDecode(s, sw); |
|
|
|
return sw.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="s">The HTML string to decode</param>
|
|
|
|
/// <param name="output">The TextWriter output stream containing the decoded string. </param>
|
|
|
|
public static void HtmlDecode(string s, TextWriter output) |
|
|
|
{ |
|
|
|
if (output == null) |
|
|
|
{ |
|
|
|
throw new ArgumentNullException("output"); |
|
|
|
} |
|
|
|
|
|
|
|
if (!String.IsNullOrEmpty(s)) |
|
|
|
{ |
|
|
|
HttpEncoder.Current.HtmlDecode(s, output); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static string HtmlEncode(string s) |
|
|
|
{ |
|
|
|
if (s == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
using (var sw = new StringWriter()) |
|
|
|
{ |
|
|
|
HttpEncoder.Current.HtmlEncode(s, sw); |
|
|
|
return sw.ToString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="s">The string to encode. </param>
|
|
|
|
/// <param name="output">The TextWriter output stream containing the encoded string. </param>
|
|
|
|
public static void HtmlEncode(string s, TextWriter output) |
|
|
|
{ |
|
|
|
if (output == null) |
|
|
|
{ |
|
|
|
throw new ArgumentNullException("output"); |
|
|
|
} |
|
|
|
|
|
|
|
if (!String.IsNullOrEmpty(s)) |
|
|
|
{ |
|
|
|
HttpEncoder.Current.HtmlEncode(s, output); |
|
|
|
} |
|
|
|
} |
|
|
|
public static string HtmlEncode(object value) |
|
|
|
{ |
|
|
|
if (value == null) |
|
|
|
return null; |
|
|
|
|
|
|
|
#if !(MOBILE || NO_SYSTEM_WEB_DEPENDENCY)
|
|
|
|
IHtmlString htmlString = value as IHtmlString; |
|
|
|
if (htmlString != null) |
|
|
|
return htmlString.ToHtmlString(); |
|
|
|
#endif
|
|
|
|
|
|
|
|
return HtmlEncode(value.ToString()); |
|
|
|
} |
|
|
|
|
|
|
|
public static string JavaScriptStringEncode(string value) |
|
|
|
{ |
|
|
|
return JavaScriptStringEncode(value, false); |
|
|
|
} |
|
|
|
|
|
|
|
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes) |
|
|
|
{ |
|
|
|
if (String.IsNullOrEmpty(value)) |
|
|
|
return addDoubleQuotes ? "\"\"" : String.Empty; |
|
|
|
|
|
|
|
int len = value.Length; |
|
|
|
bool needEncode = false; |
|
|
|
char c; |
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
c = value[i]; |
|
|
|
|
|
|
|
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92) |
|
|
|
{ |
|
|
|
needEncode = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!needEncode) |
|
|
|
return addDoubleQuotes ? "\"" + value + "\"" : value; |
|
|
|
|
|
|
|
var sb = new StringBuilder(); |
|
|
|
if (addDoubleQuotes) |
|
|
|
sb.Append('"'); |
|
|
|
|
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
c = value[i]; |
|
|
|
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62) |
|
|
|
sb.AppendFormat("\\u{0:x4}", (int)c); |
|
|
|
else switch ((int)c) |
|
|
|
{ |
|
|
|
case 8: |
|
|
|
sb.Append("\\b"); |
|
|
|
break; |
|
|
|
|
|
|
|
case 9: |
|
|
|
sb.Append("\\t"); |
|
|
|
break; |
|
|
|
|
|
|
|
case 10: |
|
|
|
sb.Append("\\n"); |
|
|
|
break; |
|
|
|
|
|
|
|
case 12: |
|
|
|
sb.Append("\\f"); |
|
|
|
break; |
|
|
|
|
|
|
|
case 13: |
|
|
|
sb.Append("\\r"); |
|
|
|
break; |
|
|
|
|
|
|
|
case 34: |
|
|
|
sb.Append("\\\""); |
|
|
|
break; |
|
|
|
|
|
|
|
case 92: |
|
|
|
sb.Append("\\\\"); |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
sb.Append(c); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (addDoubleQuotes) |
|
|
|
sb.Append('"'); |
|
|
|
|
|
|
|
return sb.ToString(); |
|
|
|
} |
|
|
|
public static string UrlPathEncode(string str) |
|
|
|
{ |
|
|
|
return HttpEncoder.Current.UrlPathEncode(str); |
|
|
|
} |
|
|
|
|
|
|
|
public static NameValueCollection ParseQueryString(string query) |
|
|
|
{ |
|
|
|
return ParseQueryString(query, Encoding.UTF8); |
|
|
|
} |
|
|
|
|
|
|
|
public static NameValueCollection ParseQueryString(string query, Encoding encoding) |
|
|
|
{ |
|
|
|
if (query == null) |
|
|
|
throw new ArgumentNullException("query"); |
|
|
|
if (encoding == null) |
|
|
|
throw new ArgumentNullException("encoding"); |
|
|
|
if (query.Length == 0 || (query.Length == 1 && query[0] == '?')) |
|
|
|
return new HttpQSCollection(); |
|
|
|
if (query[0] == '?') |
|
|
|
query = query.Substring(1); |
|
|
|
|
|
|
|
NameValueCollection result = new HttpQSCollection(); |
|
|
|
ParseQueryString(query, encoding, result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
internal static void ParseQueryString(string query, Encoding encoding, NameValueCollection result) |
|
|
|
{ |
|
|
|
if (query.Length == 0) |
|
|
|
return; |
|
|
|
|
|
|
|
string decoded = HtmlDecode(query); |
|
|
|
int decodedLength = decoded.Length; |
|
|
|
int namePos = 0; |
|
|
|
bool first = true; |
|
|
|
while (namePos <= decodedLength) |
|
|
|
{ |
|
|
|
int valuePos = -1, valueEnd = -1; |
|
|
|
for (int q = namePos; q < decodedLength; q++) |
|
|
|
{ |
|
|
|
if (valuePos == -1 && decoded[q] == '=') |
|
|
|
{ |
|
|
|
valuePos = q + 1; |
|
|
|
} |
|
|
|
else if (decoded[q] == '&') |
|
|
|
{ |
|
|
|
valueEnd = q; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (first) |
|
|
|
{ |
|
|
|
first = false; |
|
|
|
if (decoded[namePos] == '?') |
|
|
|
namePos++; |
|
|
|
} |
|
|
|
|
|
|
|
string name, value; |
|
|
|
if (valuePos == -1) |
|
|
|
{ |
|
|
|
name = null; |
|
|
|
valuePos = namePos; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1), encoding); |
|
|
|
} |
|
|
|
if (valueEnd < 0) |
|
|
|
{ |
|
|
|
namePos = -1; |
|
|
|
valueEnd = decoded.Length; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
namePos = valueEnd + 1; |
|
|
|
} |
|
|
|
value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos), encoding); |
|
|
|
|
|
|
|
result.Add(name, value); |
|
|
|
if (namePos == -1) |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
#endregion // Methods
|
|
|
|
} |
|
|
|
} |
|
|
|
|