Chromium Code Reviews| 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 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 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 _state = _State.HEADER_VALUE_FOLD_OR_END; | 380 _state = _State.HEADER_VALUE_FOLD_OR_END; |
| 381 break; | 381 break; |
| 382 | 382 |
| 383 case _State.HEADER_VALUE_FOLD_OR_END: | 383 case _State.HEADER_VALUE_FOLD_OR_END: |
| 384 if (byte == _CharCode.SP || byte == _CharCode.HT) { | 384 if (byte == _CharCode.SP || byte == _CharCode.HT) { |
| 385 _state = _State.HEADER_VALUE_START; | 385 _state = _State.HEADER_VALUE_START; |
| 386 } else { | 386 } else { |
| 387 String headerField = new String.fromCharCodes(_headerField); | 387 String headerField = new String.fromCharCodes(_headerField); |
| 388 String headerValue = new String.fromCharCodes(_headerValue); | 388 String headerValue = new String.fromCharCodes(_headerValue); |
| 389 bool reportHeader = true; | 389 bool reportHeader = true; |
| 390 if (headerField == "content-length" && !_chunked) { | 390 if (headerField == "connection") { |
| 391 // Ignore the Content-Length header if Transfer-Encoding | |
| 392 // is chunked (RFC 2616 section 4.4) | |
| 393 _contentLength = parseInt(headerValue); | |
| 394 } else if (headerField == "connection") { | |
| 395 List<String> tokens = _tokenizeFieldValue(headerValue); | 391 List<String> tokens = _tokenizeFieldValue(headerValue); |
| 396 for (int i = 0; i < tokens.length; i++) { | 392 for (int i = 0; i < tokens.length; i++) { |
| 397 String token = tokens[i].toLowerCase(); | 393 String token = tokens[i].toLowerCase(); |
| 398 if (token == "keep-alive") { | 394 if (token == "keep-alive") { |
| 399 _persistentConnection = true; | 395 _persistentConnection = true; |
| 400 } else if (token == "close") { | 396 } else if (token == "close") { |
| 401 _persistentConnection = false; | 397 _persistentConnection = false; |
| 402 } else if (token == "upgrade") { | 398 } else if (token == "upgrade") { |
| 403 _connectionUpgrade = true; | 399 _connectionUpgrade = true; |
| 404 } | 400 } |
| 405 _headers.add(headerField, token); | 401 _headers.add(headerField, token); |
| 406 | 402 |
| 407 } | 403 } |
| 408 reportHeader = false; | 404 reportHeader = false; |
| 409 } else if (headerField == "transfer-encoding" && | 405 } else if (headerField == "transfer-encoding" && |
| 410 headerValue.toLowerCase() == "chunked") { | 406 headerValue.toLowerCase() == "chunked") { |
| 411 // Ignore the Content-Length header if Transfer-Encoding | |
| 412 // is chunked (RFC 2616 section 4.4) | |
| 413 _chunked = true; | 407 _chunked = true; |
| 414 _contentLength = -1; | |
| 415 } | 408 } |
| 416 if (reportHeader) { | 409 if (reportHeader) { |
| 417 _headers.add(headerField, headerValue); | 410 _headers.add(headerField, headerValue); |
| 418 } | 411 } |
| 419 _headerField.clear(); | 412 _headerField.clear(); |
| 420 _headerValue.clear(); | 413 _headerValue.clear(); |
| 421 | 414 |
| 422 if (byte == _CharCode.CR) { | 415 if (byte == _CharCode.CR) { |
| 423 _state = _State.HEADER_ENDING; | 416 _state = _State.HEADER_ENDING; |
| 424 } else { | 417 } else { |
| 425 // Start of new header field. | 418 // Start of new header field. |
| 426 _headerField.add(_toLowerCase(byte)); | 419 _headerField.add(_toLowerCase(byte)); |
| 427 _state = _State.HEADER_FIELD; | 420 _state = _State.HEADER_FIELD; |
| 428 } | 421 } |
| 429 } | 422 } |
| 430 break; | 423 break; |
| 431 | 424 |
| 432 case _State.HEADER_ENDING: | 425 case _State.HEADER_ENDING: |
| 433 _expect(byte, _CharCode.LF); | 426 _expect(byte, _CharCode.LF); |
| 427 | |
| 428 _contentLength = _headers.contentLength; | |
|
Anders Johnsen
2012/12/19 15:43:58
Nice cleanup!
Søren Gjesse
2012/12/20 07:39:01
Thanks.
| |
| 429 // Ignore the Content-Length header if Transfer-Encoding | |
| 430 // is chunked (RFC 2616 section 4.4) | |
| 431 if (_chunked) _contentLength = -1; | |
| 432 | |
| 434 // If a request message has neither Content-Length nor | 433 // If a request message has neither Content-Length nor |
| 435 // Transfer-Encoding the message must not have a body (RFC | 434 // Transfer-Encoding the message must not have a body (RFC |
| 436 // 2616 section 4.3). | 435 // 2616 section 4.3). |
| 437 if (_messageType == _MessageType.REQUEST && | 436 if (_messageType == _MessageType.REQUEST && |
| 438 _contentLength < 0 && | 437 _contentLength < 0 && |
| 439 _chunked == false) { | 438 _chunked == false) { |
| 440 _contentLength = 0; | 439 _contentLength = 0; |
| 441 } | 440 } |
| 442 if (_connectionUpgrade) { | 441 if (_connectionUpgrade) { |
| 443 _state = _State.UPGRADED; | 442 _state = _State.UPGRADED; |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 Function error; | 784 Function error; |
| 786 Function closed; | 785 Function closed; |
| 787 } | 786 } |
| 788 | 787 |
| 789 | 788 |
| 790 class HttpParserException implements Exception { | 789 class HttpParserException implements Exception { |
| 791 const HttpParserException([String this.message = ""]); | 790 const HttpParserException([String this.message = ""]); |
| 792 String toString() => "HttpParserException: $message"; | 791 String toString() => "HttpParserException: $message"; |
| 793 final String message; | 792 final String message; |
| 794 } | 793 } |
| OLD | NEW |