34 using System.Collections.Generic;
35 using System.Configuration;
36 using System.Globalization;
44 static char[] hexChars =
"0123456789abcdef".ToCharArray();
45 static object entitiesLock =
new object();
46 static SortedDictionary<string, char> entities;
50 static IDictionary<string, char> Entities
68 return currentEncoder;
76 return defaultEncoder;
83 currentEncoder = defaultEncoder;
90 internal static void HeaderNameValueEncode(
string headerName,
string headerValue, out
string encodedHeaderName, out
string encodedHeaderValue)
92 if (String.IsNullOrEmpty(headerName))
93 encodedHeaderName = headerName;
95 encodedHeaderName = EncodeHeaderString(headerName);
97 if (String.IsNullOrEmpty(headerValue))
98 encodedHeaderValue = headerValue;
100 encodedHeaderValue = EncodeHeaderString(headerValue);
103 static void StringBuilderAppend(
string s, ref StringBuilder sb)
106 sb =
new StringBuilder(s);
111 static string EncodeHeaderString(
string input)
113 StringBuilder sb =
null;
116 for (
int i = 0; i < input.Length; i++)
120 if ((ch < 32 && ch != 9) || ch == 127)
121 StringBuilderAppend(String.Format(
"%{0:x2}", (
int)ch), ref sb);
125 return sb.ToString();
130 internal static string UrlPathEncode(
string value)
132 if (String.IsNullOrEmpty(value))
135 System.IO.MemoryStream result =
new System.IO.MemoryStream();
136 int length = value.Length;
137 for (
int i = 0; i < length; i++)
138 UrlPathEncodeChar(value[i], result);
140 return Encoding.ASCII.GetString(result.ToArray());
143 internal static byte[] UrlEncodeToBytes(
byte[] bytes,
int offset,
int count)
146 throw new ArgumentNullException(
"bytes");
148 int blen = bytes.Length;
150 return Array.Empty<
byte>();
152 if (offset < 0 || offset >= blen)
153 throw new ArgumentOutOfRangeException(
"offset");
155 if (count < 0 || count > blen - offset)
156 throw new ArgumentOutOfRangeException(
"count");
158 System.IO.MemoryStream result =
new System.IO.MemoryStream(count);
159 int end = offset + count;
160 for (
int i = offset; i < end; i++)
161 UrlEncodeChar((
char)bytes[i], result,
false);
163 return result.ToArray();
166 internal static string HtmlEncode(
string s)
174 bool needEncode =
false;
175 for (
int i = 0; i < s.Length; i++)
178 if (c ==
'&' || c ==
'"' || c ==
'<' || c ==
'>' || c > 159)
188 StringBuilder output =
new StringBuilder();
192 for (
int i = 0; i < len; i++)
197 output.Append(
"&");
200 output.Append(
">");
203 output.Append(
"<");
206 output.Append(
""");
209 output.Append(
"<");
213 output.Append(
">");
218 if (ch > 159 && ch < 256)
221 output.Append(((
int)ch).ToString(CultureInfo.InvariantCulture));
230 return output.ToString();
233 internal static string HtmlAttributeEncode(
string s)
241 bool needEncode =
false;
242 for (
int i = 0; i < s.Length; i++)
245 if (c ==
'&' || c ==
'"' || c ==
'<')
255 StringBuilder output =
new StringBuilder();
257 for (
int i = 0; i < len; i++)
261 output.Append(
"&");
264 output.Append(
""");
267 output.Append(
"<");
274 return output.ToString();
277 internal static string HtmlDecode(
string s)
285 if (s.IndexOf(
'&') == -1)
288 StringBuilder entity =
new StringBuilder();
289 StringBuilder output =
new StringBuilder();
297 bool is_hex_value =
false;
298 bool have_trailing_digits =
false;
300 for (
int i = 0; i < len; i++)
320 if (have_trailing_digits)
322 entity.Append(number.ToString(CultureInfo.InvariantCulture));
323 have_trailing_digits =
false;
326 output.Append(entity.ToString());
337 output.Append(entity.ToString());
344 is_hex_value =
false;
361 string key = entity.ToString();
362 if (key.Length > 1 && Entities.ContainsKey(key.Substring(1, key.Length - 2)))
363 key = Entities[key.Substring(1, key.Length - 2)].ToString();
377 output.Append(number.ToString(CultureInfo.InvariantCulture));
382 output.Append((
char)number);
386 have_trailing_digits =
false;
388 else if (is_hex_value && Uri.IsHexDigit(c))
390 number = number * 16 + Uri.FromHex(c);
391 have_trailing_digits =
true;
393 else if (Char.IsDigit(c))
395 number = number * 10 + ((int)c -
'0');
396 have_trailing_digits =
true;
398 else if (number == 0 && (c ==
'x' || c ==
'X'))
405 if (have_trailing_digits)
407 entity.Append(number.ToString(CultureInfo.InvariantCulture));
408 have_trailing_digits =
false;
415 if (entity.Length > 0)
417 output.Append(entity.ToString());
419 else if (have_trailing_digits)
421 output.Append(number.ToString(CultureInfo.InvariantCulture));
423 return output.ToString();
426 internal static bool NotEncoded(
char c)
428 return (c ==
'!' || c ==
'(' || c ==
')' || c ==
'*' || c ==
'-' || c ==
'.' || c ==
'_');
431 internal static void UrlEncodeChar(
char c, System.IO.Stream result,
bool isUnicode)
441 result.WriteByte((
byte)
'%');
442 result.WriteByte((
byte)
'u');
444 result.WriteByte((
byte)hexChars[idx]);
445 idx = (i >> 8) & 0x0F;
446 result.WriteByte((
byte)hexChars[idx]);
447 idx = (i >> 4) & 0x0F;
448 result.WriteByte((
byte)hexChars[idx]);
450 result.WriteByte((
byte)hexChars[idx]);
454 if (c >
' ' && NotEncoded(c))
456 result.WriteByte((
byte)c);
461 result.WriteByte((
byte)
'+');
465 (c < 'A' && c >
'9') ||
466 (c >
'Z' && c <
'a') ||
469 if (isUnicode && c > 127)
471 result.WriteByte((
byte)
'%');
472 result.WriteByte((
byte)
'u');
473 result.WriteByte((
byte)
'0');
474 result.WriteByte((
byte)
'0');
477 result.WriteByte((
byte)
'%');
479 int idx = ((int)c) >> 4;
480 result.WriteByte((
byte)hexChars[idx]);
481 idx = ((int)c) & 0x0F;
482 result.WriteByte((
byte)hexChars[idx]);
485 result.WriteByte((
byte)c);
488 internal static void UrlPathEncodeChar(
char c, System.IO.Stream result)
490 if (c < 33 || c > 126)
492 byte[] bIn = Encoding.UTF8.GetBytes(c.ToString());
493 for (
int i = 0; i < bIn.Length; i++)
495 result.WriteByte((
byte)
'%');
496 int idx = ((int)bIn[i]) >> 4;
497 result.WriteByte((
byte)hexChars[idx]);
498 idx = ((int)bIn[i]) & 0x0F;
499 result.WriteByte((
byte)hexChars[idx]);
504 result.WriteByte((
byte)
'%');
505 result.WriteByte((
byte)
'2');
506 result.WriteByte((
byte)
'0');
509 result.WriteByte((
byte)c);
512 static void InitEntities()
516 entities =
new SortedDictionary<string, char>(StringComparer.Ordinal);
518 entities.Add(
"nbsp",
'\u00A0');
519 entities.Add(
"iexcl",
'\u00A1');
520 entities.Add(
"cent",
'\u00A2');
521 entities.Add(
"pound",
'\u00A3');
522 entities.Add(
"curren",
'\u00A4');
523 entities.Add(
"yen",
'\u00A5');
524 entities.Add(
"brvbar",
'\u00A6');
525 entities.Add(
"sect",
'\u00A7');
526 entities.Add(
"uml",
'\u00A8');
527 entities.Add(
"copy",
'\u00A9');
528 entities.Add(
"ordf",
'\u00AA');
529 entities.Add(
"laquo",
'\u00AB');
530 entities.Add(
"not",
'\u00AC');
531 entities.Add(
"shy",
'\u00AD');
532 entities.Add(
"reg",
'\u00AE');
533 entities.Add(
"macr",
'\u00AF');
534 entities.Add(
"deg",
'\u00B0');
535 entities.Add(
"plusmn",
'\u00B1');
536 entities.Add(
"sup2",
'\u00B2');
537 entities.Add(
"sup3",
'\u00B3');
538 entities.Add(
"acute",
'\u00B4');
539 entities.Add(
"micro",
'\u00B5');
540 entities.Add(
"para",
'\u00B6');
541 entities.Add(
"middot",
'\u00B7');
542 entities.Add(
"cedil",
'\u00B8');
543 entities.Add(
"sup1",
'\u00B9');
544 entities.Add(
"ordm",
'\u00BA');
545 entities.Add(
"raquo",
'\u00BB');
546 entities.Add(
"frac14",
'\u00BC');
547 entities.Add(
"frac12",
'\u00BD');
548 entities.Add(
"frac34",
'\u00BE');
549 entities.Add(
"iquest",
'\u00BF');
550 entities.Add(
"Agrave",
'\u00C0');
551 entities.Add(
"Aacute",
'\u00C1');
552 entities.Add(
"Acirc",
'\u00C2');
553 entities.Add(
"Atilde",
'\u00C3');
554 entities.Add(
"Auml",
'\u00C4');
555 entities.Add(
"Aring",
'\u00C5');
556 entities.Add(
"AElig",
'\u00C6');
557 entities.Add(
"Ccedil",
'\u00C7');
558 entities.Add(
"Egrave",
'\u00C8');
559 entities.Add(
"Eacute",
'\u00C9');
560 entities.Add(
"Ecirc",
'\u00CA');
561 entities.Add(
"Euml",
'\u00CB');
562 entities.Add(
"Igrave",
'\u00CC');
563 entities.Add(
"Iacute",
'\u00CD');
564 entities.Add(
"Icirc",
'\u00CE');
565 entities.Add(
"Iuml",
'\u00CF');
566 entities.Add(
"ETH",
'\u00D0');
567 entities.Add(
"Ntilde",
'\u00D1');
568 entities.Add(
"Ograve",
'\u00D2');
569 entities.Add(
"Oacute",
'\u00D3');
570 entities.Add(
"Ocirc",
'\u00D4');
571 entities.Add(
"Otilde",
'\u00D5');
572 entities.Add(
"Ouml",
'\u00D6');
573 entities.Add(
"times",
'\u00D7');
574 entities.Add(
"Oslash",
'\u00D8');
575 entities.Add(
"Ugrave",
'\u00D9');
576 entities.Add(
"Uacute",
'\u00DA');
577 entities.Add(
"Ucirc",
'\u00DB');
578 entities.Add(
"Uuml",
'\u00DC');
579 entities.Add(
"Yacute",
'\u00DD');
580 entities.Add(
"THORN",
'\u00DE');
581 entities.Add(
"szlig",
'\u00DF');
582 entities.Add(
"agrave",
'\u00E0');
583 entities.Add(
"aacute",
'\u00E1');
584 entities.Add(
"acirc",
'\u00E2');
585 entities.Add(
"atilde",
'\u00E3');
586 entities.Add(
"auml",
'\u00E4');
587 entities.Add(
"aring",
'\u00E5');
588 entities.Add(
"aelig",
'\u00E6');
589 entities.Add(
"ccedil",
'\u00E7');
590 entities.Add(
"egrave",
'\u00E8');
591 entities.Add(
"eacute",
'\u00E9');
592 entities.Add(
"ecirc",
'\u00EA');
593 entities.Add(
"euml",
'\u00EB');
594 entities.Add(
"igrave",
'\u00EC');
595 entities.Add(
"iacute",
'\u00ED');
596 entities.Add(
"icirc",
'\u00EE');
597 entities.Add(
"iuml",
'\u00EF');
598 entities.Add(
"eth",
'\u00F0');
599 entities.Add(
"ntilde",
'\u00F1');
600 entities.Add(
"ograve",
'\u00F2');
601 entities.Add(
"oacute",
'\u00F3');
602 entities.Add(
"ocirc",
'\u00F4');
603 entities.Add(
"otilde",
'\u00F5');
604 entities.Add(
"ouml",
'\u00F6');
605 entities.Add(
"divide",
'\u00F7');
606 entities.Add(
"oslash",
'\u00F8');
607 entities.Add(
"ugrave",
'\u00F9');
608 entities.Add(
"uacute",
'\u00FA');
609 entities.Add(
"ucirc",
'\u00FB');
610 entities.Add(
"uuml",
'\u00FC');
611 entities.Add(
"yacute",
'\u00FD');
612 entities.Add(
"thorn",
'\u00FE');
613 entities.Add(
"yuml",
'\u00FF');
614 entities.Add(
"fnof",
'\u0192');
615 entities.Add(
"Alpha",
'\u0391');
616 entities.Add(
"Beta",
'\u0392');
617 entities.Add(
"Gamma",
'\u0393');
618 entities.Add(
"Delta",
'\u0394');
619 entities.Add(
"Epsilon",
'\u0395');
620 entities.Add(
"Zeta",
'\u0396');
621 entities.Add(
"Eta",
'\u0397');
622 entities.Add(
"Theta",
'\u0398');
623 entities.Add(
"Iota",
'\u0399');
624 entities.Add(
"Kappa",
'\u039A');
625 entities.Add(
"Lambda",
'\u039B');
626 entities.Add(
"Mu",
'\u039C');
627 entities.Add(
"Nu",
'\u039D');
628 entities.Add(
"Xi",
'\u039E');
629 entities.Add(
"Omicron",
'\u039F');
630 entities.Add(
"Pi",
'\u03A0');
631 entities.Add(
"Rho",
'\u03A1');
632 entities.Add(
"Sigma",
'\u03A3');
633 entities.Add(
"Tau",
'\u03A4');
634 entities.Add(
"Upsilon",
'\u03A5');
635 entities.Add(
"Phi",
'\u03A6');
636 entities.Add(
"Chi",
'\u03A7');
637 entities.Add(
"Psi",
'\u03A8');
638 entities.Add(
"Omega",
'\u03A9');
639 entities.Add(
"alpha",
'\u03B1');
640 entities.Add(
"beta",
'\u03B2');
641 entities.Add(
"gamma",
'\u03B3');
642 entities.Add(
"delta",
'\u03B4');
643 entities.Add(
"epsilon",
'\u03B5');
644 entities.Add(
"zeta",
'\u03B6');
645 entities.Add(
"eta",
'\u03B7');
646 entities.Add(
"theta",
'\u03B8');
647 entities.Add(
"iota",
'\u03B9');
648 entities.Add(
"kappa",
'\u03BA');
649 entities.Add(
"lambda",
'\u03BB');
650 entities.Add(
"mu",
'\u03BC');
651 entities.Add(
"nu",
'\u03BD');
652 entities.Add(
"xi",
'\u03BE');
653 entities.Add(
"omicron",
'\u03BF');
654 entities.Add(
"pi",
'\u03C0');
655 entities.Add(
"rho",
'\u03C1');
656 entities.Add(
"sigmaf",
'\u03C2');
657 entities.Add(
"sigma",
'\u03C3');
658 entities.Add(
"tau",
'\u03C4');
659 entities.Add(
"upsilon",
'\u03C5');
660 entities.Add(
"phi",
'\u03C6');
661 entities.Add(
"chi",
'\u03C7');
662 entities.Add(
"psi",
'\u03C8');
663 entities.Add(
"omega",
'\u03C9');
664 entities.Add(
"thetasym",
'\u03D1');
665 entities.Add(
"upsih",
'\u03D2');
666 entities.Add(
"piv",
'\u03D6');
667 entities.Add(
"bull",
'\u2022');
668 entities.Add(
"hellip",
'\u2026');
669 entities.Add(
"prime",
'\u2032');
670 entities.Add(
"Prime",
'\u2033');
671 entities.Add(
"oline",
'\u203E');
672 entities.Add(
"frasl",
'\u2044');
673 entities.Add(
"weierp",
'\u2118');
674 entities.Add(
"image",
'\u2111');
675 entities.Add(
"real",
'\u211C');
676 entities.Add(
"trade",
'\u2122');
677 entities.Add(
"alefsym",
'\u2135');
678 entities.Add(
"larr",
'\u2190');
679 entities.Add(
"uarr",
'\u2191');
680 entities.Add(
"rarr",
'\u2192');
681 entities.Add(
"darr",
'\u2193');
682 entities.Add(
"harr",
'\u2194');
683 entities.Add(
"crarr",
'\u21B5');
684 entities.Add(
"lArr",
'\u21D0');
685 entities.Add(
"uArr",
'\u21D1');
686 entities.Add(
"rArr",
'\u21D2');
687 entities.Add(
"dArr",
'\u21D3');
688 entities.Add(
"hArr",
'\u21D4');
689 entities.Add(
"forall",
'\u2200');
690 entities.Add(
"part",
'\u2202');
691 entities.Add(
"exist",
'\u2203');
692 entities.Add(
"empty",
'\u2205');
693 entities.Add(
"nabla",
'\u2207');
694 entities.Add(
"isin",
'\u2208');
695 entities.Add(
"notin",
'\u2209');
696 entities.Add(
"ni",
'\u220B');
697 entities.Add(
"prod",
'\u220F');
698 entities.Add(
"sum",
'\u2211');
699 entities.Add(
"minus",
'\u2212');
700 entities.Add(
"lowast",
'\u2217');
701 entities.Add(
"radic",
'\u221A');
702 entities.Add(
"prop",
'\u221D');
703 entities.Add(
"infin",
'\u221E');
704 entities.Add(
"ang",
'\u2220');
705 entities.Add(
"and",
'\u2227');
706 entities.Add(
"or",
'\u2228');
707 entities.Add(
"cap",
'\u2229');
708 entities.Add(
"cup",
'\u222A');
709 entities.Add(
"int",
'\u222B');
710 entities.Add(
"there4",
'\u2234');
711 entities.Add(
"sim",
'\u223C');
712 entities.Add(
"cong",
'\u2245');
713 entities.Add(
"asymp",
'\u2248');
714 entities.Add(
"ne",
'\u2260');
715 entities.Add(
"equiv",
'\u2261');
716 entities.Add(
"le",
'\u2264');
717 entities.Add(
"ge",
'\u2265');
718 entities.Add(
"sub",
'\u2282');
719 entities.Add(
"sup",
'\u2283');
720 entities.Add(
"nsub",
'\u2284');
721 entities.Add(
"sube",
'\u2286');
722 entities.Add(
"supe",
'\u2287');
723 entities.Add(
"oplus",
'\u2295');
724 entities.Add(
"otimes",
'\u2297');
725 entities.Add(
"perp",
'\u22A5');
726 entities.Add(
"sdot",
'\u22C5');
727 entities.Add(
"lceil",
'\u2308');
728 entities.Add(
"rceil",
'\u2309');
729 entities.Add(
"lfloor",
'\u230A');
730 entities.Add(
"rfloor",
'\u230B');
731 entities.Add(
"lang",
'\u2329');
732 entities.Add(
"rang",
'\u232A');
733 entities.Add(
"loz",
'\u25CA');
734 entities.Add(
"spades",
'\u2660');
735 entities.Add(
"clubs",
'\u2663');
736 entities.Add(
"hearts",
'\u2665');
737 entities.Add(
"diams",
'\u2666');
738 entities.Add(
"quot",
'\u0022');
739 entities.Add(
"amp",
'\u0026');
740 entities.Add(
"lt",
'\u003C');
741 entities.Add(
"gt",
'\u003E');
742 entities.Add(
"OElig",
'\u0152');
743 entities.Add(
"oelig",
'\u0153');
744 entities.Add(
"Scaron",
'\u0160');
745 entities.Add(
"scaron",
'\u0161');
746 entities.Add(
"Yuml",
'\u0178');
747 entities.Add(
"circ",
'\u02C6');
748 entities.Add(
"tilde",
'\u02DC');
749 entities.Add(
"ensp",
'\u2002');
750 entities.Add(
"emsp",
'\u2003');
751 entities.Add(
"thinsp",
'\u2009');
752 entities.Add(
"zwnj",
'\u200C');
753 entities.Add(
"zwj",
'\u200D');
754 entities.Add(
"lrm",
'\u200E');
755 entities.Add(
"rlm",
'\u200F');
756 entities.Add(
"ndash",
'\u2013');
757 entities.Add(
"mdash",
'\u2014');
758 entities.Add(
"lsquo",
'\u2018');
759 entities.Add(
"rsquo",
'\u2019');
760 entities.Add(
"sbquo",
'\u201A');
761 entities.Add(
"ldquo",
'\u201C');
762 entities.Add(
"rdquo",
'\u201D');
763 entities.Add(
"bdquo",
'\u201E');
764 entities.Add(
"dagger",
'\u2020');
765 entities.Add(
"Dagger",
'\u2021');
766 entities.Add(
"permil",
'\u2030');
767 entities.Add(
"lsaquo",
'\u2039');
768 entities.Add(
"rsaquo",
'\u203A');
769 entities.Add(
"euro",
'\u20AC');
static HttpEncoder Current
static HttpEncoder Default