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

Side by Side Diff: sdk/lib/_internal/pub_generated/lib/src/http.dart

Issue 887223007: Revert "Use native async/await support in pub." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /// Helpers for dealing with HTTP. 5 /// Helpers for dealing with HTTP.
6 library pub.http; 6 library pub.http;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:io'; 10 import 'dart:io';
(...skipping 13 matching lines...) Expand all
24 final HTTP_TIMEOUT = 30 * 1000; 24 final HTTP_TIMEOUT = 30 * 1000;
25 25
26 /// Headers and field names that should be censored in the log output. 26 /// Headers and field names that should be censored in the log output.
27 final _CENSORED_FIELDS = const ['refresh_token', 'authorization']; 27 final _CENSORED_FIELDS = const ['refresh_token', 'authorization'];
28 28
29 /// Headers required for pub.dartlang.org API requests. 29 /// Headers required for pub.dartlang.org API requests.
30 /// 30 ///
31 /// The Accept header tells pub.dartlang.org which version of the API we're 31 /// The Accept header tells pub.dartlang.org which version of the API we're
32 /// expecting, so it can either serve that version or give us a 406 error if 32 /// expecting, so it can either serve that version or give us a 406 error if
33 /// it's not supported. 33 /// it's not supported.
34 final PUB_API_HEADERS = const {'Accept': 'application/vnd.pub.v2+json'}; 34 final PUB_API_HEADERS = const {
35 'Accept': 'application/vnd.pub.v2+json'
36 };
35 37
36 /// An HTTP client that transforms 40* errors and socket exceptions into more 38 /// An HTTP client that transforms 40* errors and socket exceptions into more
37 /// user-friendly error messages. 39 /// user-friendly error messages.
38 /// 40 ///
39 /// This also adds a 30-second timeout to every request. This can be configured 41 /// This also adds a 30-second timeout to every request. This can be configured
40 /// on a per-request basis by setting the 'Pub-Request-Timeout' header to the 42 /// on a per-request basis by setting the 'Pub-Request-Timeout' header to the
41 /// desired number of milliseconds, or to "None" to disable the timeout. 43 /// desired number of milliseconds, or to "None" to disable the timeout.
42 class _PubHttpClient extends http.BaseClient { 44 class _PubHttpClient extends http.BaseClient {
43 final _requestStopwatches = new Map<http.BaseRequest, Stopwatch>(); 45 final _requestStopwatches = new Map<http.BaseRequest, Stopwatch>();
44 46
(...skipping 23 matching lines...) Expand all
68 timeoutLength = int.parse(timeoutString); 70 timeoutLength = int.parse(timeoutString);
69 } 71 }
70 72
71 var future = _inner.send(request).then((streamedResponse) { 73 var future = _inner.send(request).then((streamedResponse) {
72 _logResponse(streamedResponse); 74 _logResponse(streamedResponse);
73 75
74 var status = streamedResponse.statusCode; 76 var status = streamedResponse.statusCode;
75 // 401 responses should be handled by the OAuth2 client. It's very 77 // 401 responses should be handled by the OAuth2 client. It's very
76 // unlikely that they'll be returned by non-OAuth2 requests. We also want 78 // unlikely that they'll be returned by non-OAuth2 requests. We also want
77 // to pass along 400 responses from the token endpoint. 79 // to pass along 400 responses from the token endpoint.
78 var tokenRequest = urisEqual( 80 var tokenRequest =
79 streamedResponse.request.url, oauth2.tokenEndpoint); 81 urisEqual(streamedResponse.request.url, oauth2.tokenEndpoint);
80 if (status < 400 || status == 401 || (status == 400 && tokenRequest)) { 82 if (status < 400 || status == 401 || (status == 400 && tokenRequest)) {
81 return streamedResponse; 83 return streamedResponse;
82 } 84 }
83 85
84 if (status == 406 && 86 if (status == 406 &&
85 request.headers['Accept'] == PUB_API_HEADERS['Accept']) { 87 request.headers['Accept'] == PUB_API_HEADERS['Accept']) {
86 fail("Pub ${sdk.version} is incompatible with the current version of " 88 fail(
87 "${request.url.host}.\n" 89 "Pub ${sdk.version} is incompatible with the current version of "
88 "Upgrade pub to the latest version and try again."); 90 "${request.url.host}.\n" "Upgrade pub to the latest version and try again.");
89 } 91 }
90 92
91 if (status == 500 && 93 if (status == 500 &&
92 (request.url.host == "pub.dartlang.org" || 94 (request.url.host == "pub.dartlang.org" ||
93 request.url.host == "storage.googleapis.com")) { 95 request.url.host == "storage.googleapis.com")) {
94 var message = "HTTP error 500: Internal Server Error at " 96 var message =
95 "${request.url}."; 97 "HTTP error 500: Internal Server Error at " "${request.url}.";
96 98
97 if (request.url.host == "pub.dartlang.org" || 99 if (request.url.host == "pub.dartlang.org" ||
98 request.url.host == "storage.googleapis.com") { 100 request.url.host == "storage.googleapis.com") {
99 message += "\nThis is likely a transient error. Please try again " 101 message +=
100 "later."; 102 "\nThis is likely a transient error. Please try again " "later.";
101 } 103 }
102 104
103 fail(message); 105 fail(message);
104 } 106 }
105 107
106 return http.Response.fromStream(streamedResponse).then((response) { 108 return http.Response.fromStream(streamedResponse).then((response) {
107 throw new PubHttpException(response); 109 throw new PubHttpException(response);
108 }); 110 });
109 }).catchError((error, stackTrace) { 111 }).catchError((error, stackTrace) {
110 if (error is SocketException && 112 if (error is SocketException && error.osError != null) {
111 error.osError != null) {
112 if (error.osError.errorCode == 8 || 113 if (error.osError.errorCode == 8 ||
113 error.osError.errorCode == -2 || 114 error.osError.errorCode == -2 ||
114 error.osError.errorCode == -5 || 115 error.osError.errorCode == -5 ||
115 error.osError.errorCode == 11001 || 116 error.osError.errorCode == 11001 ||
116 error.osError.errorCode == 11004) { 117 error.osError.errorCode == 11004) {
117 fail('Could not resolve URL "${request.url.origin}".', 118 fail(
118 error, stackTrace); 119 'Could not resolve URL "${request.url.origin}".',
120 error,
121 stackTrace);
119 } else if (error.osError.errorCode == -12276) { 122 } else if (error.osError.errorCode == -12276) {
120 fail('Unable to validate SSL certificate for ' 123 fail(
121 '"${request.url.origin}".', 124 'Unable to validate SSL certificate for ' '"${request.url.origin}" .',
122 error, stackTrace); 125 error,
126 stackTrace);
123 } 127 }
124 } 128 }
125 throw error; 129 throw error;
126 }); 130 });
127 131
128 if (timeoutLength == null) return future; 132 if (timeoutLength == null) return future;
129 return timeout(future, timeoutLength, request.url, 133 return timeout(
134 future,
135 timeoutLength,
136 request.url,
130 'fetching URL "${request.url}"'); 137 'fetching URL "${request.url}"');
131 } 138 }
132 139
133 /// Logs the fact that [request] was sent, and information about it. 140 /// Logs the fact that [request] was sent, and information about it.
134 void _logRequest(http.BaseRequest request) { 141 void _logRequest(http.BaseRequest request) {
135 var requestLog = new StringBuffer(); 142 var requestLog = new StringBuffer();
136 requestLog.writeln("HTTP ${request.method} ${request.url}"); 143 requestLog.writeln("HTTP ${request.method} ${request.url}");
137 request.headers.forEach((name, value) => 144 request.headers.forEach(
138 requestLog.writeln(_logField(name, value))); 145 (name, value) => requestLog.writeln(_logField(name, value)));
139 146
140 if (request.method == 'POST') { 147 if (request.method == 'POST') {
141 var contentTypeString = request.headers[HttpHeaders.CONTENT_TYPE]; 148 var contentTypeString = request.headers[HttpHeaders.CONTENT_TYPE];
142 if (contentTypeString == null) contentTypeString = ''; 149 if (contentTypeString == null) contentTypeString = '';
143 var contentType = ContentType.parse(contentTypeString); 150 var contentType = ContentType.parse(contentTypeString);
144 if (request is http.MultipartRequest) { 151 if (request is http.MultipartRequest) {
145 requestLog.writeln(); 152 requestLog.writeln();
146 requestLog.writeln("Body fields:"); 153 requestLog.writeln("Body fields:");
147 request.fields.forEach((name, value) => 154 request.fields.forEach(
148 requestLog.writeln(_logField(name, value))); 155 (name, value) => requestLog.writeln(_logField(name, value)));
149 156
150 // TODO(nweiz): make MultipartRequest.files readable, and log them? 157 // TODO(nweiz): make MultipartRequest.files readable, and log them?
151 } else if (request is http.Request) { 158 } else if (request is http.Request) {
152 if (contentType.value == 'application/x-www-form-urlencoded') { 159 if (contentType.value == 'application/x-www-form-urlencoded') {
153 requestLog.writeln(); 160 requestLog.writeln();
154 requestLog.writeln("Body fields:"); 161 requestLog.writeln("Body fields:");
155 request.bodyFields.forEach((name, value) => 162 request.bodyFields.forEach(
156 requestLog.writeln(_logField(name, value))); 163 (name, value) => requestLog.writeln(_logField(name, value)));
157 } else if (contentType.value == 'text/plain' || 164 } else if (contentType.value == 'text/plain' ||
158 contentType.value == 'application/json') { 165 contentType.value == 'application/json') {
159 requestLog.write(request.body); 166 requestLog.write(request.body);
160 } 167 }
161 } 168 }
162 } 169 }
163 170
164 log.fine(requestLog.toString().trim()); 171 log.fine(requestLog.toString().trim());
165 } 172 }
166 173
167 /// Logs the fact that [response] was received, and information about it. 174 /// Logs the fact that [response] was received, and information about it.
168 void _logResponse(http.StreamedResponse response) { 175 void _logResponse(http.StreamedResponse response) {
169 // TODO(nweiz): Fork the response stream and log the response body. Be 176 // TODO(nweiz): Fork the response stream and log the response body. Be
170 // careful not to log OAuth2 private data, though. 177 // careful not to log OAuth2 private data, though.
171 178
172 var responseLog = new StringBuffer(); 179 var responseLog = new StringBuffer();
173 var request = response.request; 180 var request = response.request;
174 var stopwatch = _requestStopwatches.remove(request)..stop(); 181 var stopwatch = _requestStopwatches.remove(request)..stop();
175 responseLog.writeln("HTTP response ${response.statusCode} " 182 responseLog.writeln(
176 "${response.reasonPhrase} for ${request.method} ${request.url}"); 183 "HTTP response ${response.statusCode} "
184 "${response.reasonPhrase} for ${request.method} ${request.url}");
177 responseLog.writeln("took ${stopwatch.elapsed}"); 185 responseLog.writeln("took ${stopwatch.elapsed}");
178 response.headers.forEach((name, value) => 186 response.headers.forEach(
179 responseLog.writeln(_logField(name, value))); 187 (name, value) => responseLog.writeln(_logField(name, value)));
180 188
181 log.fine(responseLog.toString().trim()); 189 log.fine(responseLog.toString().trim());
182 } 190 }
183 191
184 /// Returns a log-formatted string for the HTTP field or header with the given 192 /// Returns a log-formatted string for the HTTP field or header with the given
185 /// [name] and [value]. 193 /// [name] and [value].
186 String _logField(String name, String value) { 194 String _logField(String name, String value) {
187 if (_CENSORED_FIELDS.contains(name.toLowerCase())) { 195 if (_CENSORED_FIELDS.contains(name.toLowerCase())) {
188 return "$name: <censored>"; 196 return "$name: <censored>";
189 } else { 197 } else {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 value = JSON.decode(response.body); 250 value = JSON.decode(response.body);
243 } on FormatException catch (e) { 251 } on FormatException catch (e) {
244 invalidServerResponse(response); 252 invalidServerResponse(response);
245 } 253 }
246 if (value is! Map) invalidServerResponse(response); 254 if (value is! Map) invalidServerResponse(response);
247 return value; 255 return value;
248 } 256 }
249 257
250 /// Throws an error describing an invalid response from the server. 258 /// Throws an error describing an invalid response from the server.
251 void invalidServerResponse(http.Response response) => 259 void invalidServerResponse(http.Response response) =>
252 fail('Invalid server response:\n${response.body}'); 260 fail('Invalid server response:\n${response.body}');
253 261
254 /// Exception thrown when an HTTP operation fails. 262 /// Exception thrown when an HTTP operation fails.
255 class PubHttpException implements Exception { 263 class PubHttpException implements Exception {
256 final http.Response response; 264 final http.Response response;
257 265
258 const PubHttpException(this.response); 266 const PubHttpException(this.response);
259 267
260 String toString() => 'HTTP error ${response.statusCode}: ' 268 String toString() =>
261 '${response.reasonPhrase}'; 269 'HTTP error ${response.statusCode}: ' '${response.reasonPhrase}';
262 } 270 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/pub_generated/lib/src/global_packages.dart ('k') | sdk/lib/_internal/pub_generated/lib/src/io.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698