| 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 _HttpIncoming extends Stream<List<int>> { | 7 class _HttpIncoming extends Stream<List<int>> { |
| 8 final int _transferLength; | 8 final int _transferLength; |
| 9 final Completer _dataCompleter = new Completer(); | 9 final Completer _dataCompleter = new Completer(); |
| 10 Stream<List<int>> _stream; | 10 Stream<List<int>> _stream; |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 _writeHeaders(); | 398 _writeHeaders(); |
| 399 return _ioSink.consume(stream); | 399 return _ioSink.consume(stream); |
| 400 } | 400 } |
| 401 | 401 |
| 402 Future<T> writeStream(Stream<List<int>> stream) { | 402 Future<T> writeStream(Stream<List<int>> stream) { |
| 403 _writeHeaders(); | 403 _writeHeaders(); |
| 404 return _ioSink.writeStream(stream).then((_) => this); | 404 return _ioSink.writeStream(stream).then((_) => this); |
| 405 } | 405 } |
| 406 | 406 |
| 407 void close() { | 407 void close() { |
| 408 if (!_headersWritten && !_ignoreBody && headers.chunkedTransferEncoding) { | 408 // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and |
| 409 // persistentConnection is not guaranteed to be in sync. |
| 410 if (!_headersWritten && !_ignoreBody && headers.contentLength == -1) { |
| 409 // If no body was written, _ignoreBody is false (it's not a HEAD | 411 // If no body was written, _ignoreBody is false (it's not a HEAD |
| 410 // request) and the content-length is unspecified, set contentLength to 0. | 412 // request) and the content-length is unspecified, set contentLength to 0. |
| 411 headers.chunkedTransferEncoding = false; | 413 headers.chunkedTransferEncoding = false; |
| 412 headers.contentLength = 0; | 414 headers.contentLength = 0; |
| 413 } | 415 } |
| 414 _writeHeaders(); | 416 _writeHeaders(); |
| 415 _ioSink.close(); | 417 _ioSink.close(); |
| 416 } | 418 } |
| 417 | 419 |
| 418 Future<T> get done { | 420 Future<T> get done { |
| 419 _writeHeaders(); | 421 _writeHeaders(); |
| 420 return _ioSink.done; | 422 return _ioSink.done; |
| 421 } | 423 } |
| 422 | 424 |
| 423 void _writeHeaders() { | 425 void _writeHeaders() { |
| 424 if (_headersWritten) return; | 426 if (_headersWritten) return; |
| 425 _headersWritten = true; | 427 _headersWritten = true; |
| 426 _ioSink.encoding = Encoding.ASCII; | 428 _ioSink.encoding = Encoding.ASCII; |
| 427 headers._synchronize(); // Be sure the 'chunked' option is updated. | 429 headers._synchronize(); // Be sure the 'chunked' option is updated. |
| 428 bool asGZip = false; | 430 bool asGZip = false; |
| 429 bool isServerSide = this is _HttpResponse; | 431 bool isServerSide = this is _HttpResponse; |
| 430 if (isServerSide && headers.chunkedTransferEncoding) { | 432 if (isServerSide && headers.chunkedTransferEncoding) { |
| 431 var response = this; | 433 var response = this; |
| 432 List acceptEncodings = | 434 List acceptEncodings = |
| 433 response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING]; | 435 response._httpRequest.headers[HttpHeaders.ACCEPT_ENCODING]; |
| 434 List contentEncoding = headers[HttpHeaders.CONTENT_ENCODING]; | 436 List contentEncoding = headers[HttpHeaders.CONTENT_ENCODING]; |
| 435 if (acceptEncodings != null && | 437 if (acceptEncodings != null && |
| 436 acceptEncodings.any((encoding) => encoding.toLowerCase() == "gzip") && | 438 acceptEncodings |
| 439 .expand((list) => list.split(",")) |
| 440 .any((encoding) => encoding.trim().toLowerCase() == "gzip") && |
| 437 contentEncoding == null) { | 441 contentEncoding == null) { |
| 438 headers.set(HttpHeaders.CONTENT_ENCODING, "gzip"); | 442 headers.set(HttpHeaders.CONTENT_ENCODING, "gzip"); |
| 439 asGZip = true; | 443 asGZip = true; |
| 440 } | 444 } |
| 441 } | 445 } |
| 442 _writeHeader(); | 446 _writeHeader(); |
| 443 _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip)); | 447 _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip)); |
| 444 _ioSink.encoding = encoding; | 448 _ioSink.encoding = encoding; |
| 445 } | 449 } |
| 446 | 450 |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 | 802 |
| 799 // Transformer that transforms data to HTTP Chunked Encoding. | 803 // Transformer that transforms data to HTTP Chunked Encoding. |
| 800 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> { | 804 class _ChunkedTransformer extends StreamEventTransformer<List<int>, List<int>> { |
| 801 void handleData(List<int> data, EventSink<List<int>> sink) { | 805 void handleData(List<int> data, EventSink<List<int>> sink) { |
| 802 sink.add(_chunkHeader(data.length)); | 806 sink.add(_chunkHeader(data.length)); |
| 803 if (data.length > 0) sink.add(data); | 807 if (data.length > 0) sink.add(data); |
| 804 sink.add(_chunkFooter); | 808 sink.add(_chunkFooter); |
| 805 } | 809 } |
| 806 | 810 |
| 807 void handleDone(EventSink<List<int>> sink) { | 811 void handleDone(EventSink<List<int>> sink) { |
| 808 handleData([], sink); | 812 handleData(const [], sink); |
| 809 sink.close(); | 813 sink.close(); |
| 810 } | 814 } |
| 811 | 815 |
| 812 static List<int> _chunkHeader(int length) { | 816 static List<int> _chunkHeader(int length) { |
| 813 const hexDigits = const [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, | 817 const hexDigits = const [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
| 814 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46]; | 818 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46]; |
| 815 var header = []; | 819 var header = []; |
| 816 if (length == 0) { | 820 if (length == 0) { |
| 817 header.add(hexDigits[length]); | 821 header.add(hexDigits[length]); |
| 818 } else { | 822 } else { |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 | 1714 |
| 1711 | 1715 |
| 1712 class _RedirectInfo implements RedirectInfo { | 1716 class _RedirectInfo implements RedirectInfo { |
| 1713 const _RedirectInfo(int this.statusCode, | 1717 const _RedirectInfo(int this.statusCode, |
| 1714 String this.method, | 1718 String this.method, |
| 1715 Uri this.location); | 1719 Uri this.location); |
| 1716 final int statusCode; | 1720 final int statusCode; |
| 1717 final String method; | 1721 final String method; |
| 1718 final Uri location; | 1722 final Uri location; |
| 1719 } | 1723 } |
| OLD | NEW |