std.net.http.client.Client
type pub ClientAn HTTP client for sending requests and parsing their responses.
A Client transparently supports both HTTP and HTTPS connections.
Constructing a Client is considered to be somewhat expensive due to the
various data structures it needs to set up (e.g. TLS configuration, a
connection pool, etc). It's best to do this once and reuse the Client as
much as possible.
Requests are built using methods such as Client.get, Client.post or
Client.put. These methods return a Request, used for constructing
the request (e.g. setting the headers, body, etc). For example, to send a GET
request:
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
let req = client.get(uri)
let resp = req.send.or_panic
let body = ByteArray.new
# Read the entire response and panic upon encountering an error.
let _ = resp.body.read_all(body).or_panic
Refer to the documentation of these methods and the Request type for
more details.
TLS configuration
The configuration for TLS clients is stored in the Client.tls field. By
default the system certificate store is used. To use a custom certificate,
use std.net.tls.ClientConfig.with_certificate to create a custom client
configuration object and assign it to the Client.tls field:
import std.net.http.client (Client)
import std.net.tls (ClientConfig)
let client = Client.new
client.tls = ClientConfig
.with_certificate(...)
.or_panic_with('the certificate is invalid')
Default User-Agent header
The default value for the User-Agent header is inko/VERSION
(https://inko-lang.org) where VERSION is the version of Inko (e.g.
inko/1.2.3 (https://inko-lang.org)). It's highly recommended to use a
custom value instead. This can be changed by setting the field
Client.user_agent to a different value, or by setting the User-Agent
header to a custom value on a per-request basis.
Timeouts
A Client uses a timeout when connecting to a server and when sending
requests and parsing their responses. These timeouts are controlled by the
following fields:
Client.connect_timeoutClient.request_timeout
TCP keepalive
Each connection uses a custom set of TCP keepalive settings, controlled by the following fields:
Client.tcp_keepalive_timeClient.tcp_keepalive_interval
Both default to 15 seconds in an attempt to prevent idle reusable connections from being terminated prematurely.
Connection reuse
Connections are reused whenever possible, unless a server explicitly signals
that keep-alive conections aren't supported. By default the maximum number of
connections per host is limited to 5 connections. To disable keeping
connections alive, set this value to 0 using Client.connections_per_host=.
Connections can only be reused if the body of a response is consumed as a
whole. If any bytes remain available, the connection is terminated when a
Response is dropped.
Redirects
Redirects are followed when using Request.send or Request.body to send a
request. For more details, refer to the documentation of Request.body.
Basic authentication
If the URI to send a request to includes the user info component (i.e.
https://user:pass@host), this component is used to set the Authorization
header before sending a request, unless a custom Authorization header is
already specified. For example:
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri
.parse('https://user:pass@httpbun.com/basic-auth/user/pass')
.or_panic
let resp = client.get(uri).send.or_panic
let body = ByteArray.new
let _ = resp.body.read_all(body).or_panic
body.to_string
The output of this is:
{
"authenticated": true,
"user": "user"
}
By default this header is removed when redirecting to a different host. This
can be disabled by setting Client.remove_authorization_for_different_host to
false.
Websockets
A Client supports establishing a WebSocket connection, using the schemes
ws, wss, http and https. To create such a connection, use
Client.websocket to create a WebsocketRequest, then call
WebsocketRequest.send to send the request and establish the connection:
import std.net.http.client (Client)
import std.uri (Uri)
type async Main {
fn async main {
let client = Client.new
let uri = Uri.parse('https://echo.websocket.org').or_panic
let (sock, _response) = client.websocket(uri).send.or_panic
let _ = sock.receive.or_panic
let _ = sock.text('hello').or_panic
sock.receive.or_panic # => Message.Text('hello')
}
}
Fields
random
let pub @random: RandomThe random number generator to use when generating multipart form boundaries.
tls
let pub @tls: Option[ClientConfig]The TLS configuration to use for client connections.
When set to an Option.None, the TLS configuration is lazily initialized
the first time an HTTPS request is performed. If this fails (i.e. there are
no certificates to use), an Error.InvalidTlsConfig error is produced.
This defaults to an Option.None.
limits
let pub @limits: LimitsLimits to apply when parsing responses.
user_agent
let pub @user_agent: StringThe value to use for the User-Agent header.
connect_timeout
let pub @connect_timeout: DurationThe timeout to apply when connecting to a server.
This defaults to 5 seconds.
request_timeout
let pub @request_timeout: DurationThe timeout to apply when sending a request and parsing its response.
This defaults to 15 seconds.
tcp_keepalive_time
let pub @tcp_keepalive_time: DurationThe time after which an idle connection should start sending TCP keepalive messages.
This defaults to 15 seconds.
tcp_keepalive_interval
let pub @tcp_keepalive_interval: DurationThe interval at which TCP keepalive messages should be sent.
This defaults to 15 seconds.
max_redirects
let pub @max_redirects: IntThe maximum number of redirects to follow when performing a GET, HEAD, OPTIONS or TRACE request.
This defaults to 5. Setting this to zero disables the following of redirects entirely.
remove_authorization_for_different_host
let pub @remove_authorization_for_different_host: BoolIf the Authorization header used for basic authentication should be
removed when redirecting to a different host.
This is enabled by default to ensure basic authentication details aren't leaked by accident.
base_uri
let pub @base_uri: Option[Uri]A base URI to use for all requests.
The components of this base URI are merged with the target URI, overwriting the components in the target URI. This means that if this base URI has a host set, it always overwrites the host of the request URI.
The purpose of this field is to force requests to use certain components (e.g. the hostname) regardless of what the original URI contains. This in turn makes it possible to test client by setting this field to a host+port combination of some test specific HTTP server.
Static methods
new
Show source codeHide source code
fn pub static new -> Self {
Self(
random: Random.new,
tls: Option.None,
dns: dns.Resolver.new,
connections: Pool.new,
user_agent: USER_AGENT,
limits: Limits.new,
connect_timeout: Duration.from_secs(5),
request_timeout: Duration.from_secs(15),
tcp_keepalive_time: Duration.from_secs(15),
tcp_keepalive_interval: Duration.from_secs(15),
max_redirects: 5,
remove_authorization_for_different_host: true,
base_uri: Option.None,
buffer: ByteArray.new,
)
}fn pub static new -> ClientReturns a new Client with its default configuration.
Instance methods
connections_per_host=
Show source codeHide source code
fn pub mut connections_per_host=(value: Int) {
@connections.limit = value
}fn pub mut connections_per_host=(value: Int)Sets maximum number of connections to keep alive per scope.
This defaults to 5 connections per host. Setting this to zero disables keeping connections alive.
delete
Show source codeHide source code
fn pub mut delete(uri: Uri) -> Request {
request(Method.Delete, uri)
}fn pub mut delete(uri: Uri) -> RequestReturns a Request for sending a DELETE request.
Examples
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.delete(uri)
get
Show source codeHide source code
fn pub mut get(uri: Uri) -> Request {
request(Method.Get, uri)
}fn pub mut get(uri: Uri) -> RequestReturns a Request for sending a GET request.
Examples
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.get(uri)
head
Show source codeHide source code
fn pub mut head(uri: Uri) -> Request {
request(Method.Head, uri)
}fn pub mut head(uri: Uri) -> RequestReturns a Request for sending a HEAD request.
Examples
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.head(uri)
post
Show source codeHide source code
fn pub mut post(uri: Uri) -> Request {
request(Method.Post, uri)
}fn pub mut post(uri: Uri) -> RequestReturns a Request for sending a POST request.
Examples
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.post(uri)
put
Show source codeHide source code
fn pub mut put(uri: Uri) -> Request {
request(Method.Put, uri)
}fn pub mut put(uri: Uri) -> RequestReturns a Request for sending a PUT request.
Examples
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.put(uri)
request
Show source codeHide source code
fn pub mut request(method: Method, uri: Uri) -> Request {
Request.new(self, method, uri)
}fn pub mut request(method: Method, uri: Uri) -> RequestReturns a Request using the request method and URI.
Examples
import std.net.http (Method)
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.request(Method.Get, uri)
websocket
Show source codeHide source code
fn pub mut websocket(uri: Uri) -> WebsocketRequest {
WebsocketRequest.new(get(uri))
}fn pub mut websocket(uri: Uri) -> WebsocketRequestReturns a WebsocketRequest for establishing a WebSocket connection.
Examples
import std.net.http.client (Client)
import std.uri (Uri)
let client = Client.new
let uri = Uri.parse('https://example.com').or_panic
client.websocket(uri)