HttpUtility.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // MIRROR CHANGE: drop in Codice.Utils HttpUtility subset to not depend on Unity's plastic scm package
  2. // SOURCE: Unity Plastic SCM package
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Collections.Specialized;
  7. using System.IO;
  8. using System.Text;
  9. namespace Edgegap.Codice.Utils // MIRROR CHANGE: namespace Edgegap.* to not collide if anyone has Plastic SCM installed already
  10. {
  11. public sealed class HttpUtility
  12. {
  13. private static void WriteCharBytes(IList buf, char ch, Encoding e)
  14. {
  15. if (ch > 'ÿ')
  16. {
  17. Encoding encoding = e;
  18. char[] chars = new char[1]{ ch };
  19. foreach (byte num in encoding.GetBytes(chars))
  20. buf.Add((object) num);
  21. }
  22. else
  23. buf.Add((object) (byte) ch);
  24. }
  25. public static string UrlDecode(string s, Encoding e)
  26. {
  27. if (null == s)
  28. return (string) null;
  29. if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1)
  30. return s;
  31. if (e == null)
  32. e = Encoding.UTF8;
  33. long length = (long) s.Length;
  34. List<byte> buf = new List<byte>();
  35. for (int index = 0; (long) index < length; ++index)
  36. {
  37. char ch = s[index];
  38. if (ch == '%' && (long) (index + 2) < length && s[index + 1] != '%')
  39. {
  40. if (s[index + 1] == 'u' && (long) (index + 5) < length)
  41. {
  42. int num = HttpUtility.GetChar(s, index + 2, 4);
  43. if (num != -1)
  44. {
  45. HttpUtility.WriteCharBytes((IList) buf, (char) num, e);
  46. index += 5;
  47. }
  48. else
  49. HttpUtility.WriteCharBytes((IList) buf, '%', e);
  50. }
  51. else
  52. {
  53. int num;
  54. if ((num = HttpUtility.GetChar(s, index + 1, 2)) != -1)
  55. {
  56. HttpUtility.WriteCharBytes((IList) buf, (char) num, e);
  57. index += 2;
  58. }
  59. else
  60. HttpUtility.WriteCharBytes((IList) buf, '%', e);
  61. }
  62. }
  63. else if (ch == '+')
  64. HttpUtility.WriteCharBytes((IList) buf, ' ', e);
  65. else
  66. HttpUtility.WriteCharBytes((IList) buf, ch, e);
  67. }
  68. byte[] array = buf.ToArray();
  69. return e.GetString(array);
  70. }
  71. private static int GetInt(byte b)
  72. {
  73. char ch = (char) b;
  74. if (ch >= '0' && ch <= '9')
  75. return (int) ch - 48;
  76. if (ch >= 'a' && ch <= 'f')
  77. return (int) ch - 97 + 10;
  78. return ch >= 'A' && ch <= 'F' ? (int) ch - 65 + 10 : -1;
  79. }
  80. private static int GetChar(string str, int offset, int length)
  81. {
  82. int num1 = 0;
  83. int num2 = length + offset;
  84. for (int index = offset; index < num2; ++index)
  85. {
  86. char b = str[index];
  87. if (b > '\u007F')
  88. return -1;
  89. int num3 = HttpUtility.GetInt((byte) b);
  90. if (num3 == -1)
  91. return -1;
  92. num1 = (num1 << 4) + num3;
  93. }
  94. return num1;
  95. }
  96. public static string UrlEncode(string str) => HttpUtility.UrlEncode(str, Encoding.UTF8);
  97. public static string UrlEncode(string s, Encoding Enc)
  98. {
  99. if (s == null)
  100. return (string) null;
  101. if (s == string.Empty)
  102. return string.Empty;
  103. bool flag = false;
  104. int length = s.Length;
  105. for (int index = 0; index < length; ++index)
  106. {
  107. char c = s[index];
  108. if ((c < '0' || c < 'A' && c > '9' || c > 'Z' && c < 'a' || c > 'z') && !HttpEncoder.NotEncoded(c))
  109. {
  110. flag = true;
  111. break;
  112. }
  113. }
  114. if (!flag)
  115. return s;
  116. byte[] bytes1 = new byte[Enc.GetMaxByteCount(s.Length)];
  117. int bytes2 = Enc.GetBytes(s, 0, s.Length, bytes1, 0);
  118. return Encoding.ASCII.GetString(HttpUtility.UrlEncodeToBytes(bytes1, 0, bytes2));
  119. }
  120. public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) => bytes == null ? (byte[]) null : HttpEncoder.Current.UrlEncode(bytes, offset, count);
  121. public static string HtmlDecode(string s)
  122. {
  123. if (s == null)
  124. return (string) null;
  125. using (StringWriter output = new StringWriter())
  126. {
  127. HttpEncoder.Current.HtmlDecode(s, (TextWriter) output);
  128. return output.ToString();
  129. }
  130. }
  131. public static NameValueCollection ParseQueryString(string query) => HttpUtility.ParseQueryString(query, Encoding.UTF8);
  132. public static NameValueCollection ParseQueryString(
  133. string query,
  134. Encoding encoding)
  135. {
  136. if (query == null)
  137. throw new ArgumentNullException(nameof (query));
  138. if (encoding == null)
  139. throw new ArgumentNullException(nameof (encoding));
  140. if (query.Length == 0 || query.Length == 1 && query[0] == '?')
  141. return (NameValueCollection) new HttpUtility.HttpQSCollection();
  142. if (query[0] == '?')
  143. query = query.Substring(1);
  144. NameValueCollection result = (NameValueCollection) new HttpUtility.HttpQSCollection();
  145. HttpUtility.ParseQueryString(query, encoding, result);
  146. return result;
  147. }
  148. internal static void ParseQueryString(
  149. string query,
  150. Encoding encoding,
  151. NameValueCollection result)
  152. {
  153. if (query.Length == 0)
  154. return;
  155. string str1 = HttpUtility.HtmlDecode(query);
  156. int length = str1.Length;
  157. int num1 = 0;
  158. bool flag = true;
  159. while (num1 <= length)
  160. {
  161. int startIndex = -1;
  162. int num2 = -1;
  163. for (int index = num1; index < length; ++index)
  164. {
  165. if (startIndex == -1 && str1[index] == '=')
  166. startIndex = index + 1;
  167. else if (str1[index] == '&')
  168. {
  169. num2 = index;
  170. break;
  171. }
  172. }
  173. if (flag)
  174. {
  175. flag = false;
  176. if (str1[num1] == '?')
  177. ++num1;
  178. }
  179. string name;
  180. if (startIndex == -1)
  181. {
  182. name = (string) null;
  183. startIndex = num1;
  184. }
  185. else
  186. name = HttpUtility.UrlDecode(str1.Substring(num1, startIndex - num1 - 1), encoding);
  187. if (num2 < 0)
  188. {
  189. num1 = -1;
  190. num2 = str1.Length;
  191. }
  192. else
  193. num1 = num2 + 1;
  194. string str2 = HttpUtility.UrlDecode(str1.Substring(startIndex, num2 - startIndex), encoding);
  195. result.Add(name, str2);
  196. if (num1 == -1)
  197. break;
  198. }
  199. }
  200. private sealed class HttpQSCollection : NameValueCollection
  201. {
  202. public override string ToString()
  203. {
  204. int count = this.Count;
  205. if (count == 0)
  206. return "";
  207. StringBuilder stringBuilder = new StringBuilder();
  208. string[] allKeys = this.AllKeys;
  209. for (int index = 0; index < count; ++index)
  210. stringBuilder.AppendFormat("{0}={1}&", (object) allKeys[index], (object) HttpUtility.UrlEncode(this[allKeys[index]]));
  211. if (stringBuilder.Length > 0)
  212. --stringBuilder.Length;
  213. return stringBuilder.ToString();
  214. }
  215. }
  216. }
  217. }