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 |