| // 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. |
| |
| import 'dart:async'; |
| |
| import 'base_client.dart'; |
| import 'base_request.dart'; |
| import 'exception.dart'; |
| import 'io.dart' as io; |
| import 'streamed_response.dart'; |
| |
| /// A `dart:io`-based HTTP client. |
| /// |
| /// This is the default client when running on the command line. |
| class IOClient extends BaseClient { |
| /// The underlying `dart:io` HTTP client. |
| var _inner; |
| |
| /// Creates a new HTTP client. |
| /// |
| /// [innerClient] must be a `dart:io` HTTP client. If it's not passed, a |
| /// default one will be instantiated. |
| IOClient([innerClient]) { |
| io.assertSupported("IOClient"); |
| if (innerClient != null) { |
| // TODO(nweiz): remove this assert when we can type [innerClient] |
| // properly. |
| assert(io.isHttpClient(innerClient)); |
| _inner = innerClient; |
| } else { |
| _inner = io.newHttpClient(); |
| } |
| } |
| |
| /// Sends an HTTP request and asynchronously returns the response. |
| Future<StreamedResponse> send(BaseRequest request) { |
| var stream = request.finalize(); |
| |
| return _inner.openUrl(request.method, request.url) |
| .then((ioRequest) { |
| var contentLength = request.contentLength == null ? |
| -1 : request.contentLength; |
| ioRequest |
| ..followRedirects = request.followRedirects |
| ..maxRedirects = request.maxRedirects |
| ..contentLength = contentLength |
| ..persistentConnection = request.persistentConnection; |
| request.headers.forEach((name, value) { |
| ioRequest.headers.set(name, value); |
| }); |
| return stream.pipe(ioRequest); |
| }).then((response) { |
| var headers = {}; |
| response.headers.forEach((key, values) { |
| headers[key] = values.join(','); |
| }); |
| |
| var contentLength = response.contentLength == -1 ? |
| null : response.contentLength; |
| return new StreamedResponse( |
| response.handleError((error) => |
| throw new ClientException(error.message, error.uri), |
| test: (error) => io.isHttpException(error)), |
| response.statusCode, |
| contentLength: contentLength, |
| request: request, |
| headers: headers, |
| isRedirect: response.isRedirect, |
| persistentConnection: response.persistentConnection, |
| reasonPhrase: response.reasonPhrase); |
| }).catchError((error) { |
| if (!io.isHttpException(error)) throw error; |
| throw new ClientException(error.message, error.uri); |
| }); |
| } |
| |
| /// Closes the client. This terminates all active connections. If a client |
| /// remains unclosed, the Dart process may not terminate. |
| void close() { |
| if (_inner != null) _inner.close(force: true); |
| _inner = null; |
| } |
| } |