Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: sdk/lib/io/http_impl.dart

Issue 15256002: Rewrite parts of http-parser, to better handle connection errors and pausing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/io/http_parser.dart » ('j') | sdk/lib/io/http_parser.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 } 1064 }
1065 1065
1066 class _HttpClientConnection { 1066 class _HttpClientConnection {
1067 final String key; 1067 final String key;
1068 final Socket _socket; 1068 final Socket _socket;
1069 final bool _proxyTunnel; 1069 final bool _proxyTunnel;
1070 final _HttpParser _httpParser; 1070 final _HttpParser _httpParser;
1071 StreamSubscription _subscription; 1071 StreamSubscription _subscription;
1072 final _HttpClient _httpClient; 1072 final _HttpClient _httpClient;
1073 bool _dispose = false; 1073 bool _dispose = false;
1074 bool closed = false;
Søren Gjesse 2013/05/17 07:09:28 Private? (also key above).
Anders Johnsen 2013/05/17 08:27:59 This is used from another class (HttpClient). Also
1074 1075
1075 Completer<_HttpIncoming> _nextResponseCompleter; 1076 Completer<_HttpIncoming> _nextResponseCompleter;
1076 Future _streamFuture; 1077 Future _streamFuture;
1077 1078
1078 _HttpClientConnection(String this.key, 1079 _HttpClientConnection(String this.key,
1079 Socket this._socket, 1080 Socket this._socket,
1080 _HttpClient this._httpClient, 1081 _HttpClient this._httpClient,
1081 [this._proxyTunnel = false]) 1082 [this._proxyTunnel = false])
1082 : _httpParser = new _HttpParser.responseParser() { 1083 : _httpParser = new _HttpParser.responseParser() {
1083 _socket.pipe(_httpParser); 1084 _socket.pipe(_httpParser);
1084 1085
1085 // Set up handlers on the parser here, so we are sure to get 'onDone' from 1086 // Set up handlers on the parser here, so we are sure to get 'onDone' from
1086 // the parser. 1087 // the parser.
1087 _subscription = _httpParser.listen( 1088 _subscription = _httpParser.listen(
1088 (incoming) { 1089 (incoming) {
1089 // Only handle one incoming response at the time. Keep the 1090 // Only handle one incoming response at the time. Keep the
1090 // stream paused until the response have been processed. 1091 // stream paused until the response have been processed.
1091 _subscription.pause(); 1092 _subscription.pause();
1092 // We assume the response is not here, until we have send the request. 1093 // We assume the response is not here, until we have send the request.
Søren Gjesse 2013/05/17 07:09:28 Shouldn't this be an error instead of an assert? A
Anders Johnsen 2013/05/17 08:27:59 Done.
1093 assert(_nextResponseCompleter != null); 1094 assert(_nextResponseCompleter != null);
Søren Gjesse 2013/05/17 07:09:28 Do we still need this temp variable after the comp
Anders Johnsen 2013/05/17 08:27:59 Done.
1094 var completer = _nextResponseCompleter; 1095 var completer = _nextResponseCompleter;
1095 _nextResponseCompleter = null; 1096 _nextResponseCompleter = null;
1096 completer.complete(incoming); 1097 completer.complete(incoming);
1097 }, 1098 },
1098 onError: (error) { 1099 onError: (error) {
1099 if (_nextResponseCompleter != null) { 1100 if (_nextResponseCompleter != null) {
1100 _nextResponseCompleter.completeError(error); 1101 _nextResponseCompleter.completeError(error);
1101 _nextResponseCompleter = null; 1102 _nextResponseCompleter = null;
1102 } 1103 }
1103 }, 1104 },
1104 onDone: () { 1105 onDone: () {
1106 if (_nextResponseCompleter != null) {
1107 _nextResponseCompleter.completeError(new HttpException(
1108 "Connection closed before response was received"));
1109 _nextResponseCompleter = null;
1110 }
1105 close(); 1111 close();
1106 }); 1112 });
1107 } 1113 }
1108 1114
1109 _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) { 1115 _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) {
1116 if (closed) {
1117 throw new HttpException("Socket closed before request was sent");
1118 }
1110 // Start with pausing the parser. 1119 // Start with pausing the parser.
1111 _subscription.pause(); 1120 _subscription.pause();
1112 _ProxyCredentials proxyCreds; // Credentials used to authorize proxy. 1121 _ProxyCredentials proxyCreds; // Credentials used to authorize proxy.
1113 _SiteCredentials creds; // Credentials used to authorize this request. 1122 _SiteCredentials creds; // Credentials used to authorize this request.
1114 var outgoing = new _HttpOutgoing(_socket); 1123 var outgoing = new _HttpOutgoing(_socket);
1115 // Create new request object, wrapping the outgoing connection. 1124 // Create new request object, wrapping the outgoing connection.
1116 var request = new _HttpClientRequest(outgoing, 1125 var request = new _HttpClientRequest(outgoing,
1117 uri, 1126 uri,
1118 method, 1127 method,
1119 proxy, 1128 proxy,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 }); 1229 });
1221 return request; 1230 return request;
1222 } 1231 }
1223 1232
1224 Future<Socket> detachSocket() { 1233 Future<Socket> detachSocket() {
1225 return _streamFuture.then( 1234 return _streamFuture.then(
1226 (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming())); 1235 (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming()));
1227 } 1236 }
1228 1237
1229 void destroy() { 1238 void destroy() {
1239 closed = true;
1230 _httpClient._connectionClosed(this); 1240 _httpClient._connectionClosed(this);
1231 _socket.destroy(); 1241 _socket.destroy();
1232 } 1242 }
1233 1243
1234 void close() { 1244 void close() {
1245 closed = true;
1235 _httpClient._connectionClosed(this); 1246 _httpClient._connectionClosed(this);
1236 _streamFuture 1247 _streamFuture
1237 // TODO(ajohnsen): Add timeout. 1248 // TODO(ajohnsen): Add timeout.
1238 .then((_) => _socket.destroy()); 1249 .then((_) => _socket.destroy());
1239 } 1250 }
1240 1251
1241 Future<_HttpClientConnection> createProxyTunnel(host, port, proxy) { 1252 Future<_HttpClientConnection> createProxyTunnel(host, port, proxy) {
1242 _HttpClientRequest request = 1253 _HttpClientRequest request =
1243 send(new Uri.fromComponents(domain: host, port: port), 1254 send(new Uri.fromComponents(domain: host, port: port),
1244 port, 1255 port,
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 // TODO(sgjesse): Keep a map of these as normally only a few 1411 // TODO(sgjesse): Keep a map of these as normally only a few
1401 // configuration strings will be used. 1412 // configuration strings will be used.
1402 try { 1413 try {
1403 proxyConf = new _ProxyConfiguration(_findProxy(uri)); 1414 proxyConf = new _ProxyConfiguration(_findProxy(uri));
1404 } catch (error, stackTrace) { 1415 } catch (error, stackTrace) {
1405 return new Future.error(error, stackTrace); 1416 return new Future.error(error, stackTrace);
1406 } 1417 }
1407 } 1418 }
1408 return _getConnection(uri.domain, port, proxyConf, isSecure) 1419 return _getConnection(uri.domain, port, proxyConf, isSecure)
1409 .then((info) { 1420 .then((info) {
1410 return info.connection.send(uri, 1421 send(info) {
1411 port, 1422 return info.connection.send(uri,
1412 method.toUpperCase(), 1423 port,
1413 info.proxy); 1424 method.toUpperCase(),
1425 info.proxy);
1426 }
1427 // If the connection was closed before the request was sent, create
1428 // and use another connection.
1429 if (info.connection.closed) {
1430 return _getConnection(uri.domain, port, proxyConf, isSecure)
1431 .then(send);
1432 }
1433 return send(info);
1414 }); 1434 });
1415 } 1435 }
1416 1436
1417 Future<HttpClientRequest> _openUrlFromRequest(String method, 1437 Future<HttpClientRequest> _openUrlFromRequest(String method,
1418 Uri uri, 1438 Uri uri,
1419 _HttpClientRequest previous) { 1439 _HttpClientRequest previous) {
1420 // If the new URI is relative (to either '/' or some sub-path), 1440 // If the new URI is relative (to either '/' or some sub-path),
1421 // construct a full URI from the previous one. 1441 // construct a full URI from the previous one.
1422 // See http://tools.ietf.org/html/rfc3986#section-4.2 1442 // See http://tools.ietf.org/html/rfc3986#section-4.2
1423 replaceComponents({scheme, domain, port, path}) { 1443 replaceComponents({scheme, domain, port, path}) {
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 2255
2236 2256
2237 class _RedirectInfo implements RedirectInfo { 2257 class _RedirectInfo implements RedirectInfo {
2238 const _RedirectInfo(int this.statusCode, 2258 const _RedirectInfo(int this.statusCode,
2239 String this.method, 2259 String this.method,
2240 Uri this.location); 2260 Uri this.location);
2241 final int statusCode; 2261 final int statusCode;
2242 final String method; 2262 final String method;
2243 final Uri location; 2263 final Uri location;
2244 } 2264 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/io/http_parser.dart » ('j') | sdk/lib/io/http_parser.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698