| Index: utils/pub/curl_client.dart
|
| diff --git a/utils/pub/curl_client.dart b/utils/pub/curl_client.dart
|
| index a1cc1ed36ced6008dd9240e93951111bf19bcdb5..7001a17c1865c6f44c155883dd268cfb598fa78e 100644
|
| --- a/utils/pub/curl_client.dart
|
| +++ b/utils/pub/curl_client.dart
|
| @@ -41,10 +41,9 @@ class CurlClient extends http.BaseClient {
|
| var process;
|
| return startProcess(executable, arguments).then((process_) {
|
| process = process_;
|
| - return Future.wait([
|
| - store(requestStream, process.stdin),
|
| - _waitForHeaders(process, expectBody: request.method != "HEAD")
|
| - ]);
|
| + return requestStream.pipe(wrapOutputStream(process.stdin));
|
| + }).then((_) {
|
| + return _waitForHeaders(process, expectBody: request.method != "HEAD");
|
| }).then((_) => new File(headerFile).readAsLines())
|
| .then((lines) => _buildResponse(request, process, lines));
|
| });
|
| @@ -112,33 +111,44 @@ class CurlClient extends http.BaseClient {
|
| /// in stdout. However, that seems to be too early to successfully read the
|
| /// file (at least on Mac). Instead, this just waits until the entire process
|
| /// has completed.
|
| - Future _waitForHeaders(PubProcess process, {bool expectBody}) {
|
| - var future = process.exitCode.then((exitCode) {
|
| + Future _waitForHeaders(Process process, {bool expectBody}) {
|
| + var completer = new Completer();
|
| + process.onExit = (exitCode) {
|
| log.io("Curl process exited with code $exitCode.");
|
| - if (exitCode == 0) return;
|
|
|
| - process.stderr.bytesToString().then((message) {
|
| + if (exitCode == 0) {
|
| + completer.complete(null);
|
| + return;
|
| + }
|
| +
|
| + chainToCompleter(consumeInputStream(process.stderr).then((stderrBytes) {
|
| + var message = new String.fromCharCodes(stderrBytes);
|
| log.fine('Got error reading headers from curl: $message');
|
| if (exitCode == 47) {
|
| throw new RedirectLimitExceededException([]);
|
| } else {
|
| throw new HttpException(message);
|
| }
|
| - });
|
| - });
|
| -
|
| - if (expectBody) return future;
|
| + }), completer);
|
| + };
|
|
|
| // If there's not going to be a response body (e.g. for HEAD requests), curl
|
| // prints the headers to stdout instead of the body. We want to wait until
|
| // all the headers are received to read them from the header file.
|
| - return Future.wait([process.stdout.toBytes(), future]);
|
| + if (!expectBody) {
|
| + return Future.wait([
|
| + consumeInputStream(process.stdout),
|
| + completer.future
|
| + ]);
|
| + }
|
| +
|
| + return completer.future;
|
| }
|
|
|
| /// Returns a [http.StreamedResponse] from the response data printed by the
|
| /// `curl` [process]. [lines] are the headers that `curl` wrote to a file.
|
| http.StreamedResponse _buildResponse(
|
| - http.BaseRequest request, PubProcess process, List<String> lines) {
|
| + http.BaseRequest request, Process process, List<String> lines) {
|
| // When curl follows redirects, it prints the redirect headers as well as
|
| // the headers of the final request. Each block is separated by a blank
|
| // line. We just care about the last block. There is one trailing empty
|
| @@ -157,13 +167,18 @@ class CurlClient extends http.BaseClient {
|
| var split = split1(line, ":");
|
| headers[split[0].toLowerCase()] = split[1].trim();
|
| }
|
| + var responseStream = process.stdout;
|
| + if (responseStream.closed) {
|
| + responseStream = new ListInputStream();
|
| + responseStream.markEndOfStream();
|
| + }
|
| var contentLength = -1;
|
| if (headers.containsKey('content-length')) {
|
| contentLength = int.parse(headers['content-length']);
|
| }
|
|
|
| return new http.StreamedResponse(
|
| - process.stdout, status, contentLength,
|
| + wrapInputStream(responseStream), status, contentLength,
|
| request: request,
|
| headers: headers,
|
| isRedirect: isRedirect,
|
|
|