OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 class _HttpHeaders implements HttpHeaders { | 7 class _HttpHeaders implements HttpHeaders { |
8 final Map<String, List<String>> _headers; | 8 final Map<String, List<String>> _headers; |
9 final String protocolVersion; | 9 final String protocolVersion; |
10 | 10 |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 Map<String, String> _unmodifiableParameters; | 623 Map<String, String> _unmodifiableParameters; |
624 | 624 |
625 _HeaderValue([String this._value = "", Map<String, String> parameters]) { | 625 _HeaderValue([String this._value = "", Map<String, String> parameters]) { |
626 if (parameters != null) { | 626 if (parameters != null) { |
627 _parameters = new HashMap<String, String>.from(parameters); | 627 _parameters = new HashMap<String, String>.from(parameters); |
628 } | 628 } |
629 } | 629 } |
630 | 630 |
631 static _HeaderValue parse(String value, | 631 static _HeaderValue parse(String value, |
632 {parameterSeparator: ";", | 632 {parameterSeparator: ";", |
633 valueSeparator: null, | |
634 preserveBackslash: false}) { | 633 preserveBackslash: false}) { |
635 // Parse the string. | 634 // Parse the string. |
636 var result = new _HeaderValue(); | 635 var result = new _HeaderValue(); |
637 result._parse(value, parameterSeparator, valueSeparator, preserveBackslash); | 636 result._parse(value, parameterSeparator, preserveBackslash); |
638 return result; | 637 return result; |
639 } | 638 } |
640 | 639 |
641 String get value => _value; | 640 String get value => _value; |
642 | 641 |
643 void _ensureParameters() { | 642 void _ensureParameters() { |
644 if (_parameters == null) { | 643 if (_parameters == null) { |
645 _parameters = new HashMap<String, String>(); | 644 _parameters = new HashMap<String, String>(); |
646 } | 645 } |
647 } | 646 } |
(...skipping 10 matching lines...) Expand all Loading... |
658 StringBuffer sb = new StringBuffer(); | 657 StringBuffer sb = new StringBuffer(); |
659 sb.write(_value); | 658 sb.write(_value); |
660 if (parameters != null && parameters.length > 0) { | 659 if (parameters != null && parameters.length > 0) { |
661 _parameters.forEach((String name, String value) { | 660 _parameters.forEach((String name, String value) { |
662 sb..write("; ")..write(name)..write("=")..write(value); | 661 sb..write("; ")..write(name)..write("=")..write(value); |
663 }); | 662 }); |
664 } | 663 } |
665 return sb.toString(); | 664 return sb.toString(); |
666 } | 665 } |
667 | 666 |
668 void _parse(String s, | 667 void _parse(String s, String parameterSeparator, bool preserveBackslash) { |
669 String parameterSeparator, | |
670 String valueSeparator, | |
671 bool preserveBackslash) { | |
672 int index = 0; | 668 int index = 0; |
673 | 669 |
674 bool done() => index == s.length; | 670 bool done() => index == s.length; |
675 | 671 |
676 void skipWS() { | 672 void skipWS() { |
677 while (!done()) { | 673 while (!done()) { |
678 if (s[index] != " " && s[index] != "\t") return; | 674 if (s[index] != " " && s[index] != "\t") return; |
679 index++; | 675 index++; |
680 } | 676 } |
681 } | 677 } |
682 | 678 |
683 String parseValue() { | 679 String parseValue() { |
684 int start = index; | 680 int start = index; |
685 while (!done()) { | 681 while (!done()) { |
686 if (s[index] == " " || | 682 if (s[index] == " " || |
687 s[index] == "\t" || | 683 s[index] == "\t" || |
688 s[index] == valueSeparator || | |
689 s[index] == parameterSeparator) break; | 684 s[index] == parameterSeparator) break; |
690 index++; | 685 index++; |
691 } | 686 } |
692 return s.substring(start, index); | 687 return s.substring(start, index); |
693 } | 688 } |
694 | 689 |
695 void expect(String expected) { | 690 void expect(String expected) { |
696 if (done() || s[index] != expected) { | 691 if (done() || s[index] != expected) { |
697 throw new HttpException("Failed to parse header value"); | 692 throw new HttpException("Failed to parse header value"); |
698 } | 693 } |
699 index++; | 694 index++; |
700 } | 695 } |
701 | 696 |
702 void maybeExpect(String expected) { | 697 void maybeExpect(String expected) { |
703 if (s[index] == expected) index++; | 698 if (s[index] == expected) index++; |
704 } | 699 } |
705 | 700 |
706 void parseParameters() { | 701 void parseParameters() { |
707 var parameters = new HashMap<String, String>(); | 702 var parameters = new HashMap<String, String>(); |
708 _parameters = new UnmodifiableMapView(parameters); | 703 _parameters = new UnmodifiableMapView(parameters); |
709 | 704 |
710 String parseParameterName() { | 705 String parseParameterName() { |
711 int start = index; | 706 int start = index; |
712 while (!done()) { | 707 while (!done()) { |
713 if (s[index] == " " || | 708 if (s[index] == " " || s[index] == "\t" || s[index] == "=") break; |
714 s[index] == "\t" || | |
715 s[index] == "=" || | |
716 s[index] == valueSeparator) break; | |
717 index++; | 709 index++; |
718 } | 710 } |
719 return s.substring(start, index).toLowerCase(); | 711 return s.substring(start, index).toLowerCase(); |
720 } | 712 } |
721 | 713 |
722 String parseParameterValue() { | 714 String parseParameterValue() { |
723 if (!done() && s[index] == "\"") { | 715 if (s[index] == "\"") { |
724 // Parse quoted value. | 716 // Parse quoted value. |
725 StringBuffer sb = new StringBuffer(); | 717 StringBuffer sb = new StringBuffer(); |
726 index++; | 718 index++; |
727 while (!done()) { | 719 while (!done()) { |
728 if (s[index] == "\\") { | 720 if (s[index] == "\\") { |
729 if (index + 1 == s.length) { | 721 if (index + 1 == s.length) { |
730 throw new HttpException("Failed to parse header value"); | 722 throw new HttpException("Failed to parse header value"); |
731 } | 723 } |
732 if (preserveBackslash && s[index + 1] != "\"") { | 724 if (preserveBackslash && s[index + 1] != "\"") { |
733 sb.write(s[index]); | 725 sb.write(s[index]); |
734 } | 726 } |
735 index++; | 727 index++; |
736 } else if (s[index] == "\"") { | 728 } else if (s[index] == "\"") { |
737 index++; | 729 index++; |
738 break; | 730 break; |
739 } | 731 } |
740 sb.write(s[index]); | 732 sb.write(s[index]); |
741 index++; | 733 index++; |
742 } | 734 } |
743 return sb.toString(); | 735 return sb.toString(); |
744 } else { | 736 } else { |
745 // Parse non-quoted value. | 737 // Parse non-quoted value. |
746 var val = parseValue(); | 738 return parseValue(); |
747 return val == "" ? null : val; | |
748 } | 739 } |
749 } | 740 } |
750 | 741 |
751 while (!done()) { | 742 while (!done()) { |
752 skipWS(); | 743 skipWS(); |
753 if (done()) return; | 744 if (done()) return; |
754 String name = parseParameterName(); | 745 String name = parseParameterName(); |
755 skipWS(); | 746 skipWS(); |
756 if (done()) { | 747 expect("="); |
757 parameters[name] = null; | |
758 return; | |
759 } | |
760 maybeExpect("="); | |
761 skipWS(); | 748 skipWS(); |
762 if(done()) { | |
763 parameters[name] = null; | |
764 return; | |
765 } | |
766 String value = parseParameterValue(); | 749 String value = parseParameterValue(); |
767 if (name == 'charset' && this is _ContentType) { | 750 if (name == 'charset' && this is _ContentType) { |
768 // Charset parameter of ContentTypes are always lower-case. | 751 // Charset parameter of ContentTypes are always lower-case. |
769 value = value.toLowerCase(); | 752 value = value.toLowerCase(); |
770 } | 753 } |
771 parameters[name] = value; | 754 parameters[name] = value; |
772 skipWS(); | 755 skipWS(); |
773 if (done()) return; | 756 if (done()) return; |
774 // TODO: Implement support for multi-valued parameters. | |
775 if(s[index] == valueSeparator) return; | |
776 expect(parameterSeparator); | 757 expect(parameterSeparator); |
777 } | 758 } |
778 } | 759 } |
779 | 760 |
780 skipWS(); | 761 skipWS(); |
781 _value = parseValue(); | 762 _value = parseValue(); |
782 skipWS(); | 763 skipWS(); |
783 if (done()) return; | 764 if (done()) return; |
784 maybeExpect(parameterSeparator); | 765 maybeExpect(parameterSeparator); |
785 parseParameters(); | 766 parseParameters(); |
(...skipping 26 matching lines...) Expand all Loading... |
812 if (charset != null) { | 793 if (charset != null) { |
813 _ensureParameters(); | 794 _ensureParameters(); |
814 this._parameters["charset"] = charset.toLowerCase(); | 795 this._parameters["charset"] = charset.toLowerCase(); |
815 } | 796 } |
816 } | 797 } |
817 | 798 |
818 _ContentType._(); | 799 _ContentType._(); |
819 | 800 |
820 static _ContentType parse(String value) { | 801 static _ContentType parse(String value) { |
821 var result = new _ContentType._(); | 802 var result = new _ContentType._(); |
822 result._parse(value, ";", null, false); | 803 result._parse(value, ";", false); |
823 int index = result._value.indexOf("/"); | 804 int index = result._value.indexOf("/"); |
824 if (index == -1 || index == (result._value.length - 1)) { | 805 if (index == -1 || index == (result._value.length - 1)) { |
825 result._primaryType = result._value.trim().toLowerCase(); | 806 result._primaryType = result._value.trim().toLowerCase(); |
826 result._subType = ""; | 807 result._subType = ""; |
827 } else { | 808 } else { |
828 result._primaryType = | 809 result._primaryType = |
829 result._value.substring(0, index).trim().toLowerCase(); | 810 result._value.substring(0, index).trim().toLowerCase(); |
830 result._subType = result._value.substring(index + 1).trim().toLowerCase(); | 811 result._subType = result._value.substring(index + 1).trim().toLowerCase(); |
831 } | 812 } |
832 return result; | 813 return result; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 (codeUnit >= 0x23 && codeUnit <= 0x2B) || | 970 (codeUnit >= 0x23 && codeUnit <= 0x2B) || |
990 (codeUnit >= 0x2D && codeUnit <= 0x3A) || | 971 (codeUnit >= 0x2D && codeUnit <= 0x3A) || |
991 (codeUnit >= 0x3C && codeUnit <= 0x5B) || | 972 (codeUnit >= 0x3C && codeUnit <= 0x5B) || |
992 (codeUnit >= 0x5D && codeUnit <= 0x7E))) { | 973 (codeUnit >= 0x5D && codeUnit <= 0x7E))) { |
993 throw new FormatException( | 974 throw new FormatException( |
994 "Invalid character in cookie value, code unit: '$codeUnit'"); | 975 "Invalid character in cookie value, code unit: '$codeUnit'"); |
995 } | 976 } |
996 } | 977 } |
997 } | 978 } |
998 } | 979 } |
OLD | NEW |