| 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 | 
| 11   bool _mutable = true;  // Are the headers currently mutable? | 11   bool _mutable = true; // Are the headers currently mutable? | 
| 12   List<String> _noFoldingHeaders; | 12   List<String> _noFoldingHeaders; | 
| 13 | 13 | 
| 14   int _contentLength = -1; | 14   int _contentLength = -1; | 
| 15   bool _persistentConnection = true; | 15   bool _persistentConnection = true; | 
| 16   bool _chunkedTransferEncoding = false; | 16   bool _chunkedTransferEncoding = false; | 
| 17   String _host; | 17   String _host; | 
| 18   int _port; | 18   int _port; | 
| 19 | 19 | 
| 20   final int _defaultPortForScheme; | 20   final int _defaultPortForScheme; | 
| 21 | 21 | 
| 22   _HttpHeaders(this.protocolVersion, | 22   _HttpHeaders(this.protocolVersion, | 
| 23                {int defaultPortForScheme: HttpClient.DEFAULT_HTTP_PORT, | 23       {int defaultPortForScheme: HttpClient.DEFAULT_HTTP_PORT, | 
| 24                 _HttpHeaders initialHeaders}) | 24       _HttpHeaders initialHeaders}) | 
| 25       : _headers = new HashMap<String, List<String>>(), | 25       : _headers = new HashMap<String, List<String>>(), | 
| 26         _defaultPortForScheme = defaultPortForScheme { | 26         _defaultPortForScheme = defaultPortForScheme { | 
| 27     if (initialHeaders != null) { | 27     if (initialHeaders != null) { | 
| 28       initialHeaders._headers.forEach((name, value) => _headers[name] = value); | 28       initialHeaders._headers.forEach((name, value) => _headers[name] = value); | 
| 29       _contentLength = initialHeaders._contentLength; | 29       _contentLength = initialHeaders._contentLength; | 
| 30       _persistentConnection = initialHeaders._persistentConnection; | 30       _persistentConnection = initialHeaders._persistentConnection; | 
| 31       _chunkedTransferEncoding = initialHeaders._chunkedTransferEncoding; | 31       _chunkedTransferEncoding = initialHeaders._chunkedTransferEncoding; | 
| 32       _host = initialHeaders._host; | 32       _host = initialHeaders._host; | 
| 33       _port = initialHeaders._port; | 33       _port = initialHeaders._port; | 
| 34     } | 34     } | 
| 35     if (protocolVersion == "1.0") { | 35     if (protocolVersion == "1.0") { | 
| 36       _persistentConnection = false; | 36       _persistentConnection = false; | 
| 37       _chunkedTransferEncoding = false; | 37       _chunkedTransferEncoding = false; | 
| 38     } | 38     } | 
| 39   } | 39   } | 
| 40 | 40 | 
| 41   List<String> operator[](String name) => _headers[name.toLowerCase()]; | 41   List<String> operator [](String name) => _headers[name.toLowerCase()]; | 
| 42 | 42 | 
| 43   String value(String name) { | 43   String value(String name) { | 
| 44     name = name.toLowerCase(); | 44     name = name.toLowerCase(); | 
| 45     List<String> values = _headers[name]; | 45     List<String> values = _headers[name]; | 
| 46     if (values == null) return null; | 46     if (values == null) return null; | 
| 47     if (values.length > 1) { | 47     if (values.length > 1) { | 
| 48       throw new HttpException("More than one value for header $name"); | 48       throw new HttpException("More than one value for header $name"); | 
| 49     } | 49     } | 
| 50     return values[0]; | 50     return values[0]; | 
| 51   } | 51   } | 
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 447     if (!_mutable) throw new HttpException("HTTP headers are not mutable"); | 447     if (!_mutable) throw new HttpException("HTTP headers are not mutable"); | 
| 448   } | 448   } | 
| 449 | 449 | 
| 450   _updateHostHeader() { | 450   _updateHostHeader() { | 
| 451     bool defaultPort = _port == null || _port == _defaultPortForScheme; | 451     bool defaultPort = _port == null || _port == _defaultPortForScheme; | 
| 452     _set("host", defaultPort ? host : "$host:$_port"); | 452     _set("host", defaultPort ? host : "$host:$_port"); | 
| 453   } | 453   } | 
| 454 | 454 | 
| 455   _foldHeader(String name) { | 455   _foldHeader(String name) { | 
| 456     if (name == HttpHeaders.SET_COOKIE || | 456     if (name == HttpHeaders.SET_COOKIE || | 
| 457         (_noFoldingHeaders != null && | 457         (_noFoldingHeaders != null && _noFoldingHeaders.indexOf(name) != -1)) { | 
| 458          _noFoldingHeaders.indexOf(name) != -1)) { |  | 
| 459       return false; | 458       return false; | 
| 460     } | 459     } | 
| 461     return true; | 460     return true; | 
| 462   } | 461   } | 
| 463 | 462 | 
| 464   void _finalize() { | 463   void _finalize() { | 
| 465     _mutable = false; | 464     _mutable = false; | 
| 466   } | 465   } | 
| 467 | 466 | 
| 468   void _build(BytesBuilder builder) { | 467   void _build(BytesBuilder builder) { | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 516   List<Cookie> _parseCookies() { | 515   List<Cookie> _parseCookies() { | 
| 517     // Parse a Cookie header value according to the rules in RFC 6265. | 516     // Parse a Cookie header value according to the rules in RFC 6265. | 
| 518     var cookies = new List<Cookie>(); | 517     var cookies = new List<Cookie>(); | 
| 519     void parseCookieString(String s) { | 518     void parseCookieString(String s) { | 
| 520       int index = 0; | 519       int index = 0; | 
| 521 | 520 | 
| 522       bool done() => index == -1 || index == s.length; | 521       bool done() => index == -1 || index == s.length; | 
| 523 | 522 | 
| 524       void skipWS() { | 523       void skipWS() { | 
| 525         while (!done()) { | 524         while (!done()) { | 
| 526          if (s[index] != " " && s[index] != "\t") return; | 525           if (s[index] != " " && s[index] != "\t") return; | 
| 527          index++; | 526           index++; | 
| 528         } | 527         } | 
| 529       } | 528       } | 
| 530 | 529 | 
| 531       String parseName() { | 530       String parseName() { | 
| 532         int start = index; | 531         int start = index; | 
| 533         while (!done()) { | 532         while (!done()) { | 
| 534           if (s[index] == " " || s[index] == "\t" || s[index] == "=") break; | 533           if (s[index] == " " || s[index] == "\t" || s[index] == "=") break; | 
| 535           index++; | 534           index++; | 
| 536         } | 535         } | 
| 537         return s.substring(start, index); | 536         return s.substring(start, index); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 570           // Skip it, invalid cookie data. | 569           // Skip it, invalid cookie data. | 
| 571         } | 570         } | 
| 572         skipWS(); | 571         skipWS(); | 
| 573         if (done()) return; | 572         if (done()) return; | 
| 574         if (!expect(";")) { | 573         if (!expect(";")) { | 
| 575           index = s.indexOf(';', index); | 574           index = s.indexOf(';', index); | 
| 576           continue; | 575           continue; | 
| 577         } | 576         } | 
| 578       } | 577       } | 
| 579     } | 578     } | 
|  | 579 | 
| 580     List<String> values = _headers[HttpHeaders.COOKIE]; | 580     List<String> values = _headers[HttpHeaders.COOKIE]; | 
| 581     if (values != null) { | 581     if (values != null) { | 
| 582       values.forEach((headerValue) => parseCookieString(headerValue)); | 582       values.forEach((headerValue) => parseCookieString(headerValue)); | 
| 583     } | 583     } | 
| 584     return cookies; | 584     return cookies; | 
| 585   } | 585   } | 
| 586 | 586 | 
| 587   static String _validateField(String field) { | 587   static String _validateField(String field) { | 
| 588     for (var i = 0; i < field.length; i++) { | 588     for (var i = 0; i < field.length; i++) { | 
| 589       if (!_HttpParser._isTokenChar(field.codeUnitAt(i))) { | 589       if (!_HttpParser._isTokenChar(field.codeUnitAt(i))) { | 
| 590         throw new FormatException( | 590         throw new FormatException( | 
| 591             "Invalid HTTP header field name: ${JSON.encode(field)}"); | 591             "Invalid HTTP header field name: ${JSON.encode(field)}"); | 
| 592       } | 592       } | 
| 593     } | 593     } | 
| 594     return field.toLowerCase(); | 594     return field.toLowerCase(); | 
| 595   } | 595   } | 
| 596 | 596 | 
| 597   static _validateValue(value) { | 597   static _validateValue(value) { | 
| 598     if (value is! String) return value; | 598     if (value is! String) return value; | 
| 599     for (var i = 0; i < value.length; i++) { | 599     for (var i = 0; i < value.length; i++) { | 
| 600       if (!_HttpParser._isValueChar(value.codeUnitAt(i))) { | 600       if (!_HttpParser._isValueChar(value.codeUnitAt(i))) { | 
| 601         throw new FormatException( | 601         throw new FormatException( | 
| 602             "Invalid HTTP header field value: ${JSON.encode(value)}"); | 602             "Invalid HTTP header field value: ${JSON.encode(value)}"); | 
| 603       } | 603       } | 
| 604     } | 604     } | 
| 605     return value; | 605     return value; | 
| 606   } | 606   } | 
| 607 } | 607 } | 
| 608 | 608 | 
| 609 |  | 
| 610 class _HeaderValue implements HeaderValue { | 609 class _HeaderValue implements HeaderValue { | 
| 611   String _value; | 610   String _value; | 
| 612   Map<String, String> _parameters; | 611   Map<String, String> _parameters; | 
| 613   Map<String, String> _unmodifiableParameters; | 612   Map<String, String> _unmodifiableParameters; | 
| 614 | 613 | 
| 615   _HeaderValue([this._value = "", Map<String, String> parameters]) { | 614   _HeaderValue([this._value = "", Map<String, String> parameters]) { | 
| 616     if (parameters != null) { | 615     if (parameters != null) { | 
| 617       _parameters = new HashMap<String, String>.from(parameters); | 616       _parameters = new HashMap<String, String>.from(parameters); | 
| 618     } | 617     } | 
| 619   } | 618   } | 
| 620 | 619 | 
| 621   static _HeaderValue parse(String value, | 620   static _HeaderValue parse(String value, | 
| 622                             {parameterSeparator: ";", | 621       {parameterSeparator: ";", | 
| 623                              valueSeparator: null, | 622       valueSeparator: null, | 
| 624                              preserveBackslash: false}) { | 623       preserveBackslash: false}) { | 
| 625     // Parse the string. | 624     // Parse the string. | 
| 626     var result = new _HeaderValue(); | 625     var result = new _HeaderValue(); | 
| 627     result._parse(value, parameterSeparator, valueSeparator, preserveBackslash); | 626     result._parse(value, parameterSeparator, valueSeparator, preserveBackslash); | 
| 628     return result; | 627     return result; | 
| 629   } | 628   } | 
| 630 | 629 | 
| 631   String get value => _value; | 630   String get value => _value; | 
| 632 | 631 | 
| 633   void _ensureParameters() { | 632   void _ensureParameters() { | 
| 634     if (_parameters == null) { | 633     if (_parameters == null) { | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 648     StringBuffer sb = new StringBuffer(); | 647     StringBuffer sb = new StringBuffer(); | 
| 649     sb.write(_value); | 648     sb.write(_value); | 
| 650     if (parameters != null && parameters.length > 0) { | 649     if (parameters != null && parameters.length > 0) { | 
| 651       _parameters.forEach((String name, String value) { | 650       _parameters.forEach((String name, String value) { | 
| 652         sb..write("; ")..write(name)..write("=")..write(value); | 651         sb..write("; ")..write(name)..write("=")..write(value); | 
| 653       }); | 652       }); | 
| 654     } | 653     } | 
| 655     return sb.toString(); | 654     return sb.toString(); | 
| 656   } | 655   } | 
| 657 | 656 | 
| 658   void _parse(String s, | 657   void _parse(String s, String parameterSeparator, String valueSeparator, | 
| 659         String parameterSeparator, | 658       bool preserveBackslash) { | 
| 660         String valueSeparator, |  | 
| 661         bool preserveBackslash) { |  | 
| 662     int index = 0; | 659     int index = 0; | 
| 663 | 660 | 
| 664     bool done() => index == s.length; | 661     bool done() => index == s.length; | 
| 665 | 662 | 
| 666     void skipWS() { | 663     void skipWS() { | 
| 667       while (!done()) { | 664       while (!done()) { | 
| 668         if (s[index] != " " && s[index] != "\t") return; | 665         if (s[index] != " " && s[index] != "\t") return; | 
| 669         index++; | 666         index++; | 
| 670       } | 667       } | 
| 671     } | 668     } | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 756         } | 753         } | 
| 757         String value = parseParameterValue(); | 754         String value = parseParameterValue(); | 
| 758         if (name == 'charset' && this is _ContentType && value != null) { | 755         if (name == 'charset' && this is _ContentType && value != null) { | 
| 759           // Charset parameter of ContentTypes are always lower-case. | 756           // Charset parameter of ContentTypes are always lower-case. | 
| 760           value = value.toLowerCase(); | 757           value = value.toLowerCase(); | 
| 761         } | 758         } | 
| 762         parameters[name] = value; | 759         parameters[name] = value; | 
| 763         skipWS(); | 760         skipWS(); | 
| 764         if (done()) return; | 761         if (done()) return; | 
| 765         // TODO: Implement support for multi-valued parameters. | 762         // TODO: Implement support for multi-valued parameters. | 
| 766         if(s[index] == valueSeparator) return; | 763         if (s[index] == valueSeparator) return; | 
| 767         expect(parameterSeparator); | 764         expect(parameterSeparator); | 
| 768       } | 765       } | 
| 769     } | 766     } | 
| 770 | 767 | 
| 771     skipWS(); | 768     skipWS(); | 
| 772     _value = parseValue(); | 769     _value = parseValue(); | 
| 773     skipWS(); | 770     skipWS(); | 
| 774     if (done()) return; | 771     if (done()) return; | 
| 775     maybeExpect(parameterSeparator); | 772     maybeExpect(parameterSeparator); | 
| 776     parseParameters(); | 773     parseParameters(); | 
| 777   } | 774   } | 
| 778 } | 775 } | 
| 779 | 776 | 
| 780 |  | 
| 781 class _ContentType extends _HeaderValue implements ContentType { | 777 class _ContentType extends _HeaderValue implements ContentType { | 
| 782   String _primaryType = ""; | 778   String _primaryType = ""; | 
| 783   String _subType = ""; | 779   String _subType = ""; | 
| 784 | 780 | 
| 785   _ContentType(String primaryType, | 781   _ContentType(String primaryType, String subType, String charset, | 
| 786                String subType, | 782       Map<String, String> parameters) | 
| 787                String charset, | 783       : _primaryType = primaryType, | 
| 788                Map<String, String> parameters) | 784         _subType = subType, | 
| 789       : _primaryType = primaryType, _subType = subType, super("") { | 785         super("") { | 
| 790     if (_primaryType == null) _primaryType = ""; | 786     if (_primaryType == null) _primaryType = ""; | 
| 791     if (_subType == null) _subType = ""; | 787     if (_subType == null) _subType = ""; | 
| 792     _value = "$_primaryType/$_subType"; | 788     _value = "$_primaryType/$_subType"; | 
| 793     if (parameters != null) { | 789     if (parameters != null) { | 
| 794       _ensureParameters(); | 790       _ensureParameters(); | 
| 795       parameters.forEach((String key, String value) { | 791       parameters.forEach((String key, String value) { | 
| 796         String lowerCaseKey = key.toLowerCase(); | 792         String lowerCaseKey = key.toLowerCase(); | 
| 797         if (lowerCaseKey == "charset") { | 793         if (lowerCaseKey == "charset") { | 
| 798           value = value.toLowerCase(); | 794           value = value.toLowerCase(); | 
| 799         } | 795         } | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 825 | 821 | 
| 826   String get mimeType => '$primaryType/$subType'; | 822   String get mimeType => '$primaryType/$subType'; | 
| 827 | 823 | 
| 828   String get primaryType => _primaryType; | 824   String get primaryType => _primaryType; | 
| 829 | 825 | 
| 830   String get subType => _subType; | 826   String get subType => _subType; | 
| 831 | 827 | 
| 832   String get charset => parameters["charset"]; | 828   String get charset => parameters["charset"]; | 
| 833 } | 829 } | 
| 834 | 830 | 
| 835 |  | 
| 836 class _Cookie implements Cookie { | 831 class _Cookie implements Cookie { | 
| 837   String name; | 832   String name; | 
| 838   String value; | 833   String value; | 
| 839   DateTime expires; | 834   DateTime expires; | 
| 840   int maxAge; | 835   int maxAge; | 
| 841   String domain; | 836   String domain; | 
| 842   String path; | 837   String path; | 
| 843   bool httpOnly = false; | 838   bool httpOnly = false; | 
| 844   bool secure = false; | 839   bool secure = false; | 
| 845 | 840 | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 902           if (s[index] == ";") break; | 897           if (s[index] == ";") break; | 
| 903           index++; | 898           index++; | 
| 904         } | 899         } | 
| 905         return s.substring(start, index).trim().toLowerCase(); | 900         return s.substring(start, index).trim().toLowerCase(); | 
| 906       } | 901       } | 
| 907 | 902 | 
| 908       while (!done()) { | 903       while (!done()) { | 
| 909         String name = parseAttributeName(); | 904         String name = parseAttributeName(); | 
| 910         String value = ""; | 905         String value = ""; | 
| 911         if (!done() && s[index] == "=") { | 906         if (!done() && s[index] == "=") { | 
| 912           index++;  // Skip the = character. | 907           index++; // Skip the = character. | 
| 913           value = parseAttributeValue(); | 908           value = parseAttributeValue(); | 
| 914         } | 909         } | 
| 915         if (name == "expires") { | 910         if (name == "expires") { | 
| 916           expires = HttpDate._parseCookieDate(value); | 911           expires = HttpDate._parseCookieDate(value); | 
| 917         } else if (name == "max-age") { | 912         } else if (name == "max-age") { | 
| 918           maxAge = int.parse(value); | 913           maxAge = int.parse(value); | 
| 919         } else if (name == "domain") { | 914         } else if (name == "domain") { | 
| 920           domain = value; | 915           domain = value; | 
| 921         } else if (name == "path") { | 916         } else if (name == "path") { | 
| 922           path = value; | 917           path = value; | 
| 923         } else if (name == "httponly") { | 918         } else if (name == "httponly") { | 
| 924           httpOnly = true; | 919           httpOnly = true; | 
| 925         } else if (name == "secure") { | 920         } else if (name == "secure") { | 
| 926           secure = true; | 921           secure = true; | 
| 927         } | 922         } | 
| 928         if (!done()) index++;  // Skip the ; character | 923         if (!done()) index++; // Skip the ; character | 
| 929       } | 924       } | 
| 930     } | 925     } | 
| 931 | 926 | 
| 932     name = parseName(); | 927     name = parseName(); | 
| 933     if (done() || name.length == 0) { | 928     if (done() || name.length == 0) { | 
| 934       throw new HttpException("Failed to parse header value [$s]"); | 929       throw new HttpException("Failed to parse header value [$s]"); | 
| 935     } | 930     } | 
| 936     index++;  // Skip the = character. | 931     index++; // Skip the = character. | 
| 937     value = parseValue(); | 932     value = parseValue(); | 
| 938     _validate(); | 933     _validate(); | 
| 939     if (done()) return; | 934     if (done()) return; | 
| 940     index++;  // Skip the ; character. | 935     index++; // Skip the ; character. | 
| 941     parseAttributes(); | 936     parseAttributes(); | 
| 942   } | 937   } | 
| 943 | 938 | 
| 944   String toString() { | 939   String toString() { | 
| 945     StringBuffer sb = new StringBuffer(); | 940     StringBuffer sb = new StringBuffer(); | 
| 946     sb..write(name)..write("=")..write(value); | 941     sb..write(name)..write("=")..write(value); | 
| 947     if (expires != null) { | 942     if (expires != null) { | 
| 948       sb..write("; Expires=")..write(HttpDate.format(expires)); | 943       sb..write("; Expires=")..write(HttpDate.format(expires)); | 
| 949     } | 944     } | 
| 950     if (maxAge != null) { | 945     if (maxAge != null) { | 
| 951       sb..write("; Max-Age=")..write(maxAge); | 946       sb..write("; Max-Age=")..write(maxAge); | 
| 952     } | 947     } | 
| 953     if (domain != null) { | 948     if (domain != null) { | 
| 954       sb..write("; Domain=")..write(domain); | 949       sb..write("; Domain=")..write(domain); | 
| 955     } | 950     } | 
| 956     if (path != null) { | 951     if (path != null) { | 
| 957       sb..write("; Path=")..write(path); | 952       sb..write("; Path=")..write(path); | 
| 958     } | 953     } | 
| 959     if (secure) sb.write("; Secure"); | 954     if (secure) sb.write("; Secure"); | 
| 960     if (httpOnly) sb.write("; HttpOnly"); | 955     if (httpOnly) sb.write("; HttpOnly"); | 
| 961     return sb.toString(); | 956     return sb.toString(); | 
| 962   } | 957   } | 
| 963 | 958 | 
| 964   void _validate() { | 959   void _validate() { | 
| 965     const SEPERATORS = const [ | 960     const SEPERATORS = const [ | 
| 966         "(", ")", "<", ">", "@", ",", ";", ":", "\\", | 961       "(", | 
| 967         '"', "/", "[", "]", "?", "=", "{", "}"]; | 962       ")", | 
|  | 963       "<", | 
|  | 964       ">", | 
|  | 965       "@", | 
|  | 966       ",", | 
|  | 967       ";", | 
|  | 968       ":", | 
|  | 969       "\\", | 
|  | 970       '"', | 
|  | 971       "/", | 
|  | 972       "[", | 
|  | 973       "]", | 
|  | 974       "?", | 
|  | 975       "=", | 
|  | 976       "{", | 
|  | 977       "}" | 
|  | 978     ]; | 
| 968     for (int i = 0; i < name.length; i++) { | 979     for (int i = 0; i < name.length; i++) { | 
| 969       int codeUnit = name.codeUnits[i]; | 980       int codeUnit = name.codeUnits[i]; | 
| 970       if (codeUnit <= 32 || | 981       if (codeUnit <= 32 || | 
| 971           codeUnit >= 127 || | 982           codeUnit >= 127 || | 
| 972           SEPERATORS.indexOf(name[i]) >= 0) { | 983           SEPERATORS.indexOf(name[i]) >= 0) { | 
| 973         throw new FormatException( | 984         throw new FormatException( | 
| 974             "Invalid character in cookie name, code unit: '$codeUnit'"); | 985             "Invalid character in cookie name, code unit: '$codeUnit'"); | 
| 975       } | 986       } | 
| 976     } | 987     } | 
| 977     for (int i = 0; i < value.length; i++) { | 988     for (int i = 0; i < value.length; i++) { | 
| 978       int codeUnit = value.codeUnits[i]; | 989       int codeUnit = value.codeUnits[i]; | 
| 979       if (!(codeUnit == 0x21 || | 990       if (!(codeUnit == 0x21 || | 
| 980             (codeUnit >= 0x23 && codeUnit <= 0x2B) || | 991           (codeUnit >= 0x23 && codeUnit <= 0x2B) || | 
| 981             (codeUnit >= 0x2D && codeUnit <= 0x3A) || | 992           (codeUnit >= 0x2D && codeUnit <= 0x3A) || | 
| 982             (codeUnit >= 0x3C && codeUnit <= 0x5B) || | 993           (codeUnit >= 0x3C && codeUnit <= 0x5B) || | 
| 983             (codeUnit >= 0x5D && codeUnit <= 0x7E))) { | 994           (codeUnit >= 0x5D && codeUnit <= 0x7E))) { | 
| 984         throw new FormatException( | 995         throw new FormatException( | 
| 985             "Invalid character in cookie value, code unit: '$codeUnit'"); | 996             "Invalid character in cookie value, code unit: '$codeUnit'"); | 
| 986       } | 997       } | 
| 987     } | 998     } | 
| 988   } | 999   } | 
| 989 } | 1000 } | 
| OLD | NEW | 
|---|