Index: utils/pub/io.dart |
diff --git a/utils/pub/io.dart b/utils/pub/io.dart |
index e3fc8e0202c4b84edcfc59abe54584009037bf9d..a4d554c39b71097b1c23d06c5c2a4ce894d2be68 100644 |
--- a/utils/pub/io.dart |
+++ b/utils/pub/io.dart |
@@ -128,7 +128,7 @@ Future<File> writeTextFile(file, String contents) { |
* Asynchronously deletes [file], which can be a [String] or a [File]. Returns a |
* [Future] that completes when the deletion is done. |
*/ |
-Future<Directory> deleteFile(file) { |
+Future<File> deleteFile(file) { |
return new File(_getPath(file)).delete(); |
} |
@@ -309,6 +309,56 @@ InputStream httpGet(uri) { |
} |
/** |
+ * Opens an input stream for a HTTP GET request to [uri], which may be a |
+ * [String] or [Uri]. Completes with the result of the request as a String. |
+ */ |
+Future<String> httpGetString(uri) { |
nweiz
2012/09/04 19:29:25
Why is this method different than httpGet? Is it j
Bob Nystrom
2012/09/04 22:14:46
Yup.
|
+ uri = _getUri(uri); |
+ |
+ var completer = new Completer<String>(); |
+ var client = new HttpClient(); |
+ var connection = client.getUrl(uri); |
+ |
+ connection.onError = (e) { |
+ // Show a friendly error if the URL couldn't be resolved. |
+ if ((e is SocketIOException) && (e.osError.errorCode == 8)) { |
nweiz
2012/09/04 19:29:25
I don't like these unnecessary parens. I don't thi
Bob Nystrom
2012/09/04 22:14:46
Done.
|
+ e = 'Could not resolve URL "${uri.origin}".'; |
+ } |
+ |
+ completer.completeException(e); |
+ }; |
nweiz
2012/09/04 19:29:25
Shouldn't you call client.shutdown here, too?
Bob Nystrom
2012/09/04 22:14:46
Done.
|
+ |
+ connection.onResponse = (response) { |
+ if (response.statusCode >= 400) { |
+ client.shutdown(); |
+ completer.completeException( |
+ new HttpException(response.statusCode, response.reasonPhrase)); |
+ return; |
+ } |
+ |
+ var resultStream = new ListInputStream(); |
+ var buffer = <int>[]; |
+ |
+ response.inputStream.onClosed = () { |
+ // Make sure we aren't closing in response to an error in which case |
+ // we will have already completed with that exception. |
nweiz
2012/09/04 19:29:25
onClosed and onError should be mutually exclusive.
Bob Nystrom
2012/09/04 22:14:46
They didn't seem to be. Without this check, I get
nweiz
2012/09/04 22:38:18
I believe that's a bug according to https://docs.g
Bob Nystrom
2012/09/04 23:01:20
The pub tests seem to pass without the check, so I
|
+ if (!completer.future.isComplete) { |
+ client.shutdown(); |
+ completer.complete(new String.fromCharCodes(buffer)); |
+ } |
+ }; |
+ |
+ response.inputStream.onData = () { |
+ buffer.addAll(response.inputStream.read()); |
+ }; |
+ |
+ response.inputStream.onError = (e) => completer.completeException(e); |
+ }; |
+ |
+ return completer.future; |
+} |
+ |
+/** |
* Takes all input from [source] and writes it to [sink]. |
* |
* [onClosed] is called when [source] is closed. |
@@ -451,6 +501,16 @@ Future<bool> extractTarGz(InputStream stream, destination) { |
} |
/** |
+ * Exception thrown when an HTTP operation fails. |
+ */ |
+class HttpException implements Exception { |
+ final int statusCode; |
+ final String reason; |
+ |
+ const HttpException(this.statusCode, this.reason); |
+} |
+ |
+/** |
* Contains the results of invoking a [Process] and waiting for it to complete. |
*/ |
class PubProcessResult { |