HttpClient abstract interface#
An HTTP client for communicating with an HTTP server.
Note: You should avoid directly using
HttpClientto make HTTP requests. You can useHttpClientindirectly 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:http
Client
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.
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:
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:
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.
HttpClient client = HttpClient();
client.findProxy = null;
Constructors#
HttpClient() factory#
Implementation
factory HttpClient({SecurityContext? context}) {
HttpOverrides? overrides = HttpOverrides.current;
if (overrides == null) {
return _HttpClient(context);
}
return overrides.createHttpClient(context);
}
Properties#
authenticate no getter#
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
void set authenticate(
Future<bool> Function(Uri url, String scheme, String? realm)? f,
);
authenticateProxy no getter#
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
void set authenticateProxy(
Future<bool> Function(String host, int port, String scheme, String? realm)?
f,
);
autoUncompress read / write#
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
bool autoUncompress = true;
badCertificateCallback no getter#
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
void set badCertificateCallback(
bool Function(X509Certificate cert, String host, int port)? callback,
);
connectionFactory no getter#
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:
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
void set connectionFactory(
Future<ConnectionTask<Socket>> Function(
Uri url,
String? proxyHost,
int? proxyPort,
)?
f,
);
connectionTimeout read / write#
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
Duration? connectionTimeout;
findProxy no getter#
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
"DIRECT"
for using a direct connection or
"PROXY host:port"
for using the proxy server host on port port.
A configuration can contain several configuration elements separated by semicolons, e.g.
"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
void set findProxy(String Function(Uri url)? f);
hashCode no setter inherited#
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
external int get hashCode;
idleTimeout read / write#
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
Duration idleTimeout = const Duration(seconds: 15);
keyLog no getter#
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:
final log = File('keylog.txt');
final client = HttpClient();
client.keyLog = (line) => log.writeAsStringSync(line,
mode: FileMode.append);
Implementation
void set keyLog(Function(String line)? callback);
maxConnectionsPerHost read / write#
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
int? maxConnectionsPerHost;
runtimeType no setter inherited#
A representation of the runtime type of the object.
Inherited from Object.
Implementation
external Type get runtimeType;
userAgent read / write#
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
String? userAgent;
Methods#
addCredentials()#
Add credentials to be used for authorizing HTTP requests.
Implementation
void addCredentials(Uri url, String realm, HttpClientCredentials credentials);
addProxyCredentials()#
Add credentials to be used for authorizing HTTP proxies.
Implementation
void addProxyCredentials(
String host,
int port,
String realm,
HttpClientCredentials credentials,
);
close()#
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
void close({bool force = false});
delete()#
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
Future<HttpClientRequest> delete(String host, int port, String path);
deleteUrl()#
Opens an HTTP connection using the DELETE method.
The URL to use is specified in url.
See openUrl for details.
Implementation
Future<HttpClientRequest> deleteUrl(Uri url);
get()#
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
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
Future<HttpClientRequest> getUrl(Uri url);
head()#
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
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
Future<HttpClientRequest> headUrl(Uri url);
noSuchMethod() inherited#
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:
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:
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
@pragma("vm:entry-point")
@pragma("wasm:entry-point")
external dynamic noSuchMethod(Invocation invocation);
open()#
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
Future<HttpClientRequest> open(
String method,
String host,
int port,
String path,
);
openUrl()#
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
Future<HttpClientRequest> openUrl(String method, Uri url);
patch()#
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
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
Future<HttpClientRequest> patchUrl(Uri url);
post()#
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
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
Future<HttpClientRequest> postUrl(Uri url);
put()#
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
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
Future<HttpClientRequest> putUrl(Uri url);
toString() inherited#
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
external String toString();
Operators#
operator ==() inherited#
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 == omust be true.-
Symmetric: For all objects
o1ando2,o1 == o2ando2 == o1must either both be true, or both be false. -
Transitive: For all objects
o1,o2, ando3, ifo1 == o2ando2 == o3are true, theno1 == o3must 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
external bool operator ==(Object other);
Static Properties#
enableTimelineLogging read / write#
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
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()#
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:
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.
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.
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
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#
Implementation
static const int defaultHttpPort = 80;
defaultHttpsPort#
Implementation
static const int defaultHttpsPort = 443;