Make `package:http/http.dart` support all platforms (#198)

Fixes https://github.com/dart-lang/http/issues/22

Adds config specific imports to make `package:http/http.dart` support all platforms, and allow the `Client` factory constructor to return a valid `Client` for the web platform.

This should eliminate almost all need for the platform specific imports for consumers, although it does also add the `io_client.dart` public import.

Passes presubmit internally, with edits in only 3 files (they use the IoClient constructor directly, and pass in an HttpClient). Externally build_runner now supports config specific imports as well, I am currently working on validating everything works as expected there with this change.

### New Features

* The regular `Client` factory constructor is now usable anywhere that `dart:io`
  or `dart:html` are available, and will give you an `IoClient` or
  `BrowserClient` respectively.
* The `package:http/http.dart` import is now safe to use on the web (or
  anywhere that either `dart:io` or `dart:html` are available).

### Breaking Changes

* In order to use or reference the `IoClient` directly, you will need to import
  the new `package:http/io_client.dart` import. This is typically only necessary
  if you are passing a custom `HttpClient` instance to the constructor, in which
  case you are already giving up support for web.
13 files changed
tree: b01603d4e5469ead910591b4479d79bd2f69a14d
  1. lib/
  2. test/
  3. .gitignore
  4. .test_config
  5. .travis.yml
  6. CHANGELOG.md
  7. LICENSE
  8. pubspec.yaml
  9. README.md
README.md

http

A composable, Future-based library for making HTTP requests.

This package contains a set of high-level functions and classes that make it easy to consume HTTP resources. It's platform-independent, and can be used on both the command-line and the browser. Currently the global utility functions are unsupported on the browser; see “Using on the Browser” below.

Using

The easiest way to use this library is via the top-level functions, although they currently only work on platforms where dart:io is available. They allow you to make individual HTTP requests with minimal hassle:

import 'package:http/http.dart' as http;

var url = "http://example.com/whatsit/create";
http.post(url, body: {"name": "doodle", "color": "blue"})
    .then((response) {
  print("Response status: ${response.statusCode}");
  print("Response body: ${response.body}");
});

http.read("http://example.com/foobar.txt").then(print);

If you‘re making multiple requests to the same server, you can keep open a persistent connection by using a Client rather than making one-off requests. If you do this, make sure to close the client when you’re done:

var client = new http.Client();
client.post(
    "http://example.com/whatsit/create",
    body: {"name": "doodle", "color": "blue"})
  .then((response) => client.get(response.bodyFields['uri']))
  .then((response) => print(response.body))
  .whenComplete(client.close);

You can also exert more fine-grained control over your requests and responses by creating Request or StreamedRequest objects yourself and passing them to Client.send.

This package is designed to be composable. This makes it easy for external libraries to work with one another to add behavior to it. Libraries wishing to add behavior should create a subclass of BaseClient that wraps another Client and adds the desired behavior:

class UserAgentClient extends http.BaseClient {
  final String userAgent;
  final http.Client _inner;

  UserAgentClient(this.userAgent, this._inner);

  Future<StreamedResponse> send(BaseRequest request) {
    request.headers['user-agent'] = userAgent;
    return _inner.send(request);
  }
}

Using on the Browser

The HTTP library can be used on the browser via the BrowserClient class in package:http/browser_client.dart. This client translates requests into XMLHttpRequests. For example:

import 'dart:async';
import 'package:http/browser_client.dart';

main() async {
  var client = new BrowserClient();
  var url = '/whatsit/create';
  var response =
      await client.post(url, body: {'name': 'doodle', 'color': 'blue'});
  print('Response status: ${response.statusCode}');
  print('Response body: ${response.body}');
}