6.50. kink/http/HTTP

6.50.1. type http

`http` is an HTTP client.

6.50.1.1. Http.send(Req ...[$config={}])

`send` method sends a request and receives a response.

Config methods:

• C.stream_resp

• C.timeout(Timeout_seconds)

• C.follow_redirect

• C.on_success($success): default = VAL.identity

• C.on_error($error): default = {(:Exc) Exc.raise }

Timeout

If C.timeout is called, the invocation of `send` times out after `Timeout_seconds` seconds. If `send` times out, it causes an IO error.

Result

If the client receives a response with no IO error, `send` tail-calls $success with a `resp` value `Resp`. If C.stream_resp is called, the `Resp.content.have_bin?` will be false, and `Resp` needs to be closed. If C.stream_resp is not called, the `Resp.content.have_bin?` will be true, and `Resp` does not need to be closed.

If an IO error occurs, `send` tail-calls $error with an `exception`.

Redirects

If C.follow_redirect is called, `send` performs redirects, in a similar way as `HTTP-redirect fetch` of Fetch API:

https://fetch.spec.whatwg.org/#http-redirect-fetch

Preconditions

`Req` must be a `req`.

`Req.headers` must not include headers which control routing and messaging, like Content-Length and Expect.

`Timeout_seconds` must be a positive `num` value.

$success must be a function which takes a `resp`.

$error must be a function which takes an `exception`.

6.50.2. HTTP.new(...[$config={}])

`new` returns a new `http` value.

Config method:

• C.tls_client(Tls_client): default = TLS_CLIENT.new(TRUST_ANCHOR.default)

• C.http_proxy(Http_proxy_uri)

• C.https_proxy(Https_proxy_uri)

• C.no_proxy(No_proxy_host): can be called multiple times

TLS

The result `http` will use `Tls_client` for HTTPS requests.

Proxies

If C.http_proxy is called, HTTP requests are sent to the proxy server with URI `Http_proxy_uri`.

If C.https_proxy is called, HTTPS requests are sent to the proxy server with URI `Https_proxy_uri`.

Proxies are not used when the host name of the request is specified by an invocation of C.no_proxy. The host name is compared simply by `str` equality. No normalization or name resolution is performed.

:HTTP.require_from('kink/http/')
:REQ.require_from('kink/http/')

:Http <- HTTP.new{(:C)
  C.http_proxy('http://proxy.example.org:8080')
  C.no_proxy('127.0.0.1')
  C.no_proxy('[::1]')
}

Http.send(REQ.new('GET' 'http://[::1]'))
# => proxy is skipped

Http.send(REQ.new('GET' 'http://[::0:0:1]'))
# => proxy is used, because ip address normalizaion is not performed

Http.send(REQ.new('GET' 'http://localhost'))
# => proxy is used, because name resolution is not performed

Precondition

`Tls_client` must be a `tls_client` value.

`Http_proxy_uri` must be a `str` of an http or https URI defined in [RFC 9110 - 4.2.1, 4.2.2], in the format of `http://{Host}:{Port}` or `https://{Host}:{Port}`.

`Https_proxy_uri` must be a `str` of an http or https URI defined in [RFC 9110 - 4.2.1, 4.2.2], in the format of `http://{Host}:{Port}` or `https://{Host}:{Port}`.

`No_proxy_host` must be a `str`.

6.50.3. HTTP.is?(Val)

`is?` returns whether `Val` is an `http` value.