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

Unified Diff: utils/pub/curl_client.dart

Issue 12090104: Stop using cURL in Pub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/curl/openssl.LICENSE ('k') | utils/pub/hosted_source.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/pub/curl_client.dart
diff --git a/utils/pub/curl_client.dart b/utils/pub/curl_client.dart
deleted file mode 100644
index 7001a17c1865c6f44c155883dd268cfb598fa78e..0000000000000000000000000000000000000000
--- a/utils/pub/curl_client.dart
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library curl_client;
-
-import 'dart:async';
-import 'dart:io';
-
-import '../../pkg/http/lib/http.dart' as http;
-import 'io.dart';
-import 'log.dart' as log;
-import 'utils.dart';
-
-/// A drop-in replacement for [http.Client] that uses the `curl` command-line
-/// utility rather than [dart:io] to make requests. This class will only exist
-/// temporarily until [dart:io] natively supports requests over HTTPS.
-class CurlClient extends http.BaseClient {
- /// The path to the `curl` executable to run.
- ///
- /// By default on Unix-like operating systems, this will look up `curl` on the
- /// system path. On Windows, it will use the bundled `curl.exe`.
- final String executable;
-
- /// Creates a new [CurlClient] with [executable] as the path to the `curl`
- /// executable.
- ///
- /// By default on Unix-like operating systems, this will look up `curl` on the
- /// system path. On Windows, it will use the bundled `curl.exe`.
- CurlClient([String executable])
- : executable = executable == null ? _defaultExecutable : executable;
-
- /// Sends a request via `curl` and returns the response.
- Future<http.StreamedResponse> send(http.BaseRequest request) {
- log.fine("Sending Curl request $request");
-
- var requestStream = request.finalize();
- return withTempDir((tempDir) {
- var headerFile = join(tempDir, "curl-headers");
- var arguments = _argumentsForRequest(request, headerFile);
- var process;
- return startProcess(executable, arguments).then((process_) {
- process = process_;
- 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));
- });
- }
-
- /// Returns the list of arguments to `curl` necessary for performing
- /// [request]. [headerFile] is the path to the file where the response headers
- /// should be stored.
- List<String> _argumentsForRequest(
- http.BaseRequest request, String headerFile) {
- // Note: This line of code gets munged by create_sdk.py to be the correct
- // relative path to the certificate file in the SDK.
- var pathToCertificates = "../../third_party/curl/ca-certificates.crt";
-
- var arguments = [
- "--dump-header", headerFile,
- "--cacert", relativeToPub(pathToCertificates)
- ];
- if (request.method == 'HEAD') {
- arguments.add("--head");
- } else {
- arguments.add("--request");
- arguments.add(request.method);
- }
- if (request.followRedirects) {
- arguments.add("--location");
- arguments.add("--max-redirs");
- arguments.add(request.maxRedirects.toString());
- }
- if (request.contentLength != 0) {
- arguments.add("--data-binary");
- arguments.add("@-");
- }
-
- // Override the headers automatically added by curl. We want to make it
- // behave as much like the dart:io client as possible.
- var headers = {
- 'accept': '',
- 'user-agent': ''
- };
- request.headers.forEach((name, value) => headers[name] = value);
- if (request.contentLength < 0) {
- headers['content-length'] = '';
- headers['transfer-encoding'] = 'chunked';
- } else if (request.contentLength > 0) {
- headers['content-length'] = request.contentLength.toString();
- }
-
- headers.forEach((name, value) {
- arguments.add("--header");
- arguments.add("$name: $value");
- });
- arguments.add(request.url.toString());
-
- return arguments;
- }
-
- /// Returns a [Future] that completes once the `curl` [process] has finished
- /// receiving the response headers. [expectBody] indicates that the server is
- /// expected to send a response body (which is not the case for HEAD
- /// requests).
- ///
- /// Curl prints the headers to a file and then prints the body to stdout. So,
- /// in theory, we could read the headers as soon as we see anything appear
- /// 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(Process process, {bool expectBody}) {
- var completer = new Completer();
- process.onExit = (exitCode) {
- log.io("Curl process exited with code $exitCode.");
-
- 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);
- }
- }), 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.
- 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, 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
- // line, though, which we don't want to consider a separator.
- var lastBlank = lines.lastIndexOf("", lines.length - 2);
- if (lastBlank != -1) lines.removeRange(0, lastBlank + 1);
-
- var statusParts = lines.removeAt(0).split(" ");
- var status = int.parse(statusParts[1]);
- var isRedirect = status >= 300 && status < 400;
- var reasonPhrase =
- Strings.join(statusParts.getRange(2, statusParts.length - 2), " ");
- var headers = {};
- for (var line in lines) {
- if (line.isEmpty) continue;
- 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(
- wrapInputStream(responseStream), status, contentLength,
- request: request,
- headers: headers,
- isRedirect: isRedirect,
- reasonPhrase: reasonPhrase);
- }
-
- /// The default executable to use for running curl. On Windows, this is the
- /// path to the bundled `curl.exe`; elsewhere, this is just "curl", and we
- /// assume it to be installed and on the user's PATH.
- static String get _defaultExecutable {
- if (Platform.operatingSystem != 'windows') return 'curl';
- // Note: This line of code gets munged by create_sdk.py to be the correct
- // relative path to curl in the SDK.
- var pathToCurl = "../../third_party/curl/curl.exe";
- return relativeToPub(pathToCurl);
- }
-}
« no previous file with comments | « third_party/curl/openssl.LICENSE ('k') | utils/pub/hosted_source.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698