Client
HTTP client for making web requests.
Constructor
Client ... func?
Warning
unix_socket is not container-transparent. It connects to a Unix socket on
the host where the Do process is running, not through the shell agent's
container filesystem/network translation layer.
Parameters
| Name | Type | Description |
|---|---|---|
unix_socket |
Str |
Path to a Unix domain socket to connect through (Unix only) |
proxy |
Str|url.Url|nil |
Proxy URL for all requests, or nil to disable system proxy |
cookies |
Bool |
Enable a per-client cookie jar for session-style workflows |
ca_cert |
Str|Bin |
PEM-encoded CA certificate to add to the trust store |
identity |
Str|Bin |
PKCS#12/PFX client certificate for mutual TLS |
password |
Str |
Password for the PKCS#12 identity (defaults to empty) |
invalid_certs |
:DANGER_ACCEPT: |
Pass :DANGER_ACCEPT: to disable TLS certificate validation |
func |
func | Callable to run with the client; auto-closes when done |
Returns
Client when no func is provided, otherwise the result of
calling func
Proxy
By default, the client respects system proxy environment variables
(HTTP_PROXY, HTTPS_PROXY, NO_PROXY). Pass proxy: to set an explicit
proxy or proxy: nil to disable proxy detection entirely.
# Explicit proxy
let client = Client proxy: "http://proxy.corp:8080"
# Disable system proxy
let client = Client proxy: nil
Cookies
Pass cookies: true to enable automatic storage and replay of cookies on that
client instance. Cookie state is isolated per client and is not shared with the
top-level http.get / http.post helpers.
let client = Client cookies: true
client.post https://example.com/login
client.get https://example.com/dashboard do |resp|
echo $resp.status
TLS Certificates
Use ca_cert: to trust an additional CA certificate (PEM format), and
identity: with password: for client certificate authentication (PKCS#12/PFX
format).
# Custom CA certificate
let client = Client ca_cert: (fs.read /path/to/ca.pem)
# Client certificate authentication
let client = Client
identity: (fs.read /path/to/client.pfx)
password: secret
Disabling Certificate Validation
Pass invalid_certs: :DANGER_ACCEPT: to disable TLS certificate validation.
This is dangerous and should only be used for testing.
Methods
get | post | ...
get url :headers? :query? :status? block?
head ...
delete ...
options ...
trace ...
connect ...
post url :headers? :body? :json? :lines? :multipart? :query? :status? block?
put ...
patch ...
Makes an HTTP request using the specified verb.
Parameters
| Name | Type | Description |
|---|---|---|
url |
Str |
The URL to request |
body |
Str|Bin|input |
Request body; accepts iterables for streaming |
json |
any | Request body as JSON value (auto-serialized) |
lines |
input | Stream request body with newlines between elements |
multipart |
input | Multipart/form-data parts |
headers |
Dict |
Dictionary of headers; repeated keys are accepted |
query |
Dict |
Dictionary of query parameters; repeated keys are accepted |
status |
:IGNORE:|"IGNORE" |
Return the response even when the status is outside 200-299 |
block |
func | Called with response; response is closed upon return or error |
Returns
Response -- The HTTP response
Errors
| Exception | Condition |
|---|---|
Status |
The response is non-2xx and status: is not provided |
Error |
A transport or protocol failure occurs |
let client = Client()
let response = client.get https://api.example.com/users
query: {page: 1 limit: 10}
headers: {authorization: "Bearer token123"}
echo $response.status
let response = client.post https://api.example.com/users
json:
name: Alice
age: 30
To keep the old behavior and inspect non-2xx responses directly, pass
status: :IGNORE::
let response = client.get https://api.example.com/missing
status: :IGNORE:
assert_eq $response.status 404
Request Options
body
Specifies the raw request body. Cannot be used together with json, lines,
or multipart.
When a string or binary value is passed, it is sent as-is. When an iterable is passed, the values are streamed directly to the request body without adding any delimiters.
# Direct string body
let response = client.post https://api.example.com/data
body: "raw text data"
headers: {"content-type": "text/plain"}
# Streaming without delimiters (useful for binary data)
let response = client.post https://api.example.com/stream
body: ["chunk1", "chunk2", "chunk3"]
headers: {"content-type": "application/octet-stream"}
json
Specifies the request body as a Do value that will be automatically serialized
to JSON. Cannot be used together with body, lines, or multipart.
let response = client.post https://api.example.com/users
json: {name: "Alice", email: "alice@example.com"}
lines
Streams the request body from an iterable, adding a newline after each element.
Cannot be used together with body, json, or multipart. Unlike body
which accepts any value, lines requires an iterable.
let response = client.post https://api.example.com/data
lines:
- first line
- second line
- third line
# Sends: "first line\nsecond line\nthird line\n"
multipart
Builds a multipart/form-data request body from an iterable of part specs.
Cannot be used together with body, json, or lines.
Each part must provide name and either body or, when the HTTP extension is
built with its json feature, json. filename and content_type are
optional.
let response = client.post https://api.example.com/upload
multipart:
- name: file
filename: report.txt
content_type: text/plain
body: b"report contents"
- name: metadata
json:
kind: report
Multipart part bodies accept:
Strfor text fieldsBinfor binary fields- iterable/input values for streaming uploads such as files opened in binary mode
When a part uses json:, the value is serialized the same way as a top-level
request json: body. The part content_type defaults to application/json
if omitted.
The request sets the multipart content-type header automatically, including
the boundary parameter. Do not set content-type manually on multipart
requests.
import fs:
- open
open report.bin rb do |file|
client.post https://api.example.com/upload
multipart:
- name: file
filename: report.bin
content_type: application/octet-stream
body: $file
Binary file mode matters here: text-mode file iteration is line-oriented, while binary mode yields raw chunks suitable for uploads.
headers
Specifies request headers as a dictionary. Duplicate header names can be specified by repeating keys.
Header values are normally stringified. If a value is a
DateTime, it is formatted as an HTTP-date
(IMF-fixdate), which is useful for headers such as If-Modified-Since.
let response = client.get https://api.example.com/users
headers:
authorization: Bearer token123
"user-agent": MyApp/1.0
accept: application/json
accept: application/json+verbose
import time:
- DateTime
let response = client.get https://api.example.com/archive
headers:
"if-modified-since": DateTime.from_unix(1700000000)
status: :IGNORE:
query
Specifies URL query parameters as a dictionary. Duplicate parameter names can be specified by repeating keys.