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 // Global constants. | 7 // Global constants. |
8 class _Const { | 8 class _Const { |
9 // Bytes for "HTTP". | 9 // Bytes for "HTTP". |
10 static const HTTP = const [72, 84, 84, 80]; | 10 static const HTTP = const [72, 84, 84, 80]; |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 } | 540 } |
541 _state = _State.HEADER_START; | 541 _state = _State.HEADER_START; |
542 break; | 542 break; |
543 | 543 |
544 case _State.HEADER_START: | 544 case _State.HEADER_START: |
545 _headers = new _HttpHeaders(version); | 545 _headers = new _HttpHeaders(version); |
546 if (byte == _CharCode.CR) { | 546 if (byte == _CharCode.CR) { |
547 _state = _State.HEADER_ENDING; | 547 _state = _State.HEADER_ENDING; |
548 } else { | 548 } else { |
549 // Start of new header field. | 549 // Start of new header field. |
550 _headerField.add(_toLowerCase(byte)); | 550 _headerField.add(_toLowerCaseByte(byte)); |
551 _state = _State.HEADER_FIELD; | 551 _state = _State.HEADER_FIELD; |
552 } | 552 } |
553 break; | 553 break; |
554 | 554 |
555 case _State.HEADER_FIELD: | 555 case _State.HEADER_FIELD: |
556 if (byte == _CharCode.COLON) { | 556 if (byte == _CharCode.COLON) { |
557 _state = _State.HEADER_VALUE_START; | 557 _state = _State.HEADER_VALUE_START; |
558 } else { | 558 } else { |
559 if (!_isTokenChar(byte)) { | 559 if (!_isTokenChar(byte)) { |
560 throw new HttpException("Invalid header field name"); | 560 throw new HttpException("Invalid header field name"); |
561 } | 561 } |
562 _headerField.add(_toLowerCase(byte)); | 562 _headerField.add(_toLowerCaseByte(byte)); |
563 } | 563 } |
564 break; | 564 break; |
565 | 565 |
566 case _State.HEADER_VALUE_START: | 566 case _State.HEADER_VALUE_START: |
567 if (byte == _CharCode.CR) { | 567 if (byte == _CharCode.CR) { |
568 _state = _State.HEADER_VALUE_FOLDING_OR_ENDING; | 568 _state = _State.HEADER_VALUE_FOLDING_OR_ENDING; |
569 } else if (byte != _CharCode.SP && byte != _CharCode.HT) { | 569 } else if (byte != _CharCode.SP && byte != _CharCode.HT) { |
570 // Start of new header value. | 570 // Start of new header value. |
571 _headerValue.add(byte); | 571 _headerValue.add(byte); |
572 _state = _State.HEADER_VALUE; | 572 _state = _State.HEADER_VALUE; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 } else { | 608 } else { |
609 _headers._add(headerField, headerValue); | 609 _headers._add(headerField, headerValue); |
610 } | 610 } |
611 _headerField.clear(); | 611 _headerField.clear(); |
612 _headerValue.clear(); | 612 _headerValue.clear(); |
613 | 613 |
614 if (byte == _CharCode.CR) { | 614 if (byte == _CharCode.CR) { |
615 _state = _State.HEADER_ENDING; | 615 _state = _State.HEADER_ENDING; |
616 } else { | 616 } else { |
617 // Start of new header field. | 617 // Start of new header field. |
618 _headerField.add(_toLowerCase(byte)); | 618 _headerField.add(_toLowerCaseByte(byte)); |
619 _state = _State.HEADER_FIELD; | 619 _state = _State.HEADER_FIELD; |
620 } | 620 } |
621 } | 621 } |
622 break; | 622 break; |
623 | 623 |
624 case _State.HEADER_ENDING: | 624 case _State.HEADER_ENDING: |
625 _expect(byte, _CharCode.LF); | 625 _expect(byte, _CharCode.LF); |
626 _headers._mutable = false; | 626 _headers._mutable = false; |
627 | 627 |
628 _transferLength = _headers.contentLength; | 628 _transferLength = _headers.contentLength; |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 start = index + 1; | 926 start = index + 1; |
927 } else if (headerValue[index] == " " || headerValue[index] == "\t") { | 927 } else if (headerValue[index] == " " || headerValue[index] == "\t") { |
928 start++; | 928 start++; |
929 } | 929 } |
930 index++; | 930 index++; |
931 } | 931 } |
932 tokens.add(headerValue.substring(start, index)); | 932 tokens.add(headerValue.substring(start, index)); |
933 return tokens; | 933 return tokens; |
934 } | 934 } |
935 | 935 |
936 int _toLowerCase(int byte) { | 936 static int _toLowerCaseByte(int x) { |
937 final int aCode = "A".codeUnitAt(0); | 937 // Optimized version: |
938 final int zCode = "Z".codeUnitAt(0); | 938 // - 0x41 is 'A' |
939 final int delta = "a".codeUnitAt(0) - aCode; | 939 // - 0x7f is ASCII mask |
940 return (aCode <= byte && byte <= zCode) ? byte + delta : byte; | 940 // - 26 is the number of alpha characters. |
| 941 // - 0x20 is the delta between lower and upper chars. |
| 942 return (((x - 0x41) & 0x7f) < 26) ? (x | 0x20) : x; |
941 } | 943 } |
942 | 944 |
943 // expected should already be lowercase. | 945 // expected should already be lowercase. |
944 bool _caseInsensitiveCompare(List<int> expected, List<int> value) { | 946 bool _caseInsensitiveCompare(List<int> expected, List<int> value) { |
945 if (expected.length != value.length) return false; | 947 if (expected.length != value.length) return false; |
946 for (int i = 0; i < expected.length; i++) { | 948 for (int i = 0; i < expected.length; i++) { |
947 if (expected[i] != _toLowerCase(value[i])) return false; | 949 if (expected[i] != _toLowerCaseByte(value[i])) return false; |
948 } | 950 } |
949 return true; | 951 return true; |
950 } | 952 } |
951 | 953 |
952 int _expect(int val1, int val2) { | 954 int _expect(int val1, int val2) { |
953 if (val1 != val2) { | 955 if (val1 != val2) { |
954 throw new HttpException("Failed to parse HTTP"); | 956 throw new HttpException("Failed to parse HTTP"); |
955 } | 957 } |
956 } | 958 } |
957 | 959 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 } | 1034 } |
1033 } | 1035 } |
1034 | 1036 |
1035 void _reportError(error, [stackTrace]) { | 1037 void _reportError(error, [stackTrace]) { |
1036 if (_socketSubscription != null) _socketSubscription.cancel(); | 1038 if (_socketSubscription != null) _socketSubscription.cancel(); |
1037 _state = _State.FAILURE; | 1039 _state = _State.FAILURE; |
1038 _controller.addError(error, stackTrace); | 1040 _controller.addError(error, stackTrace); |
1039 _controller.close(); | 1041 _controller.close(); |
1040 } | 1042 } |
1041 } | 1043 } |
OLD | NEW |