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

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

Issue 14595006: Extend HTTP digest support with server changing nonce (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fix 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
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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 // this authenticate response. 304 // this authenticate response.
305 if (cr.scheme == _AuthenticationScheme.BASIC && !cr.used) { 305 if (cr.scheme == _AuthenticationScheme.BASIC && !cr.used) {
306 // Credentials where found, prepare for retrying the request. 306 // Credentials where found, prepare for retrying the request.
307 return retryWithCredentials(cr); 307 return retryWithCredentials(cr);
308 } 308 }
309 309
310 // Digest authentication only supports the MD5 algorithm. 310 // Digest authentication only supports the MD5 algorithm.
311 if (cr.scheme == _AuthenticationScheme.DIGEST && 311 if (cr.scheme == _AuthenticationScheme.DIGEST &&
312 (header.parameters["algorithm"] == null || 312 (header.parameters["algorithm"] == null ||
313 header.parameters["algorithm"].toLowerCase() == "md5")) { 313 header.parameters["algorithm"].toLowerCase() == "md5")) {
314 // If the nonce is not set then this is the first authenticate 314 if (cr.nonce == null || cr.nonce == header.parameters["nonce"]) {
315 // response for these credentials. 315 // If the nonce is not set then this is the first authenticate
316 // TODO(sgjesse): Check for changed nonce. 316 // response for these credentials. Set up authentication state.
317 if (cr.nonce == null) { 317 if (cr.nonce == null) {
318 // Set up authentication state. 318 cr.nonce = header.parameters["nonce"];
319 cr.algorithm = "MD5";
320 cr.qop = header.parameters["qop"];
321 cr.nonceCount = 0;
322 }
323 // Credentials where found, prepare for retrying the request.
324 return retryWithCredentials(cr);
325 } else if (header.parameters["stale"] != null &&
326 header.parameters["stale"].toLowerCase() == "true") {
327 // If stale is true retry with new nonce.
319 cr.nonce = header.parameters["nonce"]; 328 cr.nonce = header.parameters["nonce"];
320 cr.algorithm = "MD5"; 329 // Credentials where found, prepare for retrying the request.
321 cr.qop = header.parameters["qop"]; 330 return retryWithCredentials(cr);
322 cr.nonceCount = 0;
323 } 331 }
324 // Credentials where found, prepare for retrying the request.
325 return retryWithCredentials(cr);
326 } 332 }
327 } 333 }
328 334
329 // Ask for more credentials if none found or the one found has 335 // Ask for more credentials if none found or the one found has
330 // already been used. If it has already been used it must now be 336 // already been used. If it has already been used it must now be
331 // invalid and is removed. 337 // invalid and is removed.
332 if (cr != null) { 338 if (cr != null) {
333 _httpClient._removeCredentials(cr); 339 _httpClient._removeCredentials(cr);
334 cr = null; 340 cr = null;
335 } 341 }
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 } 1113 }
1108 }, 1114 },
1109 onDone: () { 1115 onDone: () {
1110 close(); 1116 close();
1111 }); 1117 });
1112 } 1118 }
1113 1119
1114 _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) { 1120 _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) {
1115 // Start with pausing the parser. 1121 // Start with pausing the parser.
1116 _subscription.pause(); 1122 _subscription.pause();
1123 _Credentials cr; // Credentials used to authorize this request.
1117 var outgoing = new _HttpOutgoing(_socket); 1124 var outgoing = new _HttpOutgoing(_socket);
1118 // Create new request object, wrapping the outgoing connection. 1125 // Create new request object, wrapping the outgoing connection.
1119 var request = new _HttpClientRequest(outgoing, 1126 var request = new _HttpClientRequest(outgoing,
1120 uri, 1127 uri,
1121 method, 1128 method,
1122 proxy, 1129 proxy,
1123 _httpClient, 1130 _httpClient,
1124 this); 1131 this);
1125 request.headers.host = uri.domain; 1132 request.headers.host = uri.domain;
1126 request.headers.port = port; 1133 request.headers.port = port;
(...skipping 11 matching lines...) Expand all
1138 } 1145 }
1139 } 1146 }
1140 if (uri.userInfo != null && !uri.userInfo.isEmpty) { 1147 if (uri.userInfo != null && !uri.userInfo.isEmpty) {
1141 // If the URL contains user information use that for basic 1148 // If the URL contains user information use that for basic
1142 // authorization. 1149 // authorization.
1143 String auth = 1150 String auth =
1144 CryptoUtils.bytesToBase64(_encodeString(uri.userInfo)); 1151 CryptoUtils.bytesToBase64(_encodeString(uri.userInfo));
1145 request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth"); 1152 request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
1146 } else { 1153 } else {
1147 // Look for credentials. 1154 // Look for credentials.
1148 _Credentials cr = _httpClient._findCredentials(uri); 1155 cr = _httpClient._findCredentials(uri);
1149 if (cr != null) { 1156 if (cr != null) {
1150 cr.authorize(request); 1157 cr.authorize(request);
1151 } 1158 }
1152 } 1159 }
1153 // Start sending the request (lazy, delayed until the user provides 1160 // Start sending the request (lazy, delayed until the user provides
1154 // data). 1161 // data).
1155 _httpParser.responseToMethod = method; 1162 _httpParser.responseToMethod = method;
1156 _streamFuture = outgoing.done 1163 _streamFuture = outgoing.done
1157 .then((s) { 1164 .then((s) {
1158 // Request sent, set up response completer. 1165 // Request sent, set up response completer.
1159 _nextResponseCompleter = new Completer(); 1166 _nextResponseCompleter = new Completer();
1160 1167
1161 // Listen for response. 1168 // Listen for response.
1162 _nextResponseCompleter.future 1169 _nextResponseCompleter.future
1163 .then((incoming) { 1170 .then((incoming) {
1164 incoming.dataDone.then((_) { 1171 incoming.dataDone.then((_) {
1165 if (!_dispose && 1172 if (!_dispose &&
1166 incoming.headers.persistentConnection && 1173 incoming.headers.persistentConnection &&
1167 request.persistentConnection) { 1174 request.persistentConnection) {
1168 // Return connection, now we are done. 1175 // Return connection, now we are done.
1169 _httpClient._returnConnection(this); 1176 _httpClient._returnConnection(this);
1170 _subscription.resume(); 1177 _subscription.resume();
1171 } else { 1178 } else {
1172 destroy(); 1179 destroy();
1173 } 1180 }
1174 }); 1181 });
1182 // For digest authentication check if the server
1183 // requests the client to start using a new nonce.
1184 if (cr != null && cr.scheme == _AuthenticationScheme.DIGEST) {
1185 var authInfo = incoming.headers["authentication-info"];
1186 if (authInfo != null && authInfo.length == 1) {
1187 var header = new _HeaderValue.fromString(
1188 authInfo[0], parameterSeparator: ',');
1189 var nextnonce = header.parameters["nextnonce"];
1190 if (nextnonce != null) cr.nonce = nextnonce;
1191 }
1192 }
1175 request._onIncoming(incoming); 1193 request._onIncoming(incoming);
1176 }) 1194 })
1177 // If we see a state error, we failed to get the 'first' 1195 // If we see a state error, we failed to get the 'first'
1178 // element. 1196 // element.
1179 // Transform the error to a HttpParserException, for 1197 // Transform the error to a HttpParserException, for
1180 // consistency. 1198 // consistency.
1181 .catchError((error) { 1199 .catchError((error) {
1182 throw new HttpParserException( 1200 throw new HttpParserException(
1183 "Connection closed before data was received"); 1201 "Connection closed before data was received");
1184 }, test: (error) => error is StateError) 1202 }, test: (error) => error is StateError)
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 2177
2160 2178
2161 class _RedirectInfo implements RedirectInfo { 2179 class _RedirectInfo implements RedirectInfo {
2162 const _RedirectInfo(int this.statusCode, 2180 const _RedirectInfo(int this.statusCode,
2163 String this.method, 2181 String this.method,
2164 Uri this.location); 2182 Uri this.location);
2165 final int statusCode; 2183 final int statusCode;
2166 final String method; 2184 final String method;
2167 final Uri location; 2185 final Uri location;
2168 } 2186 }
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/io/http_auth_digest_test.dart » ('j') | tests/standalone/io/http_auth_digest_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698