| Index: pkg/http/lib/browser_client.dart
|
| diff --git a/pkg/http/lib/browser_client.dart b/pkg/http/lib/browser_client.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..957784ba3dcf15bcea659efbe5a1a179e87a1e26
|
| --- /dev/null
|
| +++ b/pkg/http/lib/browser_client.dart
|
| @@ -0,0 +1,98 @@
|
| +// 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 http.browser_client;
|
| +
|
| +import 'dart:async';
|
| +import 'dart:html';
|
| +import 'dart:typed_data';
|
| +
|
| +import 'package:stack_trace/stack_trace.dart';
|
| +
|
| +import 'src/base_client.dart';
|
| +import 'src/base_request.dart';
|
| +import 'src/byte_stream.dart';
|
| +import 'src/exception.dart';
|
| +import 'src/streamed_response.dart';
|
| +
|
| +// TODO(nweiz): Move this under src/, re-export from lib/http.dart, and use this
|
| +// automatically from [new Client] once we can create an HttpRequest using
|
| +// mirrors on dart2js (issue 18541) and dart2js doesn't crash on pkg/collection
|
| +// (issue 18535).
|
| +
|
| +/// A `dart:html`-based HTTP client that runs in the browser and is backed by
|
| +/// XMLHttpRequests.
|
| +///
|
| +/// This client inherits some of the limitations of XMLHttpRequest. It ignores
|
| +/// the [BaseRequest.contentLength], [BaseRequest.persistentConnection],
|
| +/// [BaseRequest.followRedirects], and [BaseRequest.maxRedirects] fields. It is
|
| +/// also unable to stream requests or responses; a request will only be sent and
|
| +/// a response will only be returned once all the data is available.
|
| +class BrowserClient extends BaseClient {
|
| + /// The currently active XHRs.
|
| + ///
|
| + /// These are aborted if the client is closed.
|
| + final _xhrs = new Set<HttpRequest>();
|
| +
|
| + /// Creates a new HTTP client.
|
| + BrowserClient();
|
| +
|
| + /// Sends an HTTP request and asynchronously returns the response.
|
| + Future<StreamedResponse> send(BaseRequest request) {
|
| + return request.finalize().toBytes().then((bytes) {
|
| + var xhr = new HttpRequest();
|
| + _xhrs.add(xhr);
|
| + xhr.open(request.method, request.url.toString(), async: true);
|
| + xhr.responseType = 'blob';
|
| + request.headers.forEach(xhr.setRequestHeader);
|
| +
|
| + var completer = new Completer();
|
| + xhr.onLoad.first.then((_) {
|
| + // TODO(nweiz): Set the response type to "arraybuffer" when issue 18542
|
| + // is fixed.
|
| + var blob = xhr.response == null ? new Blob([]) : xhr.response;
|
| + var reader = new FileReader();
|
| +
|
| + reader.onLoad.first.then((_) {
|
| + var body = reader.result;
|
| + completer.complete(new StreamedResponse(
|
| + new ByteStream.fromBytes(body),
|
| + xhr.status,
|
| + contentLength: body.length,
|
| + request: request,
|
| + headers: xhr.responseHeaders,
|
| + reasonPhrase: xhr.statusText));
|
| + });
|
| +
|
| + reader.onError.first.then((error) {
|
| + completer.complete(
|
| + new ClientException(error.toString(), request.url),
|
| + new Chain.current());
|
| + });
|
| +
|
| + reader.readAsArrayBuffer(blob);
|
| + });
|
| +
|
| + xhr.onError.first.then((_) {
|
| + // Unfortunately, the underlying XMLHttpRequest API doesn't expose any
|
| + // specific information about the error itself.
|
| + completer.completeError(
|
| + new ClientException("XMLHttpRequest error.", request.url),
|
| + new Chain.current());
|
| + });
|
| +
|
| + xhr.send(bytes);
|
| + return completer.future.whenComplete(() => _xhrs.remove(xhr));
|
| + });
|
| + }
|
| +
|
| + /// Closes the client.
|
| + ///
|
| + /// This terminates all active requests.
|
| + void close() {
|
| + for (var xhr in _xhrs) {
|
| + xhr.abort();
|
| + }
|
| + }
|
| +}
|
|
|