Skip to content

HttpClient abstract interface

abstract interface class HttpClient

An HTTP client for communicating with an HTTP server.

Note: You should avoid directly using HttpClient to make HTTP requests. You can use HttpClient indirectly through the IOClient adapter in package:http.

Using a higher-level library, like package:http, allows you to switch implementations with minimal changes to your code. For example, package:httpClient has implementations for the browser and implementations that use platform native HTTP clients on Android and iOS. Unlike HttpClient, these native implementations work with the proxies, VPNs, etc.

Sends HTTP requests to an HTTP server and receives responses. Maintains state, including session cookies and other cookies, between multiple requests to the same server.

HttpClient contains a number of methods to send an HttpClientRequest to an Http server and receive an HttpClientResponse back. For example, you can use the get, getUrl, post, and postUrl methods for GET and POST requests, respectively.

Making a simple GET request: an example

A getUrl request is a two-step process, triggered by two Futures. When the first future completes with an HttpClientRequest, the underlying network connection has been established, but no data has been sent. In the callback function for the first future, the HTTP headers and body can be set on the request. Either the first write to the request object or a call to close sends the request to the server.

When the HTTP response is received from the server, the second future, which is returned by close, completes with an HttpClientResponse object. This object provides access to the headers and body of the response. The body is available as a stream implemented by HttpClientResponse. If a body is present, it must be read. Otherwise, it leads to resource leaks. Consider using HttpClientResponse.drain if the body is unused.

dart
var client = HttpClient();
try {
  HttpClientRequest request = await client.get('localhost', 80, '/file.txt');
  // Optionally set up headers...
  // Optionally write to the request object...
  HttpClientResponse response = await request.close();
  // Process the response
  final stringData = await response.transform(utf8.decoder).join();
  print(stringData);
} finally {
  client.close();
}

The future for HttpClientRequest is created by methods such as getUrl and open.

HTTPS connections

An HttpClient can make HTTPS requests, connecting to a server using the TLS (SSL) secure networking protocol. Calling getUrl with an https: scheme will work automatically, if the server's certificate is signed by a root CA (certificate authority) on the default list of well-known trusted CAs, compiled by Mozilla.

To add a custom trusted certificate authority, or to send a client certificate to servers that request one, pass a SecurityContext object as the optional context argument to the HttpClient constructor. The desired security options can be set on the SecurityContext object.

Headers

All HttpClient requests set the following header by default:

dart
Accept-Encoding: gzip

This allows the HTTP server to use gzip compression for the body if possible. If this behavior is not desired set the Accept-Encoding header to something else. To turn off gzip compression of the response, clear this header:

dart
 request.headers.removeAll(HttpHeaders.acceptEncodingHeader)

Closing the HttpClient

HttpClient supports persistent connections and caches network connections to reuse them for multiple requests whenever possible. This means that network connections can be kept open for some time after a request has completed. Use HttpClient.close to force the HttpClient object to shut down and to close the idle network connections.

Turning proxies on and off

By default the HttpClient uses the proxy configuration available from the environment, see findProxyFromEnvironment. To turn off the use of proxies set the findProxy property to null.

dart
HttpClient client = HttpClient();
client.findProxy = null;

Constructors

HttpClient() factory

factory HttpClient({SecurityContext? context})
Implementation
dart
factory HttpClient({SecurityContext? context}) {
  HttpOverrides? overrides = HttpOverrides.current;
  if (overrides == null) {
    return _HttpClient(context);
  }
  return overrides.createHttpClient(context);
}

Properties

authenticate no getter

set authenticate((Future<bool> Function(Uri url, String scheme, String? realm))? value)

Sets the function to be called when a site is requesting authentication.

The URL requested, the authentication scheme and the security realm from the server are passed in the arguments f.url, f.scheme and f.realm.

The function returns a Future which should complete when the authentication has been resolved. If credentials cannot be provided the Future should complete with false. If credentials are available the function should add these using addCredentials before completing the Future with the value true.

If the Future completes with true the request will be retried using the updated credentials, however, the retried request will not carry the original request payload. Otherwise response processing will continue normally.

If it is known that the remote server requires authentication for all requests, it is advisable to use addCredentials directly, or manually set the 'authorization' header on the request to avoid the overhead of a failed request, or issues due to missing request payload on retried request.

Implementation
dart
void set authenticate(
  Future<bool> Function(Uri url, String scheme, String? realm)? f,
);

authenticateProxy no getter

set authenticateProxy((Future<bool> Function(String host, int port, String scheme, String? realm))? value)

Sets the function to be called when a proxy is requesting authentication.

Information on the proxy in use, the authentication scheme and the security realm for the authentication are passed in the arguments f.host, f.port, f.scheme and f.realm.

The function returns a Future which should complete when the authentication has been resolved. If credentials cannot be provided the Future should complete with false. If credentials are available the function should add these using addProxyCredentials before completing the Future with the value true.

If the Future completes with true the request will be retried using the updated credentials. Otherwise response processing will continue normally.

Implementation
dart
void set authenticateProxy(
  Future<bool> Function(String host, int port, String scheme, String? realm)?
  f,
);

autoUncompress read / write

bool autoUncompress

getter:

Gets and sets whether the body of a response will be automatically uncompressed.

The body of an HTTP response can be compressed. In most situations providing the un-compressed body is most convenient. Therefore the default behavior is to un-compress the body. However in some situations (e.g. implementing a transparent proxy) keeping the uncompressed stream is required.

NOTE: Headers in the response are never modified. This means that when automatic un-compression is turned on the value of the header Content-Length will reflect the length of the original compressed body. Likewise the header Content-Encoding will also have the original value indicating compression.

NOTE: Automatic un-compression is only performed if the Content-Encoding header value is gzip.

This value affects all responses produced by this client after the value is changed.

To disable, set to false.

Default is true.

setter:

Gets and sets whether the body of a response will be automatically uncompressed.

The body of an HTTP response can be compressed. In most situations providing the un-compressed body is most convenient. Therefore the default behavior is to un-compress the body. However in some situations (e.g. implementing a transparent proxy) keeping the uncompressed stream is required.

NOTE: Headers in the response are never modified. This means that when automatic un-compression is turned on the value of the header Content-Length will reflect the length of the original compressed body. Likewise the header Content-Encoding will also have the original value indicating compression.

NOTE: Automatic un-compression is only performed if the Content-Encoding header value is gzip.

This value affects all responses produced by this client after the value is changed.

To disable, set to false.

Default is true.

Implementation
dart
bool autoUncompress = true;

badCertificateCallback no getter

set badCertificateCallback((bool Function(X509Certificate cert, String host, int port))? value)

Sets a callback that will decide whether to accept a secure connection with a server certificate that cannot be authenticated by any of our trusted root certificates.

When a secure HTTP request is made, using this HttpClient, and the server returns a server certificate that cannot be authenticated, the callback is called asynchronously with the X509Certificate object and the server's hostname and port. If the value of badCertificateCallback is null, the bad certificate is rejected, as if the callback returned false

If the callback returns true, the secure connection is accepted and the Future<HttpClientRequest> that was returned from the call making the request completes with a valid HttpRequest object. If the callback returns false, the Future<HttpClientRequest> completes with an exception.

If a bad certificate is received on a connection attempt, the library calls the function that was the value of badCertificateCallback at the time the request is made, even if the value of badCertificateCallback has changed since then.

Implementation
dart
void set badCertificateCallback(
  bool Function(X509Certificate cert, String host, int port)? callback,
);

connectionFactory no getter

set connectionFactory((Future<ConnectionTask<Socket>> Function(Uri url, String? proxyHost, int? proxyPort))? value)

Sets the function used to create socket connections.

The URL requested (e.g. through getUrl) and proxy configuration (f.proxyHost and f.proxyPort) are passed as arguments. f.proxyHost and f.proxyPort will be null if the connection is not made through a proxy.

Since connections may be reused based on host and port, it is important that the function not ignore f.proxyHost and f.proxyPort if they are not null. If proxies are not meaningful for the returned Socket, you can set findProxy to use a direct connection.

For example:

dart
import "dart:io";

void main() async {
  HttpClient client = HttpClient()
    ..connectionFactory = (Uri uri, String? proxyHost, int? proxyPort) {
        assert(proxyHost == null);
        assert(proxyPort == null);
        var address = InternetAddress("/var/run/docker.sock",
            type: InternetAddressType.unix);
        return Socket.startConnect(address, 0);
    }
    ..findProxy = (Uri uri) => 'DIRECT';

  final request = await client.getUrl(Uri.parse("http://ignored/v1.41/info"));
  final response = await request.close();
  print(response.statusCode);
  await response.drain();
  client.close();
}
Implementation
dart
void set connectionFactory(
  Future<ConnectionTask<Socket>> Function(
    Uri url,
    String? proxyHost,
    int? proxyPort,
  )?
  f,
);

connectionTimeout read / write

Duration? connectionTimeout

getter:

Gets and sets the connection timeout.

When connecting to a new host exceeds this timeout, a SocketException is thrown. The timeout applies only to connections initiated after the timeout is set.

When this is null, the OS default timeout is used. The default is null.

setter:

Gets and sets the connection timeout.

When connecting to a new host exceeds this timeout, a SocketException is thrown. The timeout applies only to connections initiated after the timeout is set.

When this is null, the OS default timeout is used. The default is null.

Implementation
dart
Duration? connectionTimeout;

findProxy no getter

set findProxy((String Function(Uri url))? value)

Sets the function used to resolve the proxy server to be used for opening an HTTP connection to the specified url. If this function is not set, direct connections will always be used.

The string returned by f must be in the format used by browser PAC (proxy auto-config) scripts. That is either

dart
"DIRECT"

for using a direct connection or

dart
"PROXY host:port"

for using the proxy server host on port port.

A configuration can contain several configuration elements separated by semicolons, e.g.

dart
"PROXY host:port; PROXY host2:port2; DIRECT"

The static function findProxyFromEnvironment on this class can be used to implement proxy server resolving based on environment variables.

Implementation
dart
void set findProxy(String Function(Uri url)? f);

hashCode no setter inherited

int get hashCode

The hash code for this object.

A hash code is a single integer which represents the state of the object that affects operator == comparisons.

All objects have hash codes. The default hash code implemented by Object represents only the identity of the object, the same way as the default operator == implementation only considers objects equal if they are identical (see identityHashCode).

If operator == is overridden to use the object state instead, the hash code must also be changed to represent that state, otherwise the object cannot be used in hash based data structures like the default Set and Map implementations.

Hash codes must be the same for objects that are equal to each other according to operator ==. The hash code of an object should only change if the object changes in a way that affects equality. There are no further requirements for the hash codes. They need not be consistent between executions of the same program and there are no distribution guarantees.

Objects that are not equal are allowed to have the same hash code. It is even technically allowed that all instances have the same hash code, but if clashes happen too often, it may reduce the efficiency of hash-based data structures like HashSet or HashMap.

If a subclass overrides hashCode, it should override the operator == operator as well to maintain consistency.

Inherited from Object.

Implementation
dart
external int get hashCode;

idleTimeout read / write

Duration idleTimeout

getter:

Gets and sets the idle timeout of non-active persistent (keep-alive) connections.

The default value is 15 seconds.

setter:

Gets and sets the idle timeout of non-active persistent (keep-alive) connections.

The default value is 15 seconds.

Implementation
dart
Duration idleTimeout = const Duration(seconds: 15);

keyLog no getter

set keyLog((dynamic Function(String line))? value)

Sets a callback that will be called when new TLS keys are exchanged with the server. It will receive one line of text in NSS Key Log Format for each call. Writing these lines to a file will allow tools (such as Wireshark) to decrypt communication between the this client and the server. This is meant to allow network-level debugging of secure sockets and should not be used in production code. For example:

dart
final log = File('keylog.txt');
final client = HttpClient();
client.keyLog = (line) => log.writeAsStringSync(line,
    mode: FileMode.append);
Implementation
dart
void set keyLog(Function(String line)? callback);

maxConnectionsPerHost read / write

int? maxConnectionsPerHost

getter:

Gets and sets the maximum number of live connections, to a single host.

Increasing this number may lower performance and take up unwanted system resources.

To disable, set to null.

Default is null.

setter:

Gets and sets the maximum number of live connections, to a single host.

Increasing this number may lower performance and take up unwanted system resources.

To disable, set to null.

Default is null.

Implementation
dart
int? maxConnectionsPerHost;

runtimeType no setter inherited

Type get runtimeType

A representation of the runtime type of the object.

Inherited from Object.

Implementation
dart
external Type get runtimeType;

userAgent read / write

String? userAgent

getter:

Gets and sets the default value of the User-Agent header for all requests generated by this HttpClient.

The default value is Dart/<version> (dart:io).

If the userAgent is set to null, no default User-Agent header will be added to each request.

setter:

Gets and sets the default value of the User-Agent header for all requests generated by this HttpClient.

The default value is Dart/<version> (dart:io).

If the userAgent is set to null, no default User-Agent header will be added to each request.

Implementation
dart
String? userAgent;

Methods

addCredentials()

void addCredentials(Uri url, String realm, HttpClientCredentials credentials)

Add credentials to be used for authorizing HTTP requests.

Implementation
dart
void addCredentials(Uri url, String realm, HttpClientCredentials credentials);

addProxyCredentials()

void addProxyCredentials(
  String host,
  int port,
  String realm,
  HttpClientCredentials credentials,
)

Add credentials to be used for authorizing HTTP proxies.

Implementation
dart
void addProxyCredentials(
  String host,
  int port,
  String realm,
  HttpClientCredentials credentials,
);

close()

void close({bool force = false})

Shuts down the HTTP client.

If force is false (the default) the HttpClient will be kept alive until all active connections are done. If force is true any active connections will be closed to immediately release all resources. These closed connections will receive an error event to indicate that the client was shut down. In both cases trying to establish a new connection after calling close will throw an exception.

Implementation
dart
void close({bool force = false});

delete()

Future<HttpClientRequest> delete(String host, int port, String path)

Opens an HTTP connection using the DELETE method.

The server is specified using host and port, and the path (including a possible query) is specified using path.

See open for details.

Implementation
dart
Future<HttpClientRequest> delete(String host, int port, String path);

deleteUrl()

Future<HttpClientRequest> deleteUrl(Uri url)

Opens an HTTP connection using the DELETE method.

The URL to use is specified in url.

See openUrl for details.

Implementation
dart
Future<HttpClientRequest> deleteUrl(Uri url);

get()

Future<HttpClientRequest> get(String host, int port, String path)

Opens an HTTP connection using the GET method.

The server is specified using host and port, and the path (including a possible query) is specified using path.

See open for details.

Implementation
dart
Future<HttpClientRequest> get(String host, int port, String path);

getUrl()

Opens an HTTP connection using the GET method.

The URL to use is specified in url.

See openUrl for details.

Implementation
dart
Future<HttpClientRequest> getUrl(Uri url);
Future<HttpClientRequest> head(String host, int port, String path)

Opens an HTTP connection using the HEAD method.

The server is specified using host and port, and the path (including a possible query) is specified using path.

See open for details.

Implementation
dart
Future<HttpClientRequest> head(String host, int port, String path);

headUrl()

Opens an HTTP connection using the HEAD method.

The URL to use is specified in url.

See openUrl for details.

Implementation
dart
Future<HttpClientRequest> headUrl(Uri url);

noSuchMethod() inherited

dynamic noSuchMethod(Invocation invocation)

Invoked when a nonexistent method or property is accessed.

A dynamic member invocation can attempt to call a member which doesn't exist on the receiving object. Example:

dart
dynamic object = 1;
object.add(42); // Statically allowed, run-time error

This invalid code will invoke the noSuchMethod method of the integer 1 with an Invocation representing the .add(42) call and arguments (which then throws).

Classes can override noSuchMethod to provide custom behavior for such invalid dynamic invocations.

A class with a non-default noSuchMethod invocation can also omit implementations for members of its interface. Example:

dart
class MockList<T> implements List<T> {
  noSuchMethod(Invocation invocation) {
    log(invocation);
    super.noSuchMethod(invocation); // Will throw.
  }
}
void main() {
  MockList().add(42);
}

This code has no compile-time warnings or errors even though the MockList class has no concrete implementation of any of the List interface methods. Calls to List methods are forwarded to noSuchMethod, so this code will log an invocation similar to Invocation.method(#add, [42]) and then throw.

If a value is returned from noSuchMethod, it becomes the result of the original invocation. If the value is not of a type that can be returned by the original invocation, a type error occurs at the invocation.

The default behavior is to throw a NoSuchMethodError.

Inherited from Object.

Implementation
dart
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);

open()

Future<HttpClientRequest> open(
  String method,
  String host,
  int port,
  String path,
)

Opens an HTTP connection.

The HTTP method to use is specified in method, the server is specified using host and port, and the path (including a possible query) is specified using path. The path may also contain a URI fragment, which will be ignored.

The Host header for the request will be set to the value host:port (if host is an IP address, it will still be used in the Host header). This can be overridden through the HttpClientRequest interface before the request is sent.

For additional information on the sequence of events during an HTTP transaction, and the objects returned by the futures, see the overall documentation for the class HttpClient.

Implementation
dart
Future<HttpClientRequest> open(
  String method,
  String host,
  int port,
  String path,
);

openUrl()

Future<HttpClientRequest> openUrl(String method, Uri url)

Opens an HTTP connection.

The HTTP method is specified in method and the URL to use in url.

The Host header for the request will be set to the value Uri.host:Uri.port from url (if url.host is an IP address, it will still be used in the Host header). This can be overridden through the HttpClientRequest interface before the request is sent.

For additional information on the sequence of events during an HTTP transaction, and the objects returned by the futures, see the overall documentation for the class HttpClient.

Implementation
dart
Future<HttpClientRequest> openUrl(String method, Uri url);

patch()

Future<HttpClientRequest> patch(String host, int port, String path)

Opens an HTTP connection using the PATCH method.

The server is specified using host and port, and the path (including a possible query) is specified using path.

See open for details.

Implementation
dart
Future<HttpClientRequest> patch(String host, int port, String path);

patchUrl()

Opens an HTTP connection using the PATCH method.

The URL to use is specified in url.

See openUrl for details.

Implementation
dart
Future<HttpClientRequest> patchUrl(Uri url);

post()

Future<HttpClientRequest> post(String host, int port, String path)

Opens an HTTP connection using the POST method.

The server is specified using host and port, and the path (including a possible query) is specified using path.

See open for details.

Implementation
dart
Future<HttpClientRequest> post(String host, int port, String path);

postUrl()

Opens an HTTP connection using the POST method.

The URL to use is specified in url.

See openUrl for details.

Implementation
dart
Future<HttpClientRequest> postUrl(Uri url);

put()

Future<HttpClientRequest> put(String host, int port, String path)

Opens an HTTP connection using the PUT method.

The server is specified using host and port, and the path (including a possible query) is specified using path.

See open for details.

Implementation
dart
Future<HttpClientRequest> put(String host, int port, String path);

putUrl()

Opens an HTTP connection using the PUT method.

The URL to use is specified in url.

See openUrl for details.

Implementation
dart
Future<HttpClientRequest> putUrl(Uri url);

toString() inherited

String toString()

A string representation of this object.

Some classes have a default textual representation, often paired with a static parse function (like int.parse). These classes will provide the textual representation as their string representation.

Other classes have no meaningful textual representation that a program will care about. Such classes will typically override toString to provide useful information when inspecting the object, mainly for debugging or logging.

Inherited from Object.

Implementation
dart
external String toString();

Operators

operator ==() inherited

bool operator ==(Object other)

The equality operator.

The default behavior for all Objects is to return true if and only if this object and other are the same object.

Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:

  • Total: It must return a boolean for all arguments. It should never throw.

  • Reflexive: For all objects o, o == o must be true.

  • Symmetric: For all objects o1 and o2, o1 == o2 and o2 == o1 must either both be true, or both be false.

  • Transitive: For all objects o1, o2, and o3, if o1 == o2 and o2 == o3 are true, then o1 == o3 must be true.

The method should also be consistent over time, so whether two objects are equal should only change if at least one of the objects was modified.

If a subclass overrides the equality operator, it should override the hashCode method as well to maintain consistency.

Inherited from Object.

Implementation
dart
external bool operator ==(Object other);

Static Properties

enableTimelineLogging read / write

bool get enableTimelineLogging

getter:

Current state of HTTP request logging from all HttpClients to the developer timeline.

Default is false.

setter:

Enable logging of HTTP requests from all HttpClients to the developer timeline.

Default is false.

Implementation
dart
static bool get enableTimelineLogging => _enableTimelineLogging;

static set enableTimelineLogging(bool value) {
  final enabled = valueOfNonNullableParamWithDefault<bool>(value, false);
  if (enabled != _enableTimelineLogging) {
    if (!const bool.fromEnvironment("dart.vm.product")) {
      postEvent('HttpTimelineLoggingStateChange', {
        'isolateId': Service.getIsolateId(Isolate.current),
        'enabled': enabled,
      });
    }
  }
  _enableTimelineLogging = enabled;
}

Static Methods

findProxyFromEnvironment()

String findProxyFromEnvironment(Uri url, {Map<String, String>? environment})

Function for resolving the proxy server to be used for an HTTP connection from the proxy configuration specified through environment variables.

The following environment variables are taken into account:

dart
http_proxy
https_proxy
no_proxy
HTTP_PROXY
HTTPS_PROXY
NO_PROXY

http_proxy and HTTP_PROXY specify the proxy server to use for http:// urls. Use the format hostname:port. If no port is used a default of 1080 will be used. If both are set the lower case one takes precedence.

https_proxy and HTTPS_PROXY specify the proxy server to use for https:// urls. Use the format hostname:port. If no port is used a default of 1080 will be used. If both are set the lower case one takes precedence.

no_proxy and NO_PROXY specify a comma separated list of postfixes of hostnames for which not to use the proxy server. E.g. the value "localhost,127.0.0.1" will make requests to both "localhost" and "127.0.0.1" not use a proxy. If both are set the lower case one takes precedence.

To activate this way of resolving proxies assign this function to the findProxy property on the HttpClient.

dart
HttpClient client = HttpClient();
client.findProxy = HttpClient.findProxyFromEnvironment;

If you don't want to use the system environment you can use a different one by wrapping the function.

dart
HttpClient client = HttpClient();
client.findProxy = (url) {
  return HttpClient.findProxyFromEnvironment(
      url, environment: {"http_proxy": ..., "no_proxy": ...});
}

If a proxy requires authentication it is possible to configure the username and password as well. Use the format username:password@hostname:port to include the username and password. Alternatively the API addProxyCredentials can be used to set credentials for proxies which require authentication.

Implementation
dart
static String findProxyFromEnvironment(
  Uri url, {
  Map<String, String>? environment,
}) {
  HttpOverrides? overrides = HttpOverrides.current;
  if (overrides == null) {
    return _HttpClient._findProxyFromEnvironment(url, environment);
  }
  return overrides.findProxyFromEnvironment(url, environment);
}

Constants

defaultHttpPort

const int defaultHttpPort
Implementation
dart
static const int defaultHttpPort = 80;

defaultHttpsPort

const int defaultHttpsPort
Implementation
dart
static const int defaultHttpsPort = 443;