| 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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 } | 679 } |
| 680 } | 680 } |
| 681 | 681 |
| 682 | 682 |
| 683 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> | 683 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> |
| 684 implements HttpResponse { | 684 implements HttpResponse { |
| 685 int statusCode = 200; | 685 int statusCode = 200; |
| 686 String _reasonPhrase; | 686 String _reasonPhrase; |
| 687 List<Cookie> _cookies; | 687 List<Cookie> _cookies; |
| 688 _HttpRequest _httpRequest; | 688 _HttpRequest _httpRequest; |
| 689 Duration _deadline; |
| 690 Timer _deadlineTimer; |
| 689 | 691 |
| 690 _HttpResponse(Uri uri, | 692 _HttpResponse(Uri uri, |
| 691 String protocolVersion, | 693 String protocolVersion, |
| 692 _HttpOutgoing _outgoing, | 694 _HttpOutgoing outgoing, |
| 693 String serverHeader) | 695 String serverHeader) |
| 694 : super(uri, protocolVersion, _outgoing) { | 696 : super(uri, protocolVersion, outgoing) { |
| 695 if (serverHeader != null) headers.set('Server', serverHeader); | 697 if (serverHeader != null) headers.set('Server', serverHeader); |
| 696 } | 698 } |
| 697 | 699 |
| 698 List<Cookie> get cookies { | 700 List<Cookie> get cookies { |
| 699 if (_cookies == null) _cookies = new List<Cookie>(); | 701 if (_cookies == null) _cookies = new List<Cookie>(); |
| 700 return _cookies; | 702 return _cookies; |
| 701 } | 703 } |
| 702 | 704 |
| 703 String get reasonPhrase => _findReasonPhrase(statusCode); | 705 String get reasonPhrase => _findReasonPhrase(statusCode); |
| 704 void set reasonPhrase(String reasonPhrase) { | 706 void set reasonPhrase(String reasonPhrase) { |
| 705 if (_headersWritten) throw new StateError("Header already sent"); | 707 if (_headersWritten) throw new StateError("Header already sent"); |
| 706 _reasonPhrase = reasonPhrase; | 708 _reasonPhrase = reasonPhrase; |
| 707 } | 709 } |
| 708 | 710 |
| 709 Future<Socket> detachSocket() { | 711 Future<Socket> detachSocket() { |
| 710 if (_headersWritten) throw new StateError("Headers already sent"); | 712 if (_headersWritten) throw new StateError("Headers already sent"); |
| 713 deadline = null; // Be sure to stop any deadline. |
| 711 var future = _httpRequest._httpConnection.detachSocket(); | 714 var future = _httpRequest._httpConnection.detachSocket(); |
| 712 _writeHeaders(drainRequest: false).then((_) => close()); | 715 _writeHeaders(drainRequest: false).then((_) => close()); |
| 713 // Close connection so the socket is 'free'. | 716 // Close connection so the socket is 'free'. |
| 714 close(); | 717 close(); |
| 715 done.catchError((_) { | 718 done.catchError((_) { |
| 716 // Catch any error on done, as they automatically will be | 719 // Catch any error on done, as they automatically will be |
| 717 // propagated to the websocket. | 720 // propagated to the websocket. |
| 718 }); | 721 }); |
| 719 return future; | 722 return future; |
| 720 } | 723 } |
| 721 | 724 |
| 722 HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; | 725 HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo; |
| 723 | 726 |
| 727 Duration get deadline => _deadline; |
| 728 |
| 729 void set deadline(Duration d) { |
| 730 if (_deadlineTimer != null) _deadlineTimer.cancel(); |
| 731 _deadline = d; |
| 732 |
| 733 if (_deadline == null) return; |
| 734 _deadlineTimer = new Timer(_deadline, () { |
| 735 _outgoing.socket.destroy(); |
| 736 }); |
| 737 } |
| 738 |
| 724 void _writeHeader() { | 739 void _writeHeader() { |
| 725 var builder = new BytesBuilder(); | 740 var builder = new BytesBuilder(); |
| 726 writeSP() => builder.add(const [_CharCode.SP]); | 741 writeSP() => builder.add(const [_CharCode.SP]); |
| 727 writeCRLF() => builder.add(const [_CharCode.CR, _CharCode.LF]); | 742 writeCRLF() => builder.add(const [_CharCode.CR, _CharCode.LF]); |
| 728 | 743 |
| 729 // Write status line. | 744 // Write status line. |
| 730 if (headers.protocolVersion == "1.1") { | 745 if (headers.protocolVersion == "1.1") { |
| 731 builder.add(_Const.HTTP11); | 746 builder.add(_Const.HTTP11); |
| 732 } else { | 747 } else { |
| 733 builder.add(_Const.HTTP10); | 748 builder.add(_Const.HTTP10); |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 uri: uri)); | 1106 uri: uri)); |
| 1092 } | 1107 } |
| 1093 sink.close(); | 1108 sink.close(); |
| 1094 } | 1109 } |
| 1095 } | 1110 } |
| 1096 | 1111 |
| 1097 | 1112 |
| 1098 // Extends StreamConsumer as this is an internal type, only used to pipe to. | 1113 // Extends StreamConsumer as this is an internal type, only used to pipe to. |
| 1099 class _HttpOutgoing implements StreamConsumer<List<int>> { | 1114 class _HttpOutgoing implements StreamConsumer<List<int>> { |
| 1100 final Completer _doneCompleter = new Completer(); | 1115 final Completer _doneCompleter = new Completer(); |
| 1101 final StreamConsumer _consumer; | 1116 final Socket socket; |
| 1102 | 1117 |
| 1103 _HttpOutgoing(StreamConsumer this._consumer); | 1118 _HttpOutgoing(Socket this.socket); |
| 1104 | 1119 |
| 1105 Future addStream(Stream<List<int>> stream) { | 1120 Future addStream(Stream<List<int>> stream) { |
| 1106 return _consumer.addStream(stream) | 1121 return socket.addStream(stream) |
| 1107 .catchError((error) { | 1122 .catchError((error) { |
| 1108 _doneCompleter.completeError(error); | 1123 _doneCompleter.completeError(error); |
| 1109 throw error; | 1124 throw error; |
| 1110 }); | 1125 }); |
| 1111 } | 1126 } |
| 1112 | 1127 |
| 1113 Future close() { | 1128 Future close() { |
| 1114 _doneCompleter.complete(_consumer); | 1129 _doneCompleter.complete(socket); |
| 1115 return new Future.value(); | 1130 return new Future.value(); |
| 1116 } | 1131 } |
| 1117 | 1132 |
| 1118 Future get done => _doneCompleter.future; | 1133 Future get done => _doneCompleter.future; |
| 1119 } | 1134 } |
| 1120 | 1135 |
| 1121 class _HttpClientConnection { | 1136 class _HttpClientConnection { |
| 1122 final String key; | 1137 final String key; |
| 1123 final Socket _socket; | 1138 final Socket _socket; |
| 1124 final bool _proxyTunnel; | 1139 final bool _proxyTunnel; |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 _subscription.pause(); | 1820 _subscription.pause(); |
| 1806 _state = _ACTIVE; | 1821 _state = _ACTIVE; |
| 1807 var outgoing = new _HttpOutgoing(_socket); | 1822 var outgoing = new _HttpOutgoing(_socket); |
| 1808 var response = new _HttpResponse(incoming.uri, | 1823 var response = new _HttpResponse(incoming.uri, |
| 1809 incoming.headers.protocolVersion, | 1824 incoming.headers.protocolVersion, |
| 1810 outgoing, | 1825 outgoing, |
| 1811 _httpServer.serverHeader); | 1826 _httpServer.serverHeader); |
| 1812 var request = new _HttpRequest(response, incoming, _httpServer, this); | 1827 var request = new _HttpRequest(response, incoming, _httpServer, this); |
| 1813 _streamFuture = outgoing.done | 1828 _streamFuture = outgoing.done |
| 1814 .then((_) { | 1829 .then((_) { |
| 1830 response.deadline = null; |
| 1815 if (_state == _DETACHED) return; | 1831 if (_state == _DETACHED) return; |
| 1816 if (response.persistentConnection && | 1832 if (response.persistentConnection && |
| 1817 request.persistentConnection && | 1833 request.persistentConnection && |
| 1818 incoming.fullBodyRead) { | 1834 incoming.fullBodyRead) { |
| 1819 _state = _IDLE; | 1835 _state = _IDLE; |
| 1820 // Resume the subscription for incoming requests as the | 1836 // Resume the subscription for incoming requests as the |
| 1821 // request is now processed. | 1837 // request is now processed. |
| 1822 _subscription.resume(); | 1838 _subscription.resume(); |
| 1823 } else { | 1839 } else { |
| 1824 // Close socket, keep-alive not used or body sent before | 1840 // Close socket, keep-alive not used or body sent before |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 final Uri location; | 2424 final Uri location; |
| 2409 } | 2425 } |
| 2410 | 2426 |
| 2411 String _getHttpVersion() { | 2427 String _getHttpVersion() { |
| 2412 var version = Platform.version; | 2428 var version = Platform.version; |
| 2413 // Only include major and minor version numbers. | 2429 // Only include major and minor version numbers. |
| 2414 int index = version.indexOf('.', version.indexOf('.') + 1); | 2430 int index = version.indexOf('.', version.indexOf('.') + 1); |
| 2415 version = version.substring(0, index); | 2431 version = version.substring(0, index); |
| 2416 return 'Dart/$version (dart:io)'; | 2432 return 'Dart/$version (dart:io)'; |
| 2417 } | 2433 } |
| OLD | NEW |