Skip to content
Jennifer Programming Language

http API reference

An HTTP/1.1 client over the net system library. Build a request (method, URL, headers, body), send it, and read the response back into a Response (status, headers, body). http:// connects in the clear; https:// connects with TLS (net.connectTLS). The one-shot verbs (get / post / request / ...) use one connection per request (Connection: close); connect / exchange reuse a persistent connection to one origin (keep-alive) so a request loop pays a single handshake. send adds a request policy on top of the one-shot path: automatic 3xx redirect-following, retry / backoff on 429 / 5xx, and a cookie jar across the redirect chain. Because it uses net, this module needs the default jennifer binary. A text Response body is decoded as UTF-8 (a binary body raises an error; use requestBytes / getBytes for that). Chunked and Content-Length framing are both handled.

Import with import "http.j" as http;. See the http guide for prose and examples.

Functions

http.basic(user as string, pass as string)

Build an Authorization value for HTTP Basic auth (base64 of "user:password"), to pass as a request header. Mirrors rest.basic.

Parameters

  • user {string} - the username
  • pass {string} - the password

Returns {string} - the "Basic <base64>" header value

http.close(session as Session)

Close a session's connection. Idempotent-safe to call once; do not use the session afterwards.

Parameters

  • session {Session} - the session to close

http.connect(url as string, options as Options)

Open a persistent connection to the origin of url (its scheme / host / port; the path is ignored - exchange supplies per-request paths). The socket is reused across exchange calls to the same origin, so a request loop pays one handshake instead of N.

Parameters

  • url {string} - a URL whose origin to connect to
  • options {Options} - the request options (timeout, cap, tls)

Returns {Session} - an open session

Throws

  • {Error} - kind "http" (or a net error) if the connection cannot be opened

http.defaultOptions()

The zero Options (default timeout / cap, verified TLS, no redirects, no retries), for inline use: http.send(m, u, {}, "", http.defaultOptions()). Set fields on the result to opt into behaviour.

Returns {Options} - the default options

http.delete(url as string, headers as map of string to string)

Issue a DELETE request.

Parameters

  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)

Returns {Response} - the parsed response

http.exchange(session as Session, method as string, path as string, headers as map of string to string, body as string)

Send one request over a session's reused connection and return the response plus the updated session (reassign it: def x as http.Exchange init http.exchange($s, ...); $s = $x.session;). path is a request target on the session's origin (e.g. "/items?page=2"). Cookies from the response are folded into the session jar and replayed on later requests. If the connection was closed (by a prior Connection: close or a to-EOF response), it is transparently reopened. Redirects are not followed here (that can cross origins and break the socket) - use send for redirect-following; exchange returns the 3xx.

Parameters

  • session {Session} - the session (from connect or a prior exchange)
  • method {string} - the HTTP method
  • path {string} - the request path on the session's origin
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for none)

Returns {Exchange} - the response and the session to thread onward

Throws

  • {Error} - kind "http" on a malformed response or a cap breach, "read timed out" on timeout

http.get(url as string, headers as map of string to string)

Issue a GET request.

Parameters

  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)

Returns {Response} - the parsed response

http.getBytes(url as string, headers as map of string to string)

GET a URL and return its body as raw bytes (the download shortcut).

Parameters

  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)

Returns {BytesResponse} - the response with a raw bytes body

http.head(url as string, headers as map of string to string)

Issue a HEAD request (status and headers, no body).

Parameters

  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)

Returns {Response} - the parsed response (empty body)

http.header(resp as Response, name as string)

Read a response header by name, case-insensitively.

Parameters

  • resp {Response} - the response to read from
  • name {string} - the header name (case-insensitive)

Returns {string} - the header value, or "" if absent

http.options(url as string, headers as map of string to string)

Issue an OPTIONS request (capability probe; read the Allow header).

Parameters

  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)

Returns {Response} - the parsed response

http.patch(url as string, contentType as string, body as string, headers as map of string to string)

Issue a PATCH request (a partial update) with contentType and body.

Parameters

  • url {string} - the absolute request URL
  • contentType {string} - the Content-Type header value
  • body {string} - the request body
  • headers {map of string to string} - extra request headers ({} for none)

Returns {Response} - the parsed response

http.post(url as string, contentType as string, body as string, headers as map of string to string)

Issue a POST request with contentType and body.

Parameters

  • url {string} - the absolute request URL
  • contentType {string} - the Content-Type header value
  • body {string} - the request body
  • headers {map of string to string} - extra request headers ({} for none)

Returns {Response} - the parsed response

http.put(url as string, contentType as string, body as string, headers as map of string to string)

Issue a PUT request with contentType and body.

Parameters

  • url {string} - the absolute request URL
  • contentType {string} - the Content-Type header value
  • body {string} - the request body
  • headers {map of string to string} - extra request headers ({} for none)

Returns {Response} - the parsed response

http.request(method as string, url as string, headers as map of string to string, body as string)

Send one HTTP request and return the response (with the default idle timeout).

Parameters

  • method {string} - the HTTP method (e.g. "GET", "POST")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for no body)

Returns {Response} - the parsed response

Throws

  • {Error} - kind "http" if the response is malformed, or a "read timed out" error on timeout

http.requestBytes(method as string, url as string, headers as map of string to string, body as string)

Send one request and return a raw-bytes BytesResponse (default idle timeout, default 64 MiB cap, full TLS verification). The binary counterpart to request; for a large download or a self-signed host use requestWithBytes.

Parameters

  • method {string} - the HTTP method (e.g. "GET")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for no body)

Returns {BytesResponse} - the response with a raw bytes body

Throws

  • {Error} - kind "http" if the response is malformed or exceeds the cap, or a "read timed out" error on timeout

http.requestRawBody(method as string, url as string, headers as map of string to string, body as bytes, timeoutMs as int, maxBytes as int)

Send one request with a raw bytes body and return the text Response. Unlike requestWith (whose string body is UTF-8-encoded onto the wire), the body here is written byte-for-byte, so a binary payload - a multipart/form-data file upload, a protobuf - is transmitted intact. The response is still parsed as text (use requestWithBytes if the response may be non-UTF-8).

Parameters

  • method {string} - the HTTP method (e.g. "POST")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers (set your own Content-Type)
  • body {bytes} - the raw request body
  • timeoutMs {int} - the per-read idle timeout in milliseconds (0 = none)
  • maxBytes {int} - the response-body cap (0 = 64 MiB default, negative = unlimited)

Returns {Response} - the parsed response

Throws

  • {Error} - kind "http" on a malformed response or a cap breach; "read timed out" on timeout

http.requestRawBodyTls(method as string, url as string, headers as map of string to string, body as bytes, timeoutMs as int, maxBytes as int, tls as TlsOptions)

requestRawBody with explicit TLS options for an https:// server (a self-signed or private-CA host). For http:// the options are ignored.

Parameters

  • method {string} - the HTTP method
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers
  • body {bytes} - the raw request body
  • timeoutMs {int} - the per-read idle timeout in milliseconds (0 = none)
  • maxBytes {int} - the response-body cap (0 = default, negative = unlimited)
  • tls {TlsOptions} - certificate-verification options for the TLS handshake

Returns {Response} - the parsed response

Throws

  • {Error} - kind "http" on a malformed response or a cap breach; "read timed out" on timeout

http.requestTls(method as string, url as string, headers as map of string to string, body as string, tls as TlsOptions)

Send one request with explicit TLS options (default idle timeout and body cap). The https-with-a-self-signed-cert shortcut over requestWithTls.

Parameters

  • method {string} - the HTTP method (e.g. "GET", "POST")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for no body)
  • tls {TlsOptions} - certificate-verification options for the TLS handshake

Returns {Response} - the parsed response

Throws

  • {Error} - kind "http" if the response is malformed, or a "read timed out" error on timeout

http.requestWith(method as string, url as string, headers as map of string to string, body as string, timeoutMs as int, maxBytes as int)

Send one HTTP request with an explicit idle timeout and body cap, returning the response. timeoutMs bounds each read (a stalled server fails rather than hanging); 0 disables it. maxBytes caps the response body: 0 uses the 64 MiB default (MAX_BODY_BYTES, which protects against an untrusted server streaming to OOM), a negative value lifts the cap (for a trusted large download), and a positive value sets an exact ceiling. request and the verb shortcuts use DEFAULT_TIMEOUT_MS and the default cap.

Parameters

  • method {string} - the HTTP method (e.g. "GET", "POST")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for no body)
  • timeoutMs {int} - the per-read idle timeout in milliseconds (0 = none)
  • maxBytes {int} - the response-body cap (0 = 64 MiB default, negative = unlimited, positive = exact)

Returns {Response} - the parsed response

Throws

  • {Error} - kind "http" if the response is malformed or exceeds maxBytes, or a "read timed out" error on timeout

http.requestWithBytes(method as string, url as string, headers as map of string to string, body as string, timeoutMs as int, maxBytes as int, tls as TlsOptions)

Send one request and return the body as raw bytes (a BytesResponse) - the byte-safe path for downloading binary content (a .tar.gz, an image) that a UTF-8 text Response cannot hold. Explicit per-read idle timeout and body cap; pass a negative maxBytes for an unbounded download (a large release archive), or TlsOptions for a self-signed / private-CA https:// host.

Parameters

  • method {string} - the HTTP method (e.g. "GET")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for no body)
  • timeoutMs {int} - the per-read idle timeout in milliseconds (0 = none)
  • maxBytes {int} - the response-body cap (0 = 64 MiB default, negative = unlimited, positive = exact)
  • tls {TlsOptions} - certificate-verification options for the TLS handshake

Returns {BytesResponse} - the response with a raw bytes body

Throws

  • {Error} - kind "http" if the response is malformed or exceeds maxBytes, or a "read timed out" error on timeout

http.requestWithTls(method as string, url as string, headers as map of string to string, body as string, timeoutMs as int, maxBytes as int, tls as TlsOptions)

Like requestWith, but with explicit TLS options for an https:// URL (a self-signed or private-CA server). For http:// the options are ignored.

Parameters

  • method {string} - the HTTP method (e.g. "GET", "POST")
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for no body)
  • timeoutMs {int} - the per-read idle timeout in milliseconds (0 = none)
  • maxBytes {int} - the response-body cap (0 = 64 MiB default, negative = unlimited, positive = exact)
  • tls {TlsOptions} - certificate-verification options for the TLS handshake

Returns {Response} - the parsed response

Throws

  • {Error} - kind "http" if the response is malformed or exceeds maxBytes, or a "read timed out" error on timeout

http.send(method as string, url as string, headers as map of string to string, body as string, options as Options)

Send a request with a policy: follow up to options.maxRedirects 3xx redirects, retry a 429 / 5xx up to options.maxRetries with exponential backoff (honouring a numeric Retry-After), and carry cookies across the redirect chain. A 303 (and a 301/302 on a POST) becomes a bodyless GET; 307/308 preserve the method and body. With a zero Options it is a one-shot request, exactly like request.

Parameters

  • method {string} - the HTTP method
  • url {string} - the absolute request URL
  • headers {map of string to string} - request headers ({} for none)
  • body {string} - the request body ("" for none)
  • options {Options} - the request policy

Returns {Response} - the final response (after any redirects / retries)

Throws

  • {Error} - kind "http" on a malformed response or a body-cap breach, "read timed out" on timeout

Structs

http.BytesResponse

A response with a raw bytes body - the byte-safe counterpart to Response, for downloading binary payloads (a .tar.gz, an image, any non-text content) that a UTF-8 string body cannot hold. Returned by requestBytes / requestWithBytes / getBytes. headers keys are lowercased (read $r.headers["content-type"] directly, or with http.header after wrapping - the map is shared shape with Response).

FieldTypeDescription
statusintthe numeric status code
statusTextstringthe reason phrase from the status line
headersmap of string to stringresponse headers, keys lowercased
bodybytesthe response body, exactly as received (no decoding)

http.Exchange

The result of an exchange: the response, and the updated session to thread into the next exchange (it carries the reused socket and any new cookies).

FieldTypeDescription
responseResponsethe response
sessionSessionthe session to use for the next request

http.Options

Per-request policy for send and a persistent Session. The zero value (from http.defaultOptions() or def o as http.Options;) is the safe default: the standard timeout and body cap, TLS fully verified, and no redirect-following or retrying (so a bare send behaves like request). Opt into a behaviour by setting its field.

FieldTypeDescription
timeoutMsintper-read idle timeout (0 = 30s default, as request)
maxBytesintresponse-body cap (0 = 64 MiB default, negative = unlimited)
maxRedirectsinthow many 3xx redirects to follow (0 = none; the 3xx is returned)
maxRetriesinthow many times to retry a 429 / 5xx (0 = none), with exponential backoff honouring Retry-After
backoffMsintbase backoff for the first retry (0 = 250ms), doubled each attempt and capped at 30s
tlsTlsOptionsTLS verification options for https:// (zero = full verification)
allowCrossOriginRedirectboolkeep credential headers / cookies across a redirect to a different origin (default false = drop them, the browser rule)

http.Response

An HTTP response. headers keys are lowercased (HTTP header names are case-insensitive); use http.header for a case-insensitive read.

FieldTypeDescription
statusintthe numeric status code (e.g. 200, 404)
statusTextstringthe reason phrase from the status line
headersmap of string to stringresponse headers, keys lowercased
bodystringthe response body decoded as UTF-8 text

http.Session

A persistent HTTP connection to one origin (scheme + host + port), holding the reused socket, a cookie jar, and the request options. Value-semantic, but the conn handle is shared across copies (a net.Conn), so the live socket survives being threaded through exchange. Build with connect; retire with close.

FieldTypeDescription
connnet.Connthe underlying socket (shared across copies)
schemestring"http" or "https"
hoststringthe origin host
portintthe origin port
openboolwhether conn is currently usable (false after the server closed it)
jarmap of string to stringthe accumulated cookies (name -> value)
optionsOptionsthe request options (timeout, cap, tls)

http.TlsOptions

TLS options for an https:// request, mirroring net.TLSOptions. The zero value (skipVerify false, empty caCert) full-verifies the server certificate against the URL host, which is what a plain request / verb shortcut uses - so an https:// call with no options behaves exactly as before.

FieldTypeDescription
skipVerifyboolaccept any certificate (self-signed, wrong host, expired). Opt-in; disables authentication and exposes the connection to a man-in-the-middle. Use only for a trusted LAN endpoint you cannot give a proper CA.
caCertbytesa PEM certificate to trust in addition to the system roots, for a private CA or a pinned self-signed cert. The safer alternative to skipVerify: the server is still authenticated, just against this cert.