PageRenderTime 62ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/System.Web/HttpUtility.cs

https://bitbucket.org/cosi2/dotnetanywhere-wb
C# | 737 lines | 622 code | 97 blank | 18 comment | 168 complexity | 83ae6bcbd878af09b84943d213d41ae9 MD5 | raw file
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. //using System.Collections.Specialized;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Security.Permissions;
  7. using System.Text;
  8. using System.Web.Util;
  9. namespace System.Web
  10. {
  11. public class NameValueCollection : Dictionary<string, string>
  12. {
  13. }
  14. public sealed class HttpUtility
  15. {
  16. sealed class HttpQSCollection : NameValueCollection
  17. {
  18. public override string ToString()
  19. {
  20. int count = Count;
  21. if (count == 0)
  22. return "";
  23. StringBuilder sb = new StringBuilder();
  24. string[] keys = new string[Keys.Count];
  25. Keys.CopyTo(keys, 0);// AllKeys;
  26. for (int i = 0; i < count; i++)
  27. {
  28. sb.AppendFormat("{0}={1}&", keys[i], this[keys[i]]);
  29. }
  30. if (sb.Length > 0)
  31. sb.Length--;
  32. return sb.ToString();
  33. }
  34. }
  35. #region Constructors
  36. public HttpUtility()
  37. {
  38. }
  39. #endregion // Constructors
  40. #region Methods
  41. public static void HtmlAttributeEncode(string s, TextWriter output)
  42. {
  43. if (output == null)
  44. {
  45. #if NET_4_0
  46. throw new ArgumentNullException ("output");
  47. #else
  48. throw new NullReferenceException(".NET emulation");
  49. #endif
  50. }
  51. #if NET_4_0
  52. HttpEncoder.Current.HtmlAttributeEncode (s, output);
  53. #else
  54. output.Write(HttpEncoder.HtmlAttributeEncode(s));
  55. #endif
  56. }
  57. public static string HtmlAttributeEncode(string s)
  58. {
  59. #if NET_4_0
  60. if (s == null)
  61. return null;
  62. using (var sw = new StringWriter ()) {
  63. HttpEncoder.Current.HtmlAttributeEncode (s, sw);
  64. return sw.ToString ();
  65. }
  66. #else
  67. return HttpEncoder.HtmlAttributeEncode(s);
  68. #endif
  69. }
  70. public static string UrlDecode(string str)
  71. {
  72. return UrlDecode(str, Encoding.UTF8);
  73. }
  74. static char[] GetChars(MemoryStream b, Encoding e)
  75. {
  76. return e.GetChars(b.GetBuffer(), 0, (int)b.Length);
  77. }
  78. static void WriteCharBytes(IList buf, char ch, Encoding e)
  79. {
  80. if (ch > 255)
  81. {
  82. foreach (byte b in e.GetBytes(new char[] { ch }))
  83. buf.Add(b);
  84. }
  85. else
  86. buf.Add((byte)ch);
  87. }
  88. public static string UrlDecode(string s, Encoding e)
  89. {
  90. if (null == s)
  91. return null;
  92. if (s.IndexOf('%') == -1 && s.IndexOf('+') == -1)
  93. return s;
  94. if (e == null)
  95. e = Encoding.UTF8;
  96. long len = s.Length;
  97. var bytes = new List<byte>();
  98. int xchar;
  99. char ch;
  100. for (int i = 0; i < len; i++)
  101. {
  102. ch = s[i];
  103. if (ch == '%' && i + 2 < len && s[i + 1] != '%')
  104. {
  105. if (s[i + 1] == 'u' && i + 5 < len)
  106. {
  107. // unicode hex sequence
  108. xchar = GetChar(s, i + 2, 4);
  109. if (xchar != -1)
  110. {
  111. WriteCharBytes(bytes, (char)xchar, e);
  112. i += 5;
  113. }
  114. else
  115. WriteCharBytes(bytes, '%', e);
  116. }
  117. else if ((xchar = GetChar(s, i + 1, 2)) != -1)
  118. {
  119. WriteCharBytes(bytes, (char)xchar, e);
  120. i += 2;
  121. }
  122. else
  123. {
  124. WriteCharBytes(bytes, '%', e);
  125. }
  126. continue;
  127. }
  128. if (ch == '+')
  129. WriteCharBytes(bytes, ' ', e);
  130. else
  131. WriteCharBytes(bytes, ch, e);
  132. }
  133. byte[] buf = bytes.ToArray();
  134. bytes = null;
  135. return e.GetString(buf);
  136. }
  137. public static string UrlDecode(byte[] bytes, Encoding e)
  138. {
  139. if (bytes == null)
  140. return null;
  141. return UrlDecode(bytes, 0, bytes.Length, e);
  142. }
  143. static int GetInt(byte b)
  144. {
  145. char c = (char)b;
  146. if (c >= '0' && c <= '9')
  147. return c - '0';
  148. if (c >= 'a' && c <= 'f')
  149. return c - 'a' + 10;
  150. if (c >= 'A' && c <= 'F')
  151. return c - 'A' + 10;
  152. return -1;
  153. }
  154. static int GetChar(byte[] bytes, int offset, int length)
  155. {
  156. int value = 0;
  157. int end = length + offset;
  158. for (int i = offset; i < end; i++)
  159. {
  160. int current = GetInt(bytes[i]);
  161. if (current == -1)
  162. return -1;
  163. value = (value << 4) + current;
  164. }
  165. return value;
  166. }
  167. static int GetChar(string str, int offset, int length)
  168. {
  169. int val = 0;
  170. int end = length + offset;
  171. for (int i = offset; i < end; i++)
  172. {
  173. char c = str[i];
  174. if (c > 127)
  175. return -1;
  176. int current = GetInt((byte)c);
  177. if (current == -1)
  178. return -1;
  179. val = (val << 4) + current;
  180. }
  181. return val;
  182. }
  183. public static string UrlDecode(byte[] bytes, int offset, int count, Encoding e)
  184. {
  185. if (bytes == null)
  186. return null;
  187. if (count == 0)
  188. return String.Empty;
  189. if (bytes == null)
  190. throw new ArgumentNullException("bytes");
  191. if (offset < 0 || offset > bytes.Length)
  192. throw new ArgumentOutOfRangeException("offset");
  193. if (count < 0 || offset + count > bytes.Length)
  194. throw new ArgumentOutOfRangeException("count");
  195. StringBuilder output = new StringBuilder();
  196. MemoryStream acc = new MemoryStream();
  197. int end = count + offset;
  198. int xchar;
  199. for (int i = offset; i < end; i++)
  200. {
  201. if (bytes[i] == '%' && i + 2 < count && bytes[i + 1] != '%')
  202. {
  203. if (bytes[i + 1] == (byte)'u' && i + 5 < end)
  204. {
  205. if (acc.Length > 0)
  206. {
  207. output.Append(GetChars(acc, e));
  208. acc.SetLength(0);
  209. }
  210. xchar = GetChar(bytes, i + 2, 4);
  211. if (xchar != -1)
  212. {
  213. output.Append((char)xchar);
  214. i += 5;
  215. continue;
  216. }
  217. }
  218. else if ((xchar = GetChar(bytes, i + 1, 2)) != -1)
  219. {
  220. acc.WriteByte((byte)xchar);
  221. i += 2;
  222. continue;
  223. }
  224. }
  225. if (acc.Length > 0)
  226. {
  227. output.Append(GetChars(acc, e));
  228. acc.SetLength(0);
  229. }
  230. if (bytes[i] == '+')
  231. {
  232. output.Append(' ');
  233. }
  234. else
  235. {
  236. output.Append((char)bytes[i]);
  237. }
  238. }
  239. if (acc.Length > 0)
  240. {
  241. output.Append(GetChars(acc, e));
  242. }
  243. acc = null;
  244. return output.ToString();
  245. }
  246. public static byte[] UrlDecodeToBytes(byte[] bytes)
  247. {
  248. if (bytes == null)
  249. return null;
  250. return UrlDecodeToBytes(bytes, 0, bytes.Length);
  251. }
  252. public static byte[] UrlDecodeToBytes(string str)
  253. {
  254. return UrlDecodeToBytes(str, Encoding.UTF8);
  255. }
  256. public static byte[] UrlDecodeToBytes(string str, Encoding e)
  257. {
  258. if (str == null)
  259. return null;
  260. if (e == null)
  261. throw new ArgumentNullException("e");
  262. return UrlDecodeToBytes(e.GetBytes(str));
  263. }
  264. public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count)
  265. {
  266. if (bytes == null)
  267. return null;
  268. if (count == 0)
  269. return new byte[0];
  270. int len = bytes.Length;
  271. if (offset < 0 || offset >= len)
  272. throw new ArgumentOutOfRangeException("offset");
  273. if (count < 0 || offset > len - count)
  274. throw new ArgumentOutOfRangeException("count");
  275. MemoryStream result = new MemoryStream();
  276. int end = offset + count;
  277. for (int i = offset; i < end; i++)
  278. {
  279. char c = (char)bytes[i];
  280. if (c == '+')
  281. {
  282. c = ' ';
  283. }
  284. else if (c == '%' && i < end - 2)
  285. {
  286. int xchar = GetChar(bytes, i + 1, 2);
  287. if (xchar != -1)
  288. {
  289. c = (char)xchar;
  290. i += 2;
  291. }
  292. }
  293. result.WriteByte((byte)c);
  294. }
  295. return result.ToArray();
  296. }
  297. public static string UrlEncode(string str)
  298. {
  299. return UrlEncode(str, Encoding.UTF8);
  300. }
  301. public static string UrlEncode(string s, Encoding Enc)
  302. {
  303. if (s == null)
  304. return null;
  305. if (s == String.Empty)
  306. return String.Empty;
  307. bool needEncode = false;
  308. int len = s.Length;
  309. for (int i = 0; i < len; i++)
  310. {
  311. char c = s[i];
  312. if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z'))
  313. {
  314. if (HttpEncoder.NotEncoded(c))
  315. continue;
  316. needEncode = true;
  317. break;
  318. }
  319. }
  320. if (!needEncode)
  321. return s;
  322. // avoided GetByteCount call
  323. byte[] bytes = new byte[Enc.GetMaxByteCount(s.Length)];
  324. int realLen = Enc.GetBytes(s, 0, s.Length, bytes, 0);
  325. return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, realLen));
  326. }
  327. public static string UrlEncode(byte[] bytes)
  328. {
  329. if (bytes == null)
  330. return null;
  331. if (bytes.Length == 0)
  332. return String.Empty;
  333. return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, 0, bytes.Length));
  334. }
  335. public static string UrlEncode(byte[] bytes, int offset, int count)
  336. {
  337. if (bytes == null)
  338. return null;
  339. if (bytes.Length == 0)
  340. return String.Empty;
  341. return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count));
  342. }
  343. public static byte[] UrlEncodeToBytes(string str)
  344. {
  345. return UrlEncodeToBytes(str, Encoding.UTF8);
  346. }
  347. public static byte[] UrlEncodeToBytes(string str, Encoding e)
  348. {
  349. if (str == null)
  350. return null;
  351. if (str.Length == 0)
  352. return new byte[0];
  353. byte[] bytes = e.GetBytes(str);
  354. return UrlEncodeToBytes(bytes, 0, bytes.Length);
  355. }
  356. public static byte[] UrlEncodeToBytes(byte[] bytes)
  357. {
  358. if (bytes == null)
  359. return null;
  360. if (bytes.Length == 0)
  361. return new byte[0];
  362. return UrlEncodeToBytes(bytes, 0, bytes.Length);
  363. }
  364. public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count)
  365. {
  366. if (bytes == null)
  367. return null;
  368. #if NET_4_0
  369. return HttpEncoder.Current.UrlEncode (bytes, offset, count);
  370. #else
  371. return HttpEncoder.UrlEncodeToBytes(bytes, offset, count);
  372. #endif
  373. }
  374. public static string UrlEncodeUnicode(string str)
  375. {
  376. if (str == null)
  377. return null;
  378. return Encoding.ASCII.GetString(UrlEncodeUnicodeToBytes(str));
  379. }
  380. public static byte[] UrlEncodeUnicodeToBytes(string str)
  381. {
  382. if (str == null)
  383. return null;
  384. if (str.Length == 0)
  385. return new byte[0];
  386. MemoryStream result = new MemoryStream(str.Length);
  387. foreach (char c in str)
  388. {
  389. HttpEncoder.UrlEncodeChar(c, result, true);
  390. }
  391. return result.ToArray();
  392. }
  393. /// <summary>
  394. /// Decodes an HTML-encoded string and returns the decoded string.
  395. /// </summary>
  396. /// <param name="s">The HTML string to decode. </param>
  397. /// <returns>The decoded text.</returns>
  398. public static string HtmlDecode(string s)
  399. {
  400. #if NET_4_0
  401. if (s == null)
  402. return null;
  403. using (var sw = new StringWriter ()) {
  404. HttpEncoder.Current.HtmlDecode (s, sw);
  405. return sw.ToString ();
  406. }
  407. #else
  408. return HttpEncoder.HtmlDecode(s);
  409. #endif
  410. }
  411. /// <summary>
  412. /// Decodes an HTML-encoded string and sends the resulting output to a TextWriter output stream.
  413. /// </summary>
  414. /// <param name="s">The HTML string to decode</param>
  415. /// <param name="output">The TextWriter output stream containing the decoded string. </param>
  416. public static void HtmlDecode(string s, TextWriter output)
  417. {
  418. if (output == null)
  419. {
  420. #if NET_4_0
  421. throw new ArgumentNullException ("output");
  422. #else
  423. throw new NullReferenceException(".NET emulation");
  424. #endif
  425. }
  426. if (!String.IsNullOrEmpty(s))
  427. {
  428. #if NET_4_0
  429. HttpEncoder.Current.HtmlDecode (s, output);
  430. #else
  431. output.Write(HttpEncoder.HtmlDecode(s));
  432. #endif
  433. }
  434. }
  435. public static string HtmlEncode(string s)
  436. {
  437. #if NET_4_0
  438. if (s == null)
  439. return null;
  440. using (var sw = new StringWriter ()) {
  441. HttpEncoder.Current.HtmlEncode (s, sw);
  442. return sw.ToString ();
  443. }
  444. #else
  445. return HttpEncoder.HtmlEncode(s);
  446. #endif
  447. }
  448. /// <summary>
  449. /// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
  450. /// </summary>
  451. /// <param name="s">The string to encode. </param>
  452. /// <param name="output">The TextWriter output stream containing the encoded string. </param>
  453. public static void HtmlEncode(string s, TextWriter output)
  454. {
  455. if (output == null)
  456. {
  457. #if NET_4_0
  458. throw new ArgumentNullException ("output");
  459. #else
  460. throw new NullReferenceException(".NET emulation");
  461. #endif
  462. }
  463. if (!String.IsNullOrEmpty(s))
  464. {
  465. #if NET_4_0
  466. HttpEncoder.Current.HtmlEncode (s, output);
  467. #else
  468. output.Write(HttpEncoder.HtmlEncode(s));
  469. #endif
  470. }
  471. }
  472. #if NET_4_0
  473. public static string HtmlEncode (object value)
  474. {
  475. if (value == null)
  476. return null;
  477. IHtmlString htmlString = value as IHtmlString;
  478. if (htmlString != null)
  479. return htmlString.ToHtmlString ();
  480. return HtmlEncode (value.ToString ());
  481. }
  482. public static string JavaScriptStringEncode (string value)
  483. {
  484. return JavaScriptStringEncode (value, false);
  485. }
  486. public static string JavaScriptStringEncode (string value, bool addDoubleQuotes)
  487. {
  488. if (String.IsNullOrEmpty (value))
  489. return addDoubleQuotes ? "\"\"" : String.Empty;
  490. int len = value.Length;
  491. bool needEncode = false;
  492. char c;
  493. for (int i = 0; i < len; i++) {
  494. c = value [i];
  495. if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92) {
  496. needEncode = true;
  497. break;
  498. }
  499. }
  500. if (!needEncode)
  501. return addDoubleQuotes ? "\"" + value + "\"" : value;
  502. var sb = new StringBuilder ();
  503. if (addDoubleQuotes)
  504. sb.Append ('"');
  505. for (int i = 0; i < len; i++) {
  506. c = value [i];
  507. if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
  508. sb.AppendFormat ("\\u{0:x4}", (int)c);
  509. else switch ((int)c) {
  510. case 8:
  511. sb.Append ("\\b");
  512. break;
  513. case 9:
  514. sb.Append ("\\t");
  515. break;
  516. case 10:
  517. sb.Append ("\\n");
  518. break;
  519. case 12:
  520. sb.Append ("\\f");
  521. break;
  522. case 13:
  523. sb.Append ("\\r");
  524. break;
  525. case 34:
  526. sb.Append ("\\\"");
  527. break;
  528. case 92:
  529. sb.Append ("\\\\");
  530. break;
  531. default:
  532. sb.Append (c);
  533. break;
  534. }
  535. }
  536. if (addDoubleQuotes)
  537. sb.Append ('"');
  538. return sb.ToString ();
  539. }
  540. #endif
  541. public static string UrlPathEncode(string s)
  542. {
  543. #if NET_4_0
  544. return HttpEncoder.Current.UrlPathEncode (s);
  545. #else
  546. return HttpEncoder.UrlPathEncode(s);
  547. #endif
  548. }
  549. public static NameValueCollection ParseQueryString(string query)
  550. {
  551. return ParseQueryString(query, Encoding.UTF8);
  552. }
  553. public static NameValueCollection ParseQueryString(string query, Encoding encoding)
  554. {
  555. if (query == null)
  556. throw new ArgumentNullException("query");
  557. if (encoding == null)
  558. throw new ArgumentNullException("encoding");
  559. if (query.Length == 0 || (query.Length == 1 && query[0] == '?'))
  560. return new NameValueCollection();
  561. if (query[0] == '?')
  562. query = query.Substring(1);
  563. NameValueCollection result = new HttpQSCollection();
  564. ParseQueryString(query, encoding, result);
  565. return result;
  566. }
  567. internal static void ParseQueryString(string query, Encoding encoding, NameValueCollection result)
  568. {
  569. if (query.Length == 0)
  570. return;
  571. string decoded = HtmlDecode(query);
  572. int decodedLength = decoded.Length;
  573. int namePos = 0;
  574. bool first = true;
  575. while (namePos <= decodedLength)
  576. {
  577. int valuePos = -1, valueEnd = -1;
  578. for (int q = namePos; q < decodedLength; q++)
  579. {
  580. if (valuePos == -1 && decoded[q] == '=')
  581. {
  582. valuePos = q + 1;
  583. }
  584. else if (decoded[q] == '&')
  585. {
  586. valueEnd = q;
  587. break;
  588. }
  589. }
  590. if (first)
  591. {
  592. first = false;
  593. if (decoded[namePos] == '?')
  594. namePos++;
  595. }
  596. string name, value;
  597. if (valuePos == -1)
  598. {
  599. name = null;
  600. valuePos = namePos;
  601. }
  602. else
  603. {
  604. name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1), encoding);
  605. }
  606. if (valueEnd < 0)
  607. {
  608. namePos = -1;
  609. valueEnd = decoded.Length;
  610. }
  611. else
  612. {
  613. namePos = valueEnd + 1;
  614. }
  615. value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos), encoding);
  616. result.Add(name, value);
  617. if (namePos == -1)
  618. break;
  619. }
  620. }
  621. #endregion // Methods
  622. }
  623. }