| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 // Global constants. | 5 // Global constants. |
| 6 class _Const { | 6 class _Const { |
| 7 // Bytes for "HTTP". | 7 // Bytes for "HTTP". |
| 8 static const HTTP = const [72, 84, 84, 80]; | 8 static const HTTP = const [72, 84, 84, 80]; |
| 9 // Bytes for "HTTP/1.". | 9 // Bytes for "HTTP/1.". |
| 10 static const HTTP1DOT = const [72, 84, 84, 80, 47, 49, 46]; | 10 static const HTTP1DOT = const [72, 84, 84, 80, 47, 49, 46]; |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 if (byte == _CharCode.CR || byte == _CharCode.LF) { | 319 if (byte == _CharCode.CR || byte == _CharCode.LF) { |
| 320 throw new HttpParserException("Invalid response reason phrase"); | 320 throw new HttpParserException("Invalid response reason phrase"); |
| 321 } | 321 } |
| 322 _uri_or_reason_phrase.add(byte); | 322 _uri_or_reason_phrase.add(byte); |
| 323 } | 323 } |
| 324 break; | 324 break; |
| 325 | 325 |
| 326 case _State.RESPONSE_LINE_ENDING: | 326 case _State.RESPONSE_LINE_ENDING: |
| 327 _expect(byte, _CharCode.LF); | 327 _expect(byte, _CharCode.LF); |
| 328 _messageType == _MessageType.RESPONSE; | 328 _messageType == _MessageType.RESPONSE; |
| 329 _statusCode = parseInt(new String.fromCharCodes(_method_or_status_c
ode)); | 329 _statusCode = parseInt( |
| 330 new String.fromCharCodes(_method_or_status_code)); |
| 330 if (_statusCode < 100 || _statusCode > 599) { | 331 if (_statusCode < 100 || _statusCode > 599) { |
| 331 throw new HttpParserException("Invalid response status code"); | 332 throw new HttpParserException("Invalid response status code"); |
| 332 } else { | |
| 333 // Check whether this response will never have a body. | |
| 334 _noMessageBody = | |
| 335 _statusCode <= 199 || _statusCode == 204 || _statusCode == 304
; | |
| 336 } | 333 } |
| 337 _state = _State.HEADER_START; | 334 _state = _State.HEADER_START; |
| 338 break; | 335 break; |
| 339 | 336 |
| 340 case _State.HEADER_START: | 337 case _State.HEADER_START: |
| 341 if (byte == _CharCode.CR) { | 338 if (byte == _CharCode.CR) { |
| 342 _state = _State.HEADER_ENDING; | 339 _state = _State.HEADER_ENDING; |
| 343 } else { | 340 } else { |
| 344 // Start of new header field. | 341 // Start of new header field. |
| 345 _headerField.add(_toLowerCase(byte)); | 342 _headerField.add(_toLowerCase(byte)); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 // Transfer-Encoding the message must not have a body (RFC | 433 // Transfer-Encoding the message must not have a body (RFC |
| 437 // 2616 section 4.3). | 434 // 2616 section 4.3). |
| 438 if (_messageType == _MessageType.REQUEST && | 435 if (_messageType == _MessageType.REQUEST && |
| 439 _contentLength < 0 && | 436 _contentLength < 0 && |
| 440 _chunked == false) { | 437 _chunked == false) { |
| 441 _contentLength = 0; | 438 _contentLength = 0; |
| 442 } | 439 } |
| 443 if (_connectionUpgrade) { | 440 if (_connectionUpgrade) { |
| 444 _state = _State.UPGRADED; | 441 _state = _State.UPGRADED; |
| 445 } | 442 } |
| 443 var noBody; |
| 446 if (_requestParser) { | 444 if (_requestParser) { |
| 445 noBody = _contentLength == 0; |
| 447 requestStart(new String.fromCharCodes(_method_or_status_code), | 446 requestStart(new String.fromCharCodes(_method_or_status_code), |
| 448 new String.fromCharCodes(_uri_or_reason_phrase), | 447 new String.fromCharCodes(_uri_or_reason_phrase), |
| 449 version, | 448 version, |
| 450 _headers); | 449 _headers, |
| 450 !noBody); |
| 451 } else { | 451 } else { |
| 452 // Check whether this response will never have a body. |
| 453 noBody = _contentLength == 0 || |
| 454 _statusCode <= 199 || |
| 455 _statusCode == HttpStatus.NO_CONTENT || |
| 456 _statusCode == HttpStatus.NOT_MODIFIED || |
| 457 _responseToMethod == "HEAD"; |
| 452 responseStart(_statusCode, | 458 responseStart(_statusCode, |
| 453 new String.fromCharCodes(_uri_or_reason_phrase), | 459 new String.fromCharCodes(_uri_or_reason_phrase), |
| 454 version, | 460 version, |
| 455 _headers); | 461 _headers, |
| 462 !noBody); |
| 456 } | 463 } |
| 457 if (_state == _State.CANCELED) continue; | |
| 458 _method_or_status_code.clear(); | 464 _method_or_status_code.clear(); |
| 459 _uri_or_reason_phrase.clear(); | 465 _uri_or_reason_phrase.clear(); |
| 466 if (_state == _State.CANCELED) continue; |
| 460 if (!_connectionUpgrade) { | 467 if (!_connectionUpgrade) { |
| 461 _method_or_status_code.clear(); | 468 if (noBody) { |
| 462 _uri_or_reason_phrase.clear(); | 469 _bodyEnd(); |
| 463 if (_chunked) { | 470 _reset(); |
| 471 } else if (_chunked) { |
| 464 _state = _State.CHUNK_SIZE; | 472 _state = _State.CHUNK_SIZE; |
| 465 _remainingContent = 0; | 473 _remainingContent = 0; |
| 466 } else if (_contentLength == 0 || | |
| 467 (_messageType == _MessageType.RESPONSE && | |
| 468 (_noMessageBody || _responseToMethod == "HEAD"))) { | |
| 469 // If there is no message body get ready to process the | |
| 470 // next request. | |
| 471 _bodyEnd(); | |
| 472 if (_state == _State.CANCELED) continue; | |
| 473 _reset(); | |
| 474 } else if (_contentLength > 0) { | 474 } else if (_contentLength > 0) { |
| 475 _remainingContent = _contentLength; | 475 _remainingContent = _contentLength; |
| 476 _state = _State.BODY; | 476 _state = _State.BODY; |
| 477 } else { | 477 } else { |
| 478 // Neither chunked nor content length. End of body | 478 // Neither chunked nor content length. End of body |
| 479 // indicated by close. | 479 // indicated by close. |
| 480 _state = _State.BODY; | 480 _state = _State.BODY; |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 break; | 483 break; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 _headerValue = new List(); | 684 _headerValue = new List(); |
| 685 _method_or_status_code = new List(); | 685 _method_or_status_code = new List(); |
| 686 _uri_or_reason_phrase = new List(); | 686 _uri_or_reason_phrase = new List(); |
| 687 | 687 |
| 688 _httpVersion = _HttpVersion.UNDETERMINED; | 688 _httpVersion = _HttpVersion.UNDETERMINED; |
| 689 _contentLength = -1; | 689 _contentLength = -1; |
| 690 _persistentConnection = false; | 690 _persistentConnection = false; |
| 691 _connectionUpgrade = false; | 691 _connectionUpgrade = false; |
| 692 _chunked = false; | 692 _chunked = false; |
| 693 | 693 |
| 694 _noMessageBody = false; | |
| 695 _responseToMethod = null; | 694 _responseToMethod = null; |
| 696 _remainingContent = null; | 695 _remainingContent = null; |
| 697 | 696 |
| 698 _headers = new _HttpHeaders(); | 697 _headers = new _HttpHeaders(); |
| 699 } | 698 } |
| 700 | 699 |
| 701 _releaseBuffer() { | 700 _releaseBuffer() { |
| 702 _buffer = null; | 701 _buffer = null; |
| 703 _index = null; | 702 _index = null; |
| 704 _lastIndex = null; | 703 _lastIndex = null; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 List _uri_or_reason_phrase; | 763 List _uri_or_reason_phrase; |
| 765 List _headerField; | 764 List _headerField; |
| 766 List _headerValue; | 765 List _headerValue; |
| 767 | 766 |
| 768 int _httpVersion; | 767 int _httpVersion; |
| 769 int _contentLength; | 768 int _contentLength; |
| 770 bool _persistentConnection; | 769 bool _persistentConnection; |
| 771 bool _connectionUpgrade; | 770 bool _connectionUpgrade; |
| 772 bool _chunked; | 771 bool _chunked; |
| 773 | 772 |
| 774 bool _noMessageBody; | |
| 775 String _responseToMethod; // Indicates the method used for the request. | 773 String _responseToMethod; // Indicates the method used for the request. |
| 776 int _remainingContent; | 774 int _remainingContent; |
| 777 | 775 |
| 778 _HttpHeaders _headers = new _HttpHeaders(); | 776 _HttpHeaders _headers = new _HttpHeaders(); |
| 779 | 777 |
| 780 // Callbacks. | 778 // Callbacks. |
| 781 Function requestStart; | 779 Function requestStart; |
| 782 Function responseStart; | 780 Function responseStart; |
| 783 Function dataReceived; | 781 Function dataReceived; |
| 784 Function dataEnd; | 782 Function dataEnd; |
| 785 Function error; | 783 Function error; |
| 786 Function closed; | 784 Function closed; |
| 787 } | 785 } |
| 788 | 786 |
| 789 | 787 |
| 790 class HttpParserException implements Exception { | 788 class HttpParserException implements Exception { |
| 791 const HttpParserException([String this.message = ""]); | 789 const HttpParserException([String this.message = ""]); |
| 792 String toString() => "HttpParserException: $message"; | 790 String toString() => "HttpParserException: $message"; |
| 793 final String message; | 791 final String message; |
| 794 } | 792 } |
| OLD | NEW |