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

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

Issue 124753002: Code cleanup (mostly io lib and some http lib). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Merge to head. Created 6 years, 11 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
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 const int _HEADERS_BUFFER_SIZE = 8 * 1024; 7 const int _HEADERS_BUFFER_SIZE = 8 * 1024;
8 8
9 class _HttpIncoming extends Stream<List<int>> { 9 class _HttpIncoming extends Stream<List<int>> {
10 final int _transferLength; 10 final int _transferLength;
(...skipping 15 matching lines...) Expand all
26 Uri uri; 26 Uri uri;
27 27
28 bool hasSubscriber = false; 28 bool hasSubscriber = false;
29 29
30 // The transfer length if the length of the message body as it 30 // The transfer length if the length of the message body as it
31 // appears in the message (RFC 2616 section 4.4). This can be -1 if 31 // appears in the message (RFC 2616 section 4.4). This can be -1 if
32 // the length of the massage body is not known due to transfer 32 // the length of the massage body is not known due to transfer
33 // codings. 33 // codings.
34 int get transferLength => _transferLength; 34 int get transferLength => _transferLength;
35 35
36 _HttpIncoming(_HttpHeaders this.headers, 36 _HttpIncoming(this.headers, this._transferLength, this._stream);
37 int this._transferLength,
38 Stream<List<int>> this._stream) {
39 }
40 37
41 StreamSubscription<List<int>> listen(void onData(List<int> event), 38 StreamSubscription<List<int>> listen(void onData(List<int> event),
42 {Function onError, 39 {Function onError,
43 void onDone(), 40 void onDone(),
44 bool cancelOnError}) { 41 bool cancelOnError}) {
45 hasSubscriber = true; 42 hasSubscriber = true;
46 return _stream 43 return _stream
47 .handleError((error) { 44 .handleError((error) {
48 throw new HttpException(error.message, uri: uri); 45 throw new HttpException(error.message, uri: uri);
49 }) 46 })
(...skipping 10 matching lines...) Expand all
60 fullBodyRead = true; 57 fullBodyRead = true;
61 hasSubscriber = true; 58 hasSubscriber = true;
62 _dataCompleter.complete(closing); 59 _dataCompleter.complete(closing);
63 } 60 }
64 } 61 }
65 62
66 abstract class _HttpInboundMessage extends Stream<List<int>> { 63 abstract class _HttpInboundMessage extends Stream<List<int>> {
67 final _HttpIncoming _incoming; 64 final _HttpIncoming _incoming;
68 List<Cookie> _cookies; 65 List<Cookie> _cookies;
69 66
70 _HttpInboundMessage(_HttpIncoming this._incoming); 67 _HttpInboundMessage(this._incoming);
71 68
72 List<Cookie> get cookies { 69 List<Cookie> get cookies {
73 if (_cookies != null) return _cookies; 70 if (_cookies != null) return _cookies;
74 return _cookies = headers._parseCookies(); 71 return _cookies = headers._parseCookies();
75 } 72 }
76 73
77 _HttpHeaders get headers => _incoming.headers; 74 _HttpHeaders get headers => _incoming.headers;
78 String get protocolVersion => headers.protocolVersion; 75 String get protocolVersion => headers.protocolVersion;
79 int get contentLength => headers.contentLength; 76 int get contentLength => headers.contentLength;
80 bool get persistentConnection => headers.persistentConnection; 77 bool get persistentConnection => headers.persistentConnection;
81 } 78 }
82 79
83 80
84 class _HttpRequest extends _HttpInboundMessage implements HttpRequest { 81 class _HttpRequest extends _HttpInboundMessage implements HttpRequest {
85 final HttpResponse response; 82 final HttpResponse response;
86 83
87 final _HttpServer _httpServer; 84 final _HttpServer _httpServer;
88 85
89 final _HttpConnection _httpConnection; 86 final _HttpConnection _httpConnection;
90 87
91 _HttpSession _session; 88 _HttpSession _session;
92 89
93 _HttpRequest(_HttpResponse this.response, 90 _HttpRequest(this.response, _HttpIncoming _incoming, this._httpServer,
94 _HttpIncoming _incoming, 91 this._httpConnection) : super(_incoming) {
95 _HttpServer this._httpServer,
96 _HttpConnection this._httpConnection)
97 : super(_incoming) {
98 if (headers.protocolVersion == "1.1") { 92 if (headers.protocolVersion == "1.1") {
99 response.headers.chunkedTransferEncoding = true; 93 response.headers
100 response.headers.persistentConnection = headers.persistentConnection; 94 ..chunkedTransferEncoding = true
95 ..persistentConnection = headers.persistentConnection;
101 } 96 }
102 97
103 if (_httpServer._sessionManagerInstance != null) { 98 if (_httpServer._sessionManagerInstance != null) {
104 // Map to session if exists. 99 // Map to session if exists.
105 var sessionIds = cookies 100 var sessionIds = cookies
106 .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID) 101 .where((cookie) => cookie.name.toUpperCase() == _DART_SESSION_ID)
107 .map((cookie) => cookie.value); 102 .map((cookie) => cookie.value);
108 for (var sessionId in sessionIds) { 103 for (var sessionId in sessionIds) {
109 _session = _httpServer._sessionManager.getSession(sessionId); 104 _session = _httpServer._sessionManager.getSession(sessionId);
110 if (_session != null) { 105 if (_session != null) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 List<RedirectInfo> get redirects => _httpRequest._responseRedirects; 154 List<RedirectInfo> get redirects => _httpRequest._responseRedirects;
160 155
161 // The HttpClient this response belongs to. 156 // The HttpClient this response belongs to.
162 final _HttpClient _httpClient; 157 final _HttpClient _httpClient;
163 158
164 // The HttpClientRequest of this response. 159 // The HttpClientRequest of this response.
165 final _HttpClientRequest _httpRequest; 160 final _HttpClientRequest _httpRequest;
166 161
167 List<Cookie> _cookies; 162 List<Cookie> _cookies;
168 163
169 _HttpClientResponse(_HttpIncoming _incoming, 164 _HttpClientResponse(_HttpIncoming _incoming, this._httpRequest,
170 _HttpClientRequest this._httpRequest, 165 this._httpClient) : super(_incoming) {
171 _HttpClient this._httpClient)
172 : super(_incoming) {
173 // Set uri for potential exceptions. 166 // Set uri for potential exceptions.
174 _incoming.uri = _httpRequest.uri; 167 _incoming.uri = _httpRequest.uri;
175 } 168 }
176 169
177 int get statusCode => _incoming.statusCode; 170 int get statusCode => _incoming.statusCode;
178 String get reasonPhrase => _incoming.reasonPhrase; 171 String get reasonPhrase => _incoming.reasonPhrase;
179 172
180 X509Certificate get certificate { 173 X509Certificate get certificate =>
181 var socket = _httpRequest._httpClientConnection._socket; 174 _httpRequest._httpClientConnection._socket.peerCertificate;
182 return socket.peerCertificate;
183 }
184 175
185 List<Cookie> get cookies { 176 List<Cookie> get cookies {
186 if (_cookies != null) return _cookies; 177 if (_cookies != null) return _cookies;
187 _cookies = new List<Cookie>(); 178 _cookies = new List<Cookie>();
188 List<String> values = headers[HttpHeaders.SET_COOKIE]; 179 List<String> values = headers[HttpHeaders.SET_COOKIE];
189 if (values != null) { 180 if (values != null) {
190 values.forEach((value) { 181 values.forEach((value) {
191 _cookies.add(new Cookie.fromSetCookieValue(value)); 182 _cookies.add(new Cookie.fromSetCookieValue(value));
192 }); 183 });
193 } 184 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 if (followLoops != true) { 218 if (followLoops != true) {
228 for (var redirect in redirects) { 219 for (var redirect in redirects) {
229 if (redirect.location == url) { 220 if (redirect.location == url) {
230 return new Future.error( 221 return new Future.error(
231 new RedirectException("Redirect loop detected", redirects)); 222 new RedirectException("Redirect loop detected", redirects));
232 } 223 }
233 } 224 }
234 } 225 }
235 return _httpClient._openUrlFromRequest(method, url, _httpRequest) 226 return _httpClient._openUrlFromRequest(method, url, _httpRequest)
236 .then((request) { 227 .then((request) {
237 request._responseRedirects.addAll(this.redirects); 228 request._responseRedirects
238 request._responseRedirects.add(new _RedirectInfo(statusCode, 229 ..addAll(this.redirects)
239 method, 230 ..add(new _RedirectInfo(statusCode, method, url));
240 url));
241 return request.close(); 231 return request.close();
242 }); 232 });
243 } 233 }
244 234
245 StreamSubscription<List<int>> listen(void onData(List<int> event), 235 StreamSubscription<List<int>> listen(void onData(List<int> event),
246 {Function onError, 236 {Function onError,
247 void onDone(), 237 void onDone(),
248 bool cancelOnError}) { 238 bool cancelOnError}) {
249 var stream = _incoming; 239 var stream = _incoming;
250 if (headers.value(HttpHeaders.CONTENT_ENCODING) == "gzip") { 240 if (headers.value(HttpHeaders.CONTENT_ENCODING) == "gzip") {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 // Drain body and retry. 272 // Drain body and retry.
283 return drain().then((_) { 273 return drain().then((_) {
284 return _httpClient._openUrlFromRequest(_httpRequest.method, 274 return _httpClient._openUrlFromRequest(_httpRequest.method,
285 _httpRequest.uri, 275 _httpRequest.uri,
286 _httpRequest) 276 _httpRequest)
287 .then((request) => request.close()); 277 .then((request) => request.close());
288 }); 278 });
289 } 279 }
290 280
291 List<String> authChallenge() { 281 List<String> authChallenge() {
292 if (proxyAuth) { 282 return proxyAuth ? headers[HttpHeaders.PROXY_AUTHENTICATE]
293 return headers[HttpHeaders.PROXY_AUTHENTICATE]; 283 : headers[HttpHeaders.WWW_AUTHENTICATE];
294 } else {
295 return headers[HttpHeaders.WWW_AUTHENTICATE];
296 }
297 } 284 }
298 285
299 _Credentials findCredentials(_AuthenticationScheme scheme) { 286 _Credentials findCredentials(_AuthenticationScheme scheme) {
300 if (proxyAuth) { 287 return proxyAuth ? _httpClient._findProxyCredentials(_httpRequest._proxy, scheme)
301 return _httpClient._findProxyCredentials(_httpRequest._proxy, scheme); 288 : _httpClient._findCredentials(_httpRequest.uri, scheme);
302 } else {
303 return _httpClient._findCredentials(_httpRequest.uri, scheme);
304 }
305 } 289 }
306 290
307 void removeCredentials(_Credentials cr) { 291 void removeCredentials(_Credentials cr) {
308 if (proxyAuth) { 292 if (proxyAuth) {
309 _httpClient._removeProxyCredentials(cr); 293 _httpClient._removeProxyCredentials(cr);
310 } else { 294 } else {
311 _httpClient._removeCredentials(cr); 295 _httpClient._removeCredentials(cr);
312 } 296 }
313 } 297 }
314 298
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 } 336 }
353 337
354 // Digest authentication only supports the MD5 algorithm. 338 // Digest authentication only supports the MD5 algorithm.
355 if (cr.scheme == _AuthenticationScheme.DIGEST && 339 if (cr.scheme == _AuthenticationScheme.DIGEST &&
356 (header.parameters["algorithm"] == null || 340 (header.parameters["algorithm"] == null ||
357 header.parameters["algorithm"].toLowerCase() == "md5")) { 341 header.parameters["algorithm"].toLowerCase() == "md5")) {
358 if (cr.nonce == null || cr.nonce == header.parameters["nonce"]) { 342 if (cr.nonce == null || cr.nonce == header.parameters["nonce"]) {
359 // If the nonce is not set then this is the first authenticate 343 // If the nonce is not set then this is the first authenticate
360 // response for these credentials. Set up authentication state. 344 // response for these credentials. Set up authentication state.
361 if (cr.nonce == null) { 345 if (cr.nonce == null) {
362 cr.nonce = header.parameters["nonce"]; 346 cr..nonce = header.parameters["nonce"]
363 cr.algorithm = "MD5"; 347 ..algorithm = "MD5"
364 cr.qop = header.parameters["qop"]; 348 ..qop = header.parameters["qop"]
365 cr.nonceCount = 0; 349 ..nonceCount = 0;
366 } 350 }
367 // Credentials where found, prepare for retrying the request. 351 // Credentials where found, prepare for retrying the request.
368 return retry(); 352 return retry();
369 } else if (header.parameters["stale"] != null && 353 } else if (header.parameters["stale"] != null &&
370 header.parameters["stale"].toLowerCase() == "true") { 354 header.parameters["stale"].toLowerCase() == "true") {
371 // If stale is true retry with new nonce. 355 // If stale is true retry with new nonce.
372 cr.nonce = header.parameters["nonce"]; 356 cr.nonce = header.parameters["nonce"];
373 // Credentials where found, prepare for retrying the request. 357 // Credentials where found, prepare for retrying the request.
374 return retry(); 358 return retry();
375 } 359 }
(...skipping 28 matching lines...) Expand all
404 bool _asGZip = false; 388 bool _asGZip = false;
405 389
406 IOSink _headersSink; 390 IOSink _headersSink;
407 IOSink _dataSink; 391 IOSink _dataSink;
408 392
409 final _HttpOutgoing _outgoing; 393 final _HttpOutgoing _outgoing;
410 final Uri _uri; 394 final Uri _uri;
411 395
412 final _HttpHeaders headers; 396 final _HttpHeaders headers;
413 397
414 _HttpOutboundMessage(Uri this._uri, 398 _HttpOutboundMessage(this._uri,
415 String protocolVersion, 399 String protocolVersion,
416 _HttpOutgoing outgoing) 400 _HttpOutgoing outgoing)
417 : _outgoing = outgoing, 401 : _outgoing = outgoing,
418 _headersSink = new IOSink(outgoing, encoding: ASCII), 402 _headersSink = new IOSink(outgoing, encoding: ASCII),
419 headers = new _HttpHeaders(protocolVersion) { 403 headers = new _HttpHeaders(protocolVersion) {
420 _dataSink = new IOSink(new _HttpOutboundConsumer(this)); 404 _dataSink = new IOSink(new _HttpOutboundConsumer(this));
421 } 405 }
422 406
423 int get contentLength => headers.contentLength; 407 int get contentLength => headers.contentLength;
424 void set contentLength(int contentLength) { 408 void set contentLength(int contentLength) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 void writeCharCode(int charCode) { 446 void writeCharCode(int charCode) {
463 if (!_headersWritten) _dataSink.encoding = encoding; 447 if (!_headersWritten) _dataSink.encoding = encoding;
464 _dataSink.writeCharCode(charCode); 448 _dataSink.writeCharCode(charCode);
465 } 449 }
466 450
467 void add(List<int> data) { 451 void add(List<int> data) {
468 if (data.length == 0) return; 452 if (data.length == 0) return;
469 _dataSink.add(data); 453 _dataSink.add(data);
470 } 454 }
471 455
472 void addError(error, [StackTrace stackTrace]) { 456 void addError(error, [StackTrace stackTrace]) =>
473 _dataSink.addError(error, stackTrace); 457 _dataSink.addError(error, stackTrace);
474 }
475 458
476 Future<T> addStream(Stream<List<int>> stream) { 459 Future<T> addStream(Stream<List<int>> stream) => _dataSink.addStream(stream);
477 return _dataSink.addStream(stream);
478 }
479 460
480 Future flush() { 461 Future flush() => _dataSink.flush();
481 return _dataSink.flush();
482 }
483 462
484 Future close() { 463 Future close() => _dataSink.close();
485 return _dataSink.close();
486 }
487 464
488 Future<T> get done => _dataSink.done; 465 Future<T> get done => _dataSink.done;
489 466
490 Future _writeHeaders({bool drainRequest: true}) { 467 Future _writeHeaders({bool drainRequest: true}) {
491 void write() { 468 void write() {
492 try { 469 try {
493 _writeHeader(); 470 _writeHeader();
494 } catch (error) { 471 } catch (error) {
495 // Headers too large. 472 // Headers too large.
496 throw new HttpException( 473 throw new HttpException(
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 549
573 550
574 class _HttpOutboundConsumer implements StreamConsumer { 551 class _HttpOutboundConsumer implements StreamConsumer {
575 final _HttpOutboundMessage _outbound; 552 final _HttpOutboundMessage _outbound;
576 StreamController _controller; 553 StreamController _controller;
577 StreamSubscription _subscription; 554 StreamSubscription _subscription;
578 Completer _closeCompleter = new Completer(); 555 Completer _closeCompleter = new Completer();
579 Completer _completer; 556 Completer _completer;
580 bool _socketError = false; 557 bool _socketError = false;
581 558
582 _HttpOutboundConsumer(_HttpOutboundMessage this._outbound); 559 _HttpOutboundConsumer(this._outbound);
583 560
584 void _cancel() { 561 void _cancel() {
585 if (_subscription != null) { 562 if (_subscription != null) {
586 StreamSubscription subscription = _subscription; 563 StreamSubscription subscription = _subscription;
587 _subscription = null; 564 _subscription = null;
588 subscription.cancel(); 565 subscription.cancel();
589 } 566 }
590 } 567 }
591 568
592 bool _ignoreError(error) 569 bool _ignoreError(error)
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 buffer[offset++] = _CharCode.LF; 787 buffer[offset++] = _CharCode.LF;
811 788
812 var session = _httpRequest._session; 789 var session = _httpRequest._session;
813 if (session != null && !session._destroyed) { 790 if (session != null && !session._destroyed) {
814 // Mark as not new. 791 // Mark as not new.
815 session._isNew = false; 792 session._isNew = false;
816 // Make sure we only send the current session id. 793 // Make sure we only send the current session id.
817 bool found = false; 794 bool found = false;
818 for (int i = 0; i < cookies.length; i++) { 795 for (int i = 0; i < cookies.length; i++) {
819 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { 796 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
820 cookies[i].value = session.id; 797 cookies[i]
821 cookies[i].httpOnly = true; 798 ..value = session.id
822 cookies[i].path = "/"; 799 ..httpOnly = true
800 ..path = "/";
823 found = true; 801 found = true;
824 } 802 }
825 } 803 }
826 if (!found) { 804 if (!found) {
827 var cookie = new Cookie(_DART_SESSION_ID, session.id); 805 var cookie = new Cookie(_DART_SESSION_ID, session.id);
828 cookie.httpOnly = true; 806 cookies.add(cookie
829 cookie.path = "/"; 807 ..httpOnly = true
830 cookies.add(cookie); 808 ..path = "/");
831 } 809 }
832 } 810 }
833 // Add all the cookies set to the headers. 811 // Add all the cookies set to the headers.
834 if (_cookies != null) { 812 if (_cookies != null) {
835 _cookies.forEach((cookie) { 813 _cookies.forEach((cookie) {
836 headers.add(HttpHeaders.SET_COOKIE, cookie); 814 headers.add(HttpHeaders.SET_COOKIE, cookie);
837 }); 815 });
838 } 816 }
839 817
840 headers._finalize(); 818 headers._finalize();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 898
921 Future<HttpClientResponse> _response; 899 Future<HttpClientResponse> _response;
922 900
923 // TODO(ajohnsen): Get default value from client? 901 // TODO(ajohnsen): Get default value from client?
924 bool _followRedirects = true; 902 bool _followRedirects = true;
925 903
926 int _maxRedirects = 5; 904 int _maxRedirects = 5;
927 905
928 List<RedirectInfo> _responseRedirects = []; 906 List<RedirectInfo> _responseRedirects = [];
929 907
930 _HttpClientRequest(_HttpOutgoing outgoing, 908 _HttpClientRequest(_HttpOutgoing outgoing, Uri uri, this.method, this._proxy,
931 Uri uri, 909 this._httpClient, this._httpClientConnection)
932 String this.method,
933 _Proxy this._proxy,
934 _HttpClient this._httpClient,
935 _HttpClientConnection this._httpClientConnection)
936 : super(uri, "1.1", outgoing), 910 : super(uri, "1.1", outgoing),
937 uri = uri { 911 uri = uri {
938 // GET and HEAD have 'content-length: 0' by default. 912 // GET and HEAD have 'content-length: 0' by default.
939 if (method == "GET" || method == "HEAD") { 913 if (method == "GET" || method == "HEAD") {
940 contentLength = 0; 914 contentLength = 0;
941 } else { 915 } else {
942 headers.chunkedTransferEncoding = true; 916 headers.chunkedTransferEncoding = true;
943 } 917 }
944 } 918 }
945 919
(...skipping 19 matching lines...) Expand all
965 939
966 bool get followRedirects => _followRedirects; 940 bool get followRedirects => _followRedirects;
967 void set followRedirects(bool followRedirects) { 941 void set followRedirects(bool followRedirects) {
968 if (_headersWritten) throw new StateError("Request already sent"); 942 if (_headersWritten) throw new StateError("Request already sent");
969 _followRedirects = followRedirects; 943 _followRedirects = followRedirects;
970 } 944 }
971 945
972 HttpConnectionInfo get connectionInfo => _httpClientConnection.connectionInfo; 946 HttpConnectionInfo get connectionInfo => _httpClientConnection.connectionInfo;
973 947
974 void _onIncoming(_HttpIncoming incoming) { 948 void _onIncoming(_HttpIncoming incoming) {
975 var response = new _HttpClientResponse(incoming, 949 var response = new _HttpClientResponse(incoming, this, _httpClient);
976 this,
977 _httpClient);
978 Future<HttpClientResponse> future; 950 Future<HttpClientResponse> future;
979 if (followRedirects && response.isRedirect) { 951 if (followRedirects && response.isRedirect) {
980 if (response.redirects.length < maxRedirects) { 952 if (response.redirects.length < maxRedirects) {
981 // Redirect and drain response. 953 // Redirect and drain response.
982 future = response.drain() 954 future = response.drain().then((_) => response.redirect());
983 .then((_) => response.redirect());
984 } else { 955 } else {
985 // End with exception, too many redirects. 956 // End with exception, too many redirects.
986 future = response.drain() 957 future = response.drain()
987 .then((_) => new Future.error( 958 .then((_) => new Future.error(
988 new RedirectException("Redirect limit exceeded", 959 new RedirectException("Redirect limit exceeded",
989 response.redirects))); 960 response.redirects)));
990 } 961 }
991 } else if (response._shouldAuthenticateProxy) { 962 } else if (response._shouldAuthenticateProxy) {
992 future = response._authenticate(true); 963 future = response._authenticate(true);
993 } else if (response._shouldAuthenticate) { 964 } else if (response._shouldAuthenticate) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 // Write HTTP/1.1. 1030 // Write HTTP/1.1.
1060 write(_Const.HTTP11); 1031 write(_Const.HTTP11);
1061 buffer[offset++] = _CharCode.CR; 1032 buffer[offset++] = _CharCode.CR;
1062 buffer[offset++] = _CharCode.LF; 1033 buffer[offset++] = _CharCode.LF;
1063 1034
1064 // Add the cookies to the headers. 1035 // Add the cookies to the headers.
1065 if (!cookies.isEmpty) { 1036 if (!cookies.isEmpty) {
1066 StringBuffer sb = new StringBuffer(); 1037 StringBuffer sb = new StringBuffer();
1067 for (int i = 0; i < cookies.length; i++) { 1038 for (int i = 0; i < cookies.length; i++) {
1068 if (i > 0) sb.write("; "); 1039 if (i > 0) sb.write("; ");
1069 sb.write(cookies[i].name); 1040 sb..write(cookies[i].name)..write("=")..write(cookies[i].value);
1070 sb.write("=");
1071 sb.write(cookies[i].value);
1072 } 1041 }
1073 headers.add(HttpHeaders.COOKIE, sb.toString()); 1042 headers.add(HttpHeaders.COOKIE, sb.toString());
1074 } 1043 }
1075 1044
1076 headers._finalize(); 1045 headers._finalize();
1077 1046
1078 // Write headers. 1047 // Write headers.
1079 offset = headers._write(buffer, offset); 1048 offset = headers._write(buffer, offset);
1080 buffer[offset++] = _CharCode.CR; 1049 buffer[offset++] = _CharCode.CR;
1081 buffer[offset++] = _CharCode.LF; 1050 buffer[offset++] = _CharCode.LF;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 1125
1157 // Transformer that validates the content length. 1126 // Transformer that validates the content length.
1158 class _ContentLengthValidator 1127 class _ContentLengthValidator
1159 implements StreamTransformer<List<int>, List<int>>, EventSink<List<int>> { 1128 implements StreamTransformer<List<int>, List<int>>, EventSink<List<int>> {
1160 final int expectedContentLength; 1129 final int expectedContentLength;
1161 final Uri uri; 1130 final Uri uri;
1162 int _bytesWritten = 0; 1131 int _bytesWritten = 0;
1163 1132
1164 EventSink<List<int>> _outSink; 1133 EventSink<List<int>> _outSink;
1165 1134
1166 _ContentLengthValidator(int this.expectedContentLength, Uri this.uri); 1135 _ContentLengthValidator(this.expectedContentLength, this.uri);
1167 1136
1168 Stream<List<int>> bind(Stream<List<int>> stream) { 1137 Stream<List<int>> bind(Stream<List<int>> stream) {
1169 return new Stream.eventTransformed( 1138 return new Stream.eventTransformed(
1170 stream, 1139 stream,
1171 (EventSink sink) { 1140 (EventSink sink) {
1172 if (_outSink != null) { 1141 if (_outSink != null) {
1173 throw new StateError("Validator transformer already used"); 1142 throw new StateError("Validator transformer already used");
1174 } 1143 }
1175 _outSink = sink; 1144 _outSink = sink;
1176 return this; 1145 return this;
(...skipping 30 matching lines...) Expand all
1207 _outSink.close(); 1176 _outSink.close();
1208 } 1177 }
1209 } 1178 }
1210 1179
1211 1180
1212 // Extends StreamConsumer as this is an internal type, only used to pipe to. 1181 // Extends StreamConsumer as this is an internal type, only used to pipe to.
1213 class _HttpOutgoing implements StreamConsumer<List<int>> { 1182 class _HttpOutgoing implements StreamConsumer<List<int>> {
1214 final Completer _doneCompleter = new Completer(); 1183 final Completer _doneCompleter = new Completer();
1215 final Socket socket; 1184 final Socket socket;
1216 1185
1217 _HttpOutgoing(Socket this.socket); 1186 _HttpOutgoing(this.socket);
1218 1187
1219 Future addStream(Stream<List<int>> stream) { 1188 Future addStream(Stream<List<int>> stream) {
1220 return socket.addStream(stream) 1189 return socket.addStream(stream)
1221 .catchError((error) { 1190 .catchError((error) {
1222 _doneCompleter.completeError(error); 1191 _doneCompleter.completeError(error);
1223 throw error; 1192 throw error;
1224 }); 1193 });
1225 } 1194 }
1226 1195
1227 Future close() { 1196 Future close() {
(...skipping 13 matching lines...) Expand all
1241 final _HttpClient _httpClient; 1210 final _HttpClient _httpClient;
1242 bool _dispose = false; 1211 bool _dispose = false;
1243 Timer _idleTimer; 1212 Timer _idleTimer;
1244 bool closed = false; 1213 bool closed = false;
1245 Uri _currentUri; 1214 Uri _currentUri;
1246 final Uint8List _headersBuffer = new Uint8List(_HEADERS_BUFFER_SIZE); 1215 final Uint8List _headersBuffer = new Uint8List(_HEADERS_BUFFER_SIZE);
1247 1216
1248 Completer<_HttpIncoming> _nextResponseCompleter; 1217 Completer<_HttpIncoming> _nextResponseCompleter;
1249 Future _streamFuture; 1218 Future _streamFuture;
1250 1219
1251 _HttpClientConnection(String this.key, 1220 _HttpClientConnection(this.key, this._socket, this._httpClient,
1252 Socket this._socket,
1253 _HttpClient this._httpClient,
1254 [this._proxyTunnel = false]) 1221 [this._proxyTunnel = false])
1255 : _httpParser = new _HttpParser.responseParser() { 1222 : _httpParser = new _HttpParser.responseParser() {
1256 _socket.pipe(_httpParser); 1223 _socket.pipe(_httpParser);
1257 1224
1258 // Set up handlers on the parser here, so we are sure to get 'onDone' from 1225 // Set up handlers on the parser here, so we are sure to get 'onDone' from
1259 // the parser. 1226 // the parser.
1260 _subscription = _httpParser.listen( 1227 _subscription = _httpParser.listen(
1261 (incoming) { 1228 (incoming) {
1262 // Only handle one incoming response at the time. Keep the 1229 // Only handle one incoming response at the time. Keep the
1263 // stream paused until the response have been processed. 1230 // stream paused until the response have been processed.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 _ProxyCredentials proxyCreds; // Credentials used to authorize proxy. 1266 _ProxyCredentials proxyCreds; // Credentials used to authorize proxy.
1300 _SiteCredentials creds; // Credentials used to authorize this request. 1267 _SiteCredentials creds; // Credentials used to authorize this request.
1301 var outgoing = new _HttpOutgoing(_socket); 1268 var outgoing = new _HttpOutgoing(_socket);
1302 // Create new request object, wrapping the outgoing connection. 1269 // Create new request object, wrapping the outgoing connection.
1303 var request = new _HttpClientRequest(outgoing, 1270 var request = new _HttpClientRequest(outgoing,
1304 uri, 1271 uri,
1305 method, 1272 method,
1306 proxy, 1273 proxy,
1307 _httpClient, 1274 _httpClient,
1308 this); 1275 this);
1309 request.headers.host = uri.host; 1276 request.headers
1310 request.headers.port = port; 1277 ..host = uri.host
1311 request.headers._add(HttpHeaders.ACCEPT_ENCODING, "gzip"); 1278 ..port = port
1279 .._add(HttpHeaders.ACCEPT_ENCODING, "gzip");
1312 if (_httpClient.userAgent != null) { 1280 if (_httpClient.userAgent != null) {
1313 request.headers._add('user-agent', _httpClient.userAgent); 1281 request.headers._add('user-agent', _httpClient.userAgent);
1314 } 1282 }
1315 if (proxy.isAuthenticated) { 1283 if (proxy.isAuthenticated) {
1316 // If the proxy configuration contains user information use that 1284 // If the proxy configuration contains user information use that
1317 // for proxy basic authorization. 1285 // for proxy basic authorization.
1318 String auth = _CryptoUtils.bytesToBase64( 1286 String auth = _CryptoUtils.bytesToBase64(
1319 UTF8.encode("${proxy.username}:${proxy.password}")); 1287 UTF8.encode("${proxy.username}:${proxy.password}"));
1320 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth"); 1288 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth");
1321 } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) { 1289 } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 _idleTimer = new Timer( 1445 _idleTimer = new Timer(
1478 _httpClient.idleTimeout, 1446 _httpClient.idleTimeout,
1479 () { 1447 () {
1480 _idleTimer = null; 1448 _idleTimer = null;
1481 close(); 1449 close();
1482 }); 1450 });
1483 } 1451 }
1484 } 1452 }
1485 1453
1486 class _ConnnectionInfo { 1454 class _ConnnectionInfo {
1487 _ConnnectionInfo(_HttpClientConnection this.connection, _Proxy this.proxy);
1488 final _HttpClientConnection connection; 1455 final _HttpClientConnection connection;
1489 final _Proxy proxy; 1456 final _Proxy proxy;
1457
1458 _ConnnectionInfo(this.connection, this.proxy);
1490 } 1459 }
1491 1460
1492 1461
1493 class _HttpClient implements HttpClient { 1462 class _HttpClient implements HttpClient {
1494 // TODO(ajohnsen): Use eviction timeout. 1463 // TODO(ajohnsen): Use eviction timeout.
1495 bool _closing = false; 1464 bool _closing = false;
1496 1465
1497 final Map<String, Set<_HttpClientConnection>> _idleConnections 1466 final Map<String, Set<_HttpClientConnection>> _idleConnections
1498 = new HashMap<String, Set<_HttpClientConnection>>(); 1467 = new HashMap<String, Set<_HttpClientConnection>>();
1499 final Set<_HttpClientConnection> _activeConnections 1468 final Set<_HttpClientConnection> _activeConnections
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 } 1552 }
1584 assert(_activeConnections.isEmpty); 1553 assert(_activeConnections.isEmpty);
1585 _activeConnections.clear(); 1554 _activeConnections.clear();
1586 } 1555 }
1587 } 1556 }
1588 1557
1589 set authenticate(Future<bool> f(Uri url, String scheme, String realm)) { 1558 set authenticate(Future<bool> f(Uri url, String scheme, String realm)) {
1590 _authenticate = f; 1559 _authenticate = f;
1591 } 1560 }
1592 1561
1593 void addCredentials(Uri url, String realm, HttpClientCredentials cr) { 1562 void addCredentials(Uri url, String realm, HttpClientCredentials cr) =>
1594 _credentials.add(new _SiteCredentials(url, realm, cr)); 1563 _credentials.add(new _SiteCredentials(url, realm, cr));
1595 }
1596 1564
1597 set authenticateProxy( 1565 set authenticateProxy(
1598 Future<bool> f(String host, int port, String scheme, String realm)) { 1566 Future<bool> f(String host, int port, String scheme, String realm)) {
1599 _authenticateProxy = f; 1567 _authenticateProxy = f;
1600 } 1568 }
1601 1569
1602 void addProxyCredentials(String host, 1570 void addProxyCredentials(String host,
1603 int port, 1571 int port,
1604 String realm, 1572 String realm,
1605 HttpClientCredentials cr) { 1573 HttpClientCredentials cr) =>
1606 _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr)); 1574 _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr));
1607 }
1608 1575
1609 set findProxy(String f(Uri uri)) => _findProxy = f; 1576 set findProxy(String f(Uri uri)) => _findProxy = f;
1610 1577
1611 Future<HttpClientRequest> _openUrl(String method, Uri uri) { 1578 Future<HttpClientRequest> _openUrl(String method, Uri uri) {
1612 if (method == null) { 1579 if (method == null) {
1613 throw new ArgumentError(method); 1580 throw new ArgumentError(method);
1614 } 1581 }
1615 if (method != "CONNECT") { 1582 if (method != "CONNECT") {
1616 if (uri.host.isEmpty) { 1583 if (uri.host.isEmpty) {
1617 throw new ArgumentError("No host specified in URI $uri"); 1584 throw new ArgumentError("No host specified in URI $uri");
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 }); 1624 });
1658 } 1625 }
1659 1626
1660 Future<HttpClientRequest> _openUrlFromRequest(String method, 1627 Future<HttpClientRequest> _openUrlFromRequest(String method,
1661 Uri uri, 1628 Uri uri,
1662 _HttpClientRequest previous) { 1629 _HttpClientRequest previous) {
1663 // If the new URI is relative (to either '/' or some sub-path), 1630 // If the new URI is relative (to either '/' or some sub-path),
1664 // construct a full URI from the previous one. 1631 // construct a full URI from the previous one.
1665 Uri resolved = previous.uri.resolveUri(uri); 1632 Uri resolved = previous.uri.resolveUri(uri);
1666 return openUrl(method, resolved).then((_HttpClientRequest request) { 1633 return openUrl(method, resolved).then((_HttpClientRequest request) {
1667 // Only follow redirects if initial request did. 1634
1668 request.followRedirects = previous.followRedirects; 1635 request
1669 // Allow same number of redirects. 1636 // Only follow redirects if initial request did.
1670 request.maxRedirects = previous.maxRedirects; 1637 ..followRedirects = previous.followRedirects
1638 // Allow same number of redirects.
1639 ..maxRedirects = previous.maxRedirects;
1671 // Copy headers. 1640 // Copy headers.
1672 for (var header in previous.headers._headers.keys) { 1641 for (var header in previous.headers._headers.keys) {
1673 if (request.headers[header] == null) { 1642 if (request.headers[header] == null) {
1674 request.headers.set(header, previous.headers[header]); 1643 request.headers.set(header, previous.headers[header]);
1675 } 1644 }
1676 } 1645 }
1677 request.headers.chunkedTransferEncoding = false; 1646 return request
1678 request.contentLength = 0; 1647 ..headers.chunkedTransferEncoding = false
1679 return request; 1648 ..contentLength = 0;
1680 }); 1649 });
1681 } 1650 }
1682 1651
1683 // Return a live connection to the idle pool. 1652 // Return a live connection to the idle pool.
1684 void _returnConnection(_HttpClientConnection connection) { 1653 void _returnConnection(_HttpClientConnection connection) {
1685 _activeConnections.remove(connection); 1654 _activeConnections.remove(connection);
1686 if (_closing) { 1655 if (_closing) {
1687 connection.close(); 1656 connection.close();
1688 return; 1657 return;
1689 } 1658 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 1872
1904 final Socket _socket; 1873 final Socket _socket;
1905 final _HttpServer _httpServer; 1874 final _HttpServer _httpServer;
1906 final _HttpParser _httpParser; 1875 final _HttpParser _httpParser;
1907 StreamSubscription _subscription; 1876 StreamSubscription _subscription;
1908 Timer _idleTimer; 1877 Timer _idleTimer;
1909 final Uint8List _headersBuffer = new Uint8List(_HEADERS_BUFFER_SIZE); 1878 final Uint8List _headersBuffer = new Uint8List(_HEADERS_BUFFER_SIZE);
1910 1879
1911 Future _streamFuture; 1880 Future _streamFuture;
1912 1881
1913 _HttpConnection(Socket this._socket, _HttpServer this._httpServer) 1882 _HttpConnection(this._socket, this._httpServer)
1914 : _httpParser = new _HttpParser.requestParser() { 1883 : _httpParser = new _HttpParser.requestParser() {
1915 _startTimeout(); 1884 _startTimeout();
1916 _socket.pipe(_httpParser); 1885 _socket.pipe(_httpParser);
1917 _subscription = _httpParser.listen( 1886 _subscription = _httpParser.listen(
1918 (incoming) { 1887 (incoming) {
1919 _stopTimeout(); 1888 _stopTimeout();
1920 // If the incoming was closed, close the connection. 1889 // If the incoming was closed, close the connection.
1921 incoming.dataDone.then((closing) { 1890 incoming.dataDone.then((closing) {
1922 if (closing) destroy(); 1891 if (closing) destroy();
1923 }); 1892 });
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2036 .then((socket) { 2005 .then((socket) {
2037 return new _HttpServer._(socket, true); 2006 return new _HttpServer._(socket, true);
2038 }); 2007 });
2039 } 2008 }
2040 2009
2041 _HttpServer._(this._serverSocket, this._closeServer) { 2010 _HttpServer._(this._serverSocket, this._closeServer) {
2042 _controller = new StreamController<HttpRequest>(sync: true, 2011 _controller = new StreamController<HttpRequest>(sync: true,
2043 onCancel: close); 2012 onCancel: close);
2044 } 2013 }
2045 2014
2046 _HttpServer.listenOn(ServerSocket this._serverSocket) 2015 _HttpServer.listenOn(this._serverSocket) : _closeServer = false {
2047 : _closeServer = false {
2048 _controller = new StreamController<HttpRequest>(sync: true, 2016 _controller = new StreamController<HttpRequest>(sync: true,
2049 onCancel: close); 2017 onCancel: close);
2050 } 2018 }
2051 2019
2052 StreamSubscription<HttpRequest> listen(void onData(HttpRequest event), 2020 StreamSubscription<HttpRequest> listen(void onData(HttpRequest event),
2053 {Function onError, 2021 {Function onError,
2054 void onDone(), 2022 void onDone(),
2055 bool cancelOnError}) { 2023 bool cancelOnError}) {
2056 _serverSocket.listen( 2024 _serverSocket.listen(
2057 (Socket socket) { 2025 (Socket socket) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 2080
2113 InternetAddress get address { 2081 InternetAddress get address {
2114 if (closed) throw new HttpException("HttpServer is not bound to a socket"); 2082 if (closed) throw new HttpException("HttpServer is not bound to a socket");
2115 return _serverSocket.address; 2083 return _serverSocket.address;
2116 } 2084 }
2117 2085
2118 set sessionTimeout(int timeout) { 2086 set sessionTimeout(int timeout) {
2119 _sessionManager.sessionTimeout = timeout; 2087 _sessionManager.sessionTimeout = timeout;
2120 } 2088 }
2121 2089
2122 void _handleRequest(HttpRequest request) { 2090 void _handleRequest(HttpRequest request) => _controller.add(request);
2123 _controller.add(request);
2124 }
2125 2091
2126 void _handleError(error) { 2092 void _handleError(error) {
2127 if (!closed) _controller.addError(error); 2093 if (!closed) _controller.addError(error);
2128 } 2094 }
2129 2095
2130 void _connectionClosed(_HttpConnection connection) { 2096 void _connectionClosed(_HttpConnection connection) {
2131 _connections.remove(connection); 2097 _connections.remove(connection);
2132 _maybeCloseSessionManager(); 2098 _maybeCloseSessionManager();
2133 } 2099 }
2134 2100
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2234 } 2200 }
2235 2201
2236 const _ProxyConfiguration.direct() 2202 const _ProxyConfiguration.direct()
2237 : proxies = const [const _Proxy.direct()]; 2203 : proxies = const [const _Proxy.direct()];
2238 2204
2239 final List<_Proxy> proxies; 2205 final List<_Proxy> proxies;
2240 } 2206 }
2241 2207
2242 2208
2243 class _Proxy { 2209 class _Proxy {
2244 const _Proxy(
2245 this.host, this.port, this.username, this.password) : isDirect = false;
2246 const _Proxy.direct() : host = null, port = null,
2247 username = null, password = null, isDirect = true;
2248
2249 bool get isAuthenticated => username != null;
2250
2251 final String host; 2210 final String host;
2252 final int port; 2211 final int port;
2253 final String username; 2212 final String username;
2254 final String password; 2213 final String password;
2255 final bool isDirect; 2214 final bool isDirect;
2215
2216 const _Proxy(this.host, this.port, this.username, this.password)
2217 : isDirect = false;
2218 const _Proxy.direct() : host = null, port = null,
2219 username = null, password = null, isDirect = true;
2220
2221 bool get isAuthenticated => username != null;
2256 } 2222 }
2257 2223
2258 2224
2259 class _HttpConnectionInfo implements HttpConnectionInfo { 2225 class _HttpConnectionInfo implements HttpConnectionInfo {
2226 InternetAddress remoteAddress;
2227 int remotePort;
2228 int localPort;
2229
2260 static _HttpConnectionInfo create(Socket socket) { 2230 static _HttpConnectionInfo create(Socket socket) {
2261 if (socket == null) return null; 2231 if (socket == null) return null;
2262 try { 2232 try {
2263 _HttpConnectionInfo info = new _HttpConnectionInfo(); 2233 _HttpConnectionInfo info = new _HttpConnectionInfo();
2264 info.remoteAddress = socket.remoteAddress; 2234 return info
2265 info.remotePort = socket.remotePort; 2235 ..remoteAddress = socket.remoteAddress
2266 info.localPort = socket.port; 2236 ..remotePort = socket.remotePort
2267 return info; 2237 ..localPort = socket.port;
2268 } catch (e) { } 2238 } catch (e) { }
2269 return null; 2239 return null;
2270 } 2240 }
2271
2272 InternetAddress remoteAddress;
2273 int remotePort;
2274 int localPort;
2275 } 2241 }
2276 2242
2277 2243
2278 class _DetachedSocket extends Stream<List<int>> implements Socket { 2244 class _DetachedSocket extends Stream<List<int>> implements Socket {
2279 final Stream<List<int>> _incoming; 2245 final Stream<List<int>> _incoming;
2280 final Socket _socket; 2246 final Socket _socket;
2281 2247
2282 _DetachedSocket(this._socket, this._incoming); 2248 _DetachedSocket(this._socket, this._incoming);
2283 2249
2284 StreamSubscription<List<int>> listen(void onData(List<int> event), 2250 StreamSubscription<List<int>> listen(void onData(List<int> event),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2332 2298
2333 int get remotePort => _socket.remotePort; 2299 int get remotePort => _socket.remotePort;
2334 2300
2335 bool setOption(SocketOption option, bool enabled) { 2301 bool setOption(SocketOption option, bool enabled) {
2336 return _socket.setOption(option, enabled); 2302 return _socket.setOption(option, enabled);
2337 } 2303 }
2338 } 2304 }
2339 2305
2340 2306
2341 class _AuthenticationScheme { 2307 class _AuthenticationScheme {
2308 final int _scheme;
2309
2342 static const UNKNOWN = const _AuthenticationScheme(-1); 2310 static const UNKNOWN = const _AuthenticationScheme(-1);
2343 static const BASIC = const _AuthenticationScheme(0); 2311 static const BASIC = const _AuthenticationScheme(0);
2344 static const DIGEST = const _AuthenticationScheme(1); 2312 static const DIGEST = const _AuthenticationScheme(1);
2345 2313
2346 const _AuthenticationScheme(this._scheme); 2314 const _AuthenticationScheme(this._scheme);
2347 2315
2348 factory _AuthenticationScheme.fromString(String scheme) { 2316 factory _AuthenticationScheme.fromString(String scheme) {
2349 if (scheme.toLowerCase() == "basic") return BASIC; 2317 if (scheme.toLowerCase() == "basic") return BASIC;
2350 if (scheme.toLowerCase() == "digest") return DIGEST; 2318 if (scheme.toLowerCase() == "digest") return DIGEST;
2351 return UNKNOWN; 2319 return UNKNOWN;
2352 } 2320 }
2353 2321
2354 String toString() { 2322 String toString() {
2355 if (this == BASIC) return "Basic"; 2323 if (this == BASIC) return "Basic";
2356 if (this == DIGEST) return "Digest"; 2324 if (this == DIGEST) return "Digest";
2357 return "Unknown"; 2325 return "Unknown";
2358 } 2326 }
2359
2360 final int _scheme;
2361 } 2327 }
2362 2328
2363 2329
2364 abstract class _Credentials { 2330 abstract class _Credentials {
2365 _HttpClientCredentials credentials; 2331 _HttpClientCredentials credentials;
2366 String realm; 2332 String realm;
2367 bool used = false; 2333 bool used = false;
2368 2334
2369 // Digest specific fields. 2335 // Digest specific fields.
2370 String ha1; 2336 String ha1;
2371 String nonce; 2337 String nonce;
2372 String algorithm; 2338 String algorithm;
2373 String qop; 2339 String qop;
2374 int nonceCount; 2340 int nonceCount;
2375 2341
2376 _Credentials(this.credentials, this.realm) { 2342 _Credentials(this.credentials, this.realm) {
2377 if (credentials.scheme == _AuthenticationScheme.DIGEST) { 2343 if (credentials.scheme == _AuthenticationScheme.DIGEST) {
2378 // Calculate the H(A1) value once. There is no mentioning of 2344 // Calculate the H(A1) value once. There is no mentioning of
2379 // username/password encoding in RFC 2617. However there is an 2345 // username/password encoding in RFC 2617. However there is an
2380 // open draft for adding an additional accept-charset parameter to 2346 // open draft for adding an additional accept-charset parameter to
2381 // the WWW-Authenticate and Proxy-Authenticate headers, see 2347 // the WWW-Authenticate and Proxy-Authenticate headers, see
2382 // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For 2348 // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For
2383 // now always use UTF-8 encoding. 2349 // now always use UTF-8 encoding.
2384 _HttpClientDigestCredentials creds = credentials; 2350 _HttpClientDigestCredentials creds = credentials;
2385 var hasher = new _MD5(); 2351 var hasher = new _MD5()
2386 hasher.add(UTF8.encode(creds.username)); 2352 ..add(UTF8.encode(creds.username))
2387 hasher.add([_CharCode.COLON]); 2353 ..add([_CharCode.COLON])
2388 hasher.add(realm.codeUnits); 2354 ..add(realm.codeUnits)
2389 hasher.add([_CharCode.COLON]); 2355 ..add([_CharCode.COLON])
2390 hasher.add(UTF8.encode(creds.password)); 2356 ..add(UTF8.encode(creds.password));
2391 ha1 = _CryptoUtils.bytesToHex(hasher.close()); 2357 ha1 = _CryptoUtils.bytesToHex(hasher.close());
2392 } 2358 }
2393 } 2359 }
2394 2360
2395 _AuthenticationScheme get scheme => credentials.scheme; 2361 _AuthenticationScheme get scheme => credentials.scheme;
2396 2362
2397 void authorize(HttpClientRequest request); 2363 void authorize(HttpClientRequest request);
2398 } 2364 }
2399 2365
2400 class _SiteCredentials extends _Credentials { 2366 class _SiteCredentials extends _Credentials {
2401 Uri uri; 2367 Uri uri;
2402 2368
2403 _SiteCredentials(this.uri, realm, _HttpClientCredentials creds) 2369 _SiteCredentials(this.uri, realm, _HttpClientCredentials creds)
2404 : super(creds, realm); 2370 : super(creds, realm);
2405 2371
2406 bool applies(Uri uri, _AuthenticationScheme scheme) { 2372 bool applies(Uri uri, _AuthenticationScheme scheme) {
2407 if (scheme != null && credentials.scheme != scheme) return false; 2373 if (scheme != null && credentials.scheme != scheme) return false;
2408 if (uri.host != this.uri.host) return false; 2374 if (uri.host != this.uri.host) return false;
2409 int thisPort = 2375 int thisPort =
2410 this.uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : this.uri.port; 2376 this.uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : this.uri.port;
2411 int otherPort = uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : uri.port; 2377 int otherPort = uri.port == 0 ? HttpClient.DEFAULT_HTTP_PORT : uri.port;
2412 if (otherPort != thisPort) return false; 2378 if (otherPort != thisPort) return false;
2413 return uri.path.startsWith(this.uri.path); 2379 return uri.path.startsWith(this.uri.path);
2414 } 2380 }
(...skipping 12 matching lines...) Expand all
2427 2393
2428 2394
2429 class _ProxyCredentials extends _Credentials { 2395 class _ProxyCredentials extends _Credentials {
2430 String host; 2396 String host;
2431 int port; 2397 int port;
2432 2398
2433 _ProxyCredentials(this.host, 2399 _ProxyCredentials(this.host,
2434 this.port, 2400 this.port,
2435 realm, 2401 realm,
2436 _HttpClientCredentials creds) 2402 _HttpClientCredentials creds)
2437 : super(creds, realm); 2403 : super(creds, realm);
2438 2404
2439 bool applies(_Proxy proxy, _AuthenticationScheme scheme) { 2405 bool applies(_Proxy proxy, _AuthenticationScheme scheme) {
2440 if (scheme != null && credentials.scheme != scheme) return false; 2406 if (scheme != null && credentials.scheme != scheme) return false;
2441 return proxy.host == host && proxy.port == port; 2407 return proxy.host == host && proxy.port == port;
2442 } 2408 }
2443 2409
2444 void authorize(HttpClientRequest request) { 2410 void authorize(HttpClientRequest request) {
2445 // Digest credentials cannot be used without a nonce from the 2411 // Digest credentials cannot be used without a nonce from the
2446 // server. 2412 // server.
2447 if (credentials.scheme == _AuthenticationScheme.DIGEST && 2413 if (credentials.scheme == _AuthenticationScheme.DIGEST &&
2448 nonce == null) { 2414 nonce == null) {
2449 return; 2415 return;
2450 } 2416 }
2451 credentials.authorizeProxy(this, request); 2417 credentials.authorizeProxy(this, request);
2452 } 2418 }
2453 } 2419 }
2454 2420
2455 2421
2456 abstract class _HttpClientCredentials implements HttpClientCredentials { 2422 abstract class _HttpClientCredentials implements HttpClientCredentials {
2457 _AuthenticationScheme get scheme; 2423 _AuthenticationScheme get scheme;
2458 void authorize(_Credentials credentials, HttpClientRequest request); 2424 void authorize(_Credentials credentials, HttpClientRequest request);
2459 void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request); 2425 void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request);
2460 } 2426 }
2461 2427
2462 2428
2463 class _HttpClientBasicCredentials 2429 class _HttpClientBasicCredentials
2464 extends _HttpClientCredentials 2430 extends _HttpClientCredentials
2465 implements HttpClientBasicCredentials { 2431 implements HttpClientBasicCredentials {
2466 _HttpClientBasicCredentials(this.username, 2432 String username;
2467 this.password); 2433 String password;
2434
2435 _HttpClientBasicCredentials(this.username, this.password);
2468 2436
2469 _AuthenticationScheme get scheme => _AuthenticationScheme.BASIC; 2437 _AuthenticationScheme get scheme => _AuthenticationScheme.BASIC;
2470 2438
2471 String authorization() { 2439 String authorization() {
2472 // There is no mentioning of username/password encoding in RFC 2440 // There is no mentioning of username/password encoding in RFC
2473 // 2617. However there is an open draft for adding an additional 2441 // 2617. However there is an open draft for adding an additional
2474 // accept-charset parameter to the WWW-Authenticate and 2442 // accept-charset parameter to the WWW-Authenticate and
2475 // Proxy-Authenticate headers, see 2443 // Proxy-Authenticate headers, see
2476 // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For 2444 // http://tools.ietf.org/html/draft-reschke-basicauth-enc-06. For
2477 // now always use UTF-8 encoding. 2445 // now always use UTF-8 encoding.
2478 String auth = 2446 String auth =
2479 _CryptoUtils.bytesToBase64(UTF8.encode("$username:$password")); 2447 _CryptoUtils.bytesToBase64(UTF8.encode("$username:$password"));
2480 return "Basic $auth"; 2448 return "Basic $auth";
2481 } 2449 }
2482 2450
2483 void authorize(_Credentials _, HttpClientRequest request) { 2451 void authorize(_Credentials _, HttpClientRequest request) =>
2484 request.headers.set(HttpHeaders.AUTHORIZATION, authorization()); 2452 request.headers.set(HttpHeaders.AUTHORIZATION, authorization());
2485 }
2486 2453
2487 void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) { 2454 void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) =>
2488 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, authorization()); 2455 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, authorization());
2489 }
2490
2491 String username;
2492 String password;
2493 } 2456 }
2494 2457
2495 2458
2496 class _HttpClientDigestCredentials 2459 class _HttpClientDigestCredentials
2497 extends _HttpClientCredentials 2460 extends _HttpClientCredentials
2498 implements HttpClientDigestCredentials { 2461 implements HttpClientDigestCredentials {
2499 _HttpClientDigestCredentials(this.username, 2462 String username;
2500 this.password); 2463 String password;
2464
2465 _HttpClientDigestCredentials(this.username, this.password);
2501 2466
2502 _AuthenticationScheme get scheme => _AuthenticationScheme.DIGEST; 2467 _AuthenticationScheme get scheme => _AuthenticationScheme.DIGEST;
2503 2468
2504 String authorization(_Credentials credentials, _HttpClientRequest request) { 2469 String authorization(_Credentials credentials, _HttpClientRequest request) {
2505 String requestUri = request._requestUri(); 2470 String requestUri = request._requestUri();
2506 _MD5 hasher = new _MD5(); 2471 _MD5 hasher = new _MD5()
2507 hasher.add(request.method.codeUnits); 2472 ..add(request.method.codeUnits)
2508 hasher.add([_CharCode.COLON]); 2473 ..add([_CharCode.COLON])
2509 hasher.add(requestUri.codeUnits); 2474 ..add(requestUri.codeUnits);
2510 var ha2 = _CryptoUtils.bytesToHex(hasher.close()); 2475 var ha2 = _CryptoUtils.bytesToHex(hasher.close());
2511 2476
2512 String qop; 2477 String qop;
2513 String cnonce; 2478 String cnonce;
2514 String nc; 2479 String nc;
2515 var x; 2480 var x;
2516 hasher = new _MD5(); 2481 hasher = new _MD5()
2517 hasher.add(credentials.ha1.codeUnits); 2482 ..add(credentials.ha1.codeUnits)
2518 hasher.add([_CharCode.COLON]); 2483 ..add([_CharCode.COLON]);
2519 if (credentials.qop == "auth") { 2484 if (credentials.qop == "auth") {
2520 qop = credentials.qop; 2485 qop = credentials.qop;
2521 cnonce = _CryptoUtils.bytesToHex(_IOCrypto.getRandomBytes(4)); 2486 cnonce = _CryptoUtils.bytesToHex(_IOCrypto.getRandomBytes(4));
2522 ++credentials.nonceCount; 2487 ++credentials.nonceCount;
2523 nc = credentials.nonceCount.toRadixString(16); 2488 nc = credentials.nonceCount.toRadixString(16);
2524 nc = "00000000".substring(0, 8 - nc.length + 1) + nc; 2489 nc = "00000000".substring(0, 8 - nc.length + 1) + nc;
2525 hasher.add(credentials.nonce.codeUnits); 2490 hasher
2526 hasher.add([_CharCode.COLON]); 2491 ..add(credentials.nonce.codeUnits)
2527 hasher.add(nc.codeUnits); 2492 ..add([_CharCode.COLON])
2528 hasher.add([_CharCode.COLON]); 2493 ..add(nc.codeUnits)
2529 hasher.add(cnonce.codeUnits); 2494 ..add([_CharCode.COLON])
2530 hasher.add([_CharCode.COLON]); 2495 ..add(cnonce.codeUnits)
2531 hasher.add(credentials.qop.codeUnits); 2496 ..add([_CharCode.COLON])
2532 hasher.add([_CharCode.COLON]); 2497 ..add(credentials.qop.codeUnits)
2533 hasher.add(ha2.codeUnits); 2498 ..add([_CharCode.COLON])
2499 ..add(ha2.codeUnits);
2534 } else { 2500 } else {
2535 hasher.add(credentials.nonce.codeUnits); 2501 hasher
2536 hasher.add([_CharCode.COLON]); 2502 ..add(credentials.nonce.codeUnits)
2537 hasher.add(ha2.codeUnits); 2503 ..add([_CharCode.COLON])
2504 ..add(ha2.codeUnits);
2538 } 2505 }
2539 var response = _CryptoUtils.bytesToHex(hasher.close()); 2506 var response = _CryptoUtils.bytesToHex(hasher.close());
2540 2507
2541 StringBuffer buffer = new StringBuffer(); 2508 StringBuffer buffer = new StringBuffer()
2542 buffer.write('Digest '); 2509 ..write('Digest ')
2543 buffer.write('username="$username"'); 2510 ..write('username="$username"')
2544 buffer.write(', realm="${credentials.realm}"'); 2511 ..write(', realm="${credentials.realm}"')
2545 buffer.write(', nonce="${credentials.nonce}"'); 2512 ..write(', nonce="${credentials.nonce}"')
2546 buffer.write(', uri="$requestUri"'); 2513 ..write(', uri="$requestUri"')
2547 buffer.write(', algorithm="${credentials.algorithm}"'); 2514 ..write(', algorithm="${credentials.algorithm}"');
2548 if (qop == "auth") { 2515 if (qop == "auth") {
2549 buffer.write(', qop="$qop"'); 2516 buffer
2550 buffer.write(', cnonce="$cnonce"'); 2517 ..write(', qop="$qop"')
2551 buffer.write(', nc="$nc"'); 2518 ..write(', cnonce="$cnonce"')
2519 ..write(', nc="$nc"');
2552 } 2520 }
2553 buffer.write(', response="$response"'); 2521 buffer.write(', response="$response"');
2554 return buffer.toString(); 2522 return buffer.toString();
2555 } 2523 }
2556 2524
2557 void authorize(_Credentials credentials, HttpClientRequest request) { 2525 void authorize(_Credentials credentials, HttpClientRequest request) {
2558 request.headers.set(HttpHeaders.AUTHORIZATION, 2526 request.headers.set(HttpHeaders.AUTHORIZATION,
2559 authorization(credentials, request)); 2527 authorization(credentials, request));
2560 } 2528 }
2561 2529
2562 void authorizeProxy(_ProxyCredentials credentials, 2530 void authorizeProxy(_ProxyCredentials credentials,
2563 HttpClientRequest request) { 2531 HttpClientRequest request) {
2564 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, 2532 request.headers.set(HttpHeaders.PROXY_AUTHORIZATION,
2565 authorization(credentials, request)); 2533 authorization(credentials, request));
2566 } 2534 }
2567
2568 String username;
2569 String password;
2570 } 2535 }
2571 2536
2572 2537
2573 class _RedirectInfo implements RedirectInfo { 2538 class _RedirectInfo implements RedirectInfo {
2574 const _RedirectInfo(int this.statusCode,
2575 String this.method,
2576 Uri this.location);
2577 final int statusCode; 2539 final int statusCode;
2578 final String method; 2540 final String method;
2579 final Uri location; 2541 final Uri location;
2542 const _RedirectInfo(this.statusCode, this.method, this.location);
2580 } 2543 }
2581 2544
2582 String _getHttpVersion() { 2545 String _getHttpVersion() {
2583 var version = Platform.version; 2546 var version = Platform.version;
2584 // Only include major and minor version numbers. 2547 // Only include major and minor version numbers.
2585 int index = version.indexOf('.', version.indexOf('.') + 1); 2548 int index = version.indexOf('.', version.indexOf('.') + 1);
2586 version = version.substring(0, index); 2549 version = version.substring(0, index);
2587 return 'Dart/$version (dart:io)'; 2550 return 'Dart/$version (dart:io)';
2588 } 2551 }
2589
2590
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698