Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 library curl_client; | 5 library curl_client; |
| 6 | 6 |
| 7 import 'dart:io'; | 7 import 'dart:io'; |
| 8 | 8 |
| 9 import '../../pkg/http/lib/http.dart' as http; | 9 import '../../pkg/http/lib/http.dart' as http; |
| 10 import 'io.dart'; | 10 import 'io.dart'; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 }); | 98 }); |
| 99 arguments.add(request.url.toString()); | 99 arguments.add(request.url.toString()); |
| 100 | 100 |
| 101 return arguments; | 101 return arguments; |
| 102 } | 102 } |
| 103 | 103 |
| 104 /// Returns a [Future] that completes once the `curl` [process] has finished | 104 /// Returns a [Future] that completes once the `curl` [process] has finished |
| 105 /// receiving the response headers. [expectBody] indicates that the server is | 105 /// receiving the response headers. [expectBody] indicates that the server is |
| 106 /// expected to send a response body (which is not the case for HEAD | 106 /// expected to send a response body (which is not the case for HEAD |
| 107 /// requests). | 107 /// requests). |
| 108 Future _waitForHeaders(Process process, {bool expectBody}) { | 108 Future _waitForHeaders(Process process, {bool expectBody}) { |
|
nweiz
2012/11/30 01:19:45
If you're still going to call this "waitForHeaders
Bob Nystrom
2012/11/30 01:42:45
Added a comment explaining.
| |
| 109 var exitCompleter = new Completer<int>(); | 109 var completer = new Completer(); |
| 110 var exitFuture = exitCompleter.future; | |
| 111 process.onExit = (exitCode) { | 110 process.onExit = (exitCode) { |
| 112 if (exitCode == 0) { | 111 if (exitCode == 0) { |
| 113 exitCompleter.complete(0); | 112 completer.complete(null); |
| 114 return; | 113 return; |
| 115 } | 114 } |
| 116 | 115 |
| 117 chainToCompleter(consumeInputStream(process.stderr) | 116 chainToCompleter(consumeInputStream(process.stderr) |
| 118 .transform((stderrBytes) { | 117 .transform((stderrBytes) { |
| 119 var message = new String.fromCharCodes(stderrBytes); | 118 var message = new String.fromCharCodes(stderrBytes); |
| 120 if (exitCode == 47) { | 119 if (exitCode == 47) { |
| 121 throw new RedirectLimitExceededException([]); | 120 throw new RedirectLimitExceededException([]); |
| 122 } else { | 121 } else { |
| 123 throw new HttpException(message); | 122 throw new HttpException(message); |
| 124 } | 123 } |
| 125 }), exitCompleter); | 124 }), completer); |
| 126 }; | 125 }; |
| 127 | 126 |
| 128 // If there's not going to be a response body (e.g. for HEAD requests), curl | 127 // If there's not going to be a response body (e.g. for HEAD requests), curl |
| 129 // prints the headers to stdout instead of the body. We want to wait until | 128 // prints the headers to stdout instead of the body. We want to wait until |
| 130 // all the headers are received to read them from the header file. | 129 // all the headers are received to read them from the header file. |
| 131 if (!expectBody) { | 130 if (!expectBody) { |
| 132 return Futures.wait([ | 131 return Futures.wait([ |
| 133 consumeInputStream(process.stdout), | 132 consumeInputStream(process.stdout), |
| 134 exitFuture | 133 completer.future |
| 135 ]); | 134 ]); |
| 136 } | 135 } |
| 137 | 136 |
| 138 // TODO(nweiz): remove this when issue 4061 is fixed. | |
| 139 var stackTrace; | |
| 140 try { | |
| 141 throw ""; | |
| 142 } catch (_, localStackTrace) { | |
| 143 stackTrace = localStackTrace; | |
| 144 } | |
| 145 | |
| 146 var completer = new Completer(); | |
| 147 resetCallbacks() { | |
| 148 process.stdout.onData = null; | |
| 149 process.stdout.onError = null; | |
| 150 process.stdout.onClosed = null; | |
| 151 } | |
| 152 process.stdout.onData = () { | |
| 153 // TODO(nweiz): If an error happens after the body data starts being | |
| 154 // received, it should be piped through Response.stream once issue | |
| 155 // 3657 is fixed. | |
| 156 exitFuture.handleException((e) => true); | |
| 157 resetCallbacks(); | |
| 158 completer.complete(null); | |
| 159 }; | |
| 160 process.stdout.onError = (e) { | |
| 161 resetCallbacks(); | |
| 162 completer.completeException(e, stackTrace); | |
| 163 }; | |
| 164 process.stdout.onClosed = () { | |
| 165 resetCallbacks(); | |
| 166 chainToCompleter(exitFuture, completer); | |
| 167 }; | |
| 168 return completer.future; | 137 return completer.future; |
| 169 } | 138 } |
| 170 | 139 |
| 171 /// Returns a [http.StreamedResponse] from the response data printed by the | 140 /// Returns a [http.StreamedResponse] from the response data printed by the |
| 172 /// `curl` [process]. [lines] are the headers that `curl` wrote to a file. | 141 /// `curl` [process]. [lines] are the headers that `curl` wrote to a file. |
| 173 http.StreamedResponse _buildResponse( | 142 http.StreamedResponse _buildResponse( |
| 174 http.BaseRequest request, Process process, List<String> lines) { | 143 http.BaseRequest request, Process process, List<String> lines) { |
| 175 // When curl follows redirects, it prints the redirect headers as well as | 144 // When curl follows redirects, it prints the redirect headers as well as |
| 176 // the headers of the final request. Each block is separated by a blank | 145 // the headers of the final request. Each block is separated by a blank |
| 177 // line. We just care about the last block. There is one trailing empty | 146 // line. We just care about the last block. There is one trailing empty |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 /// path to the bundled `curl.exe`; elsewhere, this is just "curl", and we | 180 /// path to the bundled `curl.exe`; elsewhere, this is just "curl", and we |
| 212 /// assume it to be installed and on the user's PATH. | 181 /// assume it to be installed and on the user's PATH. |
| 213 static String get _defaultExecutable { | 182 static String get _defaultExecutable { |
| 214 if (Platform.operatingSystem != 'windows') return 'curl'; | 183 if (Platform.operatingSystem != 'windows') return 'curl'; |
| 215 // Note: This line of code gets munged by create_sdk.py to be the correct | 184 // Note: This line of code gets munged by create_sdk.py to be the correct |
| 216 // relative path to curl in the SDK. | 185 // relative path to curl in the SDK. |
| 217 var pathToCurl = "../../third_party/curl/curl.exe"; | 186 var pathToCurl = "../../third_party/curl/curl.exe"; |
| 218 return relativeToPub(pathToCurl); | 187 return relativeToPub(pathToCurl); |
| 219 } | 188 } |
| 220 } | 189 } |
| OLD | NEW |