| Index: lib/src/http.dart
|
| diff --git a/lib/src/http.dart b/lib/src/http.dart
|
| index 27e90a074e985a9940c54e3f01640df5c6e9278c..d3f57f1a7cc4f9998a45db683785f1020b2729c2 100644
|
| --- a/lib/src/http.dart
|
| +++ b/lib/src/http.dart
|
| @@ -13,17 +13,11 @@ import 'package:http/http.dart' as http;
|
| import 'package:http_throttle/http_throttle.dart';
|
| import 'package:stack_trace/stack_trace.dart';
|
|
|
| -import 'io.dart';
|
| import 'log.dart' as log;
|
| import 'oauth2.dart' as oauth2;
|
| import 'sdk.dart' as sdk;
|
| import 'utils.dart';
|
|
|
| -// TODO(nweiz): make this configurable
|
| -/// The amount of time in milliseconds to allow HTTP requests before assuming
|
| -/// they've failed.
|
| -final HTTP_TIMEOUT = 30 * 1000;
|
| -
|
| /// Headers and field names that should be censored in the log output.
|
| final _CENSORED_FIELDS = const ['refresh_token', 'authorization'];
|
|
|
| @@ -36,10 +30,6 @@ final PUB_API_HEADERS = const {'Accept': 'application/vnd.pub.v2+json'};
|
|
|
| /// An HTTP client that transforms 40* errors and socket exceptions into more
|
| /// user-friendly error messages.
|
| -///
|
| -/// This also adds a 30-second timeout to every request. This can be configured
|
| -/// on a per-request basis by setting the 'Pub-Request-Timeout' header to the
|
| -/// desired number of milliseconds, or to "None" to disable the timeout.
|
| class _PubHttpClient extends http.BaseClient {
|
| final _requestStopwatches = new Map<http.BaseRequest, Stopwatch>();
|
|
|
| @@ -48,82 +38,72 @@ class _PubHttpClient extends http.BaseClient {
|
| _PubHttpClient([http.Client inner])
|
| : this._inner = inner == null ? new http.Client() : inner;
|
|
|
| - Future<http.StreamedResponse> send(http.BaseRequest request) {
|
| + Future<http.StreamedResponse> send(http.BaseRequest request) async {
|
| _requestStopwatches[request] = new Stopwatch()..start();
|
| request.headers[HttpHeaders.USER_AGENT] = "Dart pub ${sdk.version}";
|
| _logRequest(request);
|
|
|
| - var timeoutLength = HTTP_TIMEOUT;
|
| - var timeoutString = request.headers.remove('Pub-Request-Timeout');
|
| - if (timeoutString == 'None') {
|
| - timeoutLength = null;
|
| - } else if (timeoutString != null) {
|
| - timeoutLength = int.parse(timeoutString);
|
| - }
|
| -
|
| - var future = _inner.send(request).then((streamedResponse) {
|
| - _logResponse(streamedResponse);
|
| -
|
| - var status = streamedResponse.statusCode;
|
| - // 401 responses should be handled by the OAuth2 client. It's very
|
| - // unlikely that they'll be returned by non-OAuth2 requests. We also want
|
| - // to pass along 400 responses from the token endpoint.
|
| - var tokenRequest = urisEqual(
|
| - streamedResponse.request.url, oauth2.tokenEndpoint);
|
| - if (status < 400 || status == 401 || (status == 400 && tokenRequest)) {
|
| - return streamedResponse;
|
| - }
|
| + var streamedResponse;
|
| + try {
|
| + streamedResponse = await _inner.send(request);
|
| + } on SocketException catch (error, stackTrace) {
|
| + // Work around issue 23008.
|
| + if (stackTrace == null) stackTrace = new Chain.current();
|
|
|
| - if (status == 406 &&
|
| - request.headers['Accept'] == PUB_API_HEADERS['Accept']) {
|
| - fail("Pub ${sdk.version} is incompatible with the current version of "
|
| - "${request.url.host}.\n"
|
| - "Upgrade pub to the latest version and try again.");
|
| + if (error.osError == null) rethrow;
|
| +
|
| + if (error.osError.errorCode == 8 ||
|
| + error.osError.errorCode == -2 ||
|
| + error.osError.errorCode == -5 ||
|
| + error.osError.errorCode == 11001 ||
|
| + error.osError.errorCode == 11004) {
|
| + fail('Could not resolve URL "${request.url.origin}".',
|
| + error, stackTrace);
|
| + } else if (error.osError.errorCode == -12276) {
|
| + fail('Unable to validate SSL certificate for '
|
| + '"${request.url.origin}".',
|
| + error, stackTrace);
|
| + } else {
|
| + rethrow;
|
| }
|
| + }
|
|
|
| - if (status == 500 &&
|
| - (request.url.host == "pub.dartlang.org" ||
|
| - request.url.host == "storage.googleapis.com")) {
|
| - var message = "HTTP error 500: Internal Server Error at "
|
| - "${request.url}.";
|
| + _logResponse(streamedResponse);
|
|
|
| - if (request.url.host == "pub.dartlang.org" ||
|
| - request.url.host == "storage.googleapis.com") {
|
| - message += "\nThis is likely a transient error. Please try again "
|
| - "later.";
|
| - }
|
| + var status = streamedResponse.statusCode;
|
| + // 401 responses should be handled by the OAuth2 client. It's very
|
| + // unlikely that they'll be returned by non-OAuth2 requests. We also want
|
| + // to pass along 400 responses from the token endpoint.
|
| + var tokenRequest = urisEqual(
|
| + streamedResponse.request.url, oauth2.tokenEndpoint);
|
| + if (status < 400 || status == 401 || (status == 400 && tokenRequest)) {
|
| + return streamedResponse;
|
| + }
|
|
|
| - fail(message);
|
| - }
|
| + if (status == 406 &&
|
| + request.headers['Accept'] == PUB_API_HEADERS['Accept']) {
|
| + fail("Pub ${sdk.version} is incompatible with the current version of "
|
| + "${request.url.host}.\n"
|
| + "Upgrade pub to the latest version and try again.");
|
| + }
|
|
|
| - return http.Response.fromStream(streamedResponse).then((response) {
|
| - throw new PubHttpException(response);
|
| - });
|
| - }).catchError((error, stackTrace) {
|
| - // Work around issue 23008.
|
| - if (stackTrace == null) stackTrace = new Chain.current();
|
| + if (status == 500 &&
|
| + (request.url.host == "pub.dartlang.org" ||
|
| + request.url.host == "storage.googleapis.com")) {
|
| + var message = "HTTP error 500: Internal Server Error at "
|
| + "${request.url}.";
|
|
|
| - if (error is SocketException &&
|
| - error.osError != null) {
|
| - if (error.osError.errorCode == 8 ||
|
| - error.osError.errorCode == -2 ||
|
| - error.osError.errorCode == -5 ||
|
| - error.osError.errorCode == 11001 ||
|
| - error.osError.errorCode == 11004) {
|
| - fail('Could not resolve URL "${request.url.origin}".',
|
| - error, stackTrace);
|
| - } else if (error.osError.errorCode == -12276) {
|
| - fail('Unable to validate SSL certificate for '
|
| - '"${request.url.origin}".',
|
| - error, stackTrace);
|
| - }
|
| + if (request.url.host == "pub.dartlang.org" ||
|
| + request.url.host == "storage.googleapis.com") {
|
| + message += "\nThis is likely a transient error. Please try again "
|
| + "later.";
|
| }
|
| - throw error;
|
| - });
|
|
|
| - if (timeoutLength == null) return future;
|
| - return timeout(future, timeoutLength, request.url,
|
| - 'fetching URL "${request.url}"');
|
| + fail(message);
|
| + }
|
| +
|
| + throw new PubHttpException(
|
| + await http.Response.fromStream(streamedResponse));
|
| }
|
|
|
| /// Logs the fact that [request] was sent, and information about it.
|
|
|