Core API

    Core Messages and Errors

    HTTP.Request — Type
    Request(method, target; headers=Headers(), body=nothing, trailers=Headers(),
            host=nothing, content_length=-1, proto_major=1, proto_minor=1,
            close=false, context=RequestContext(), copyheaders=true)
    Request(method, target, headers[, body])

    An HTTP request: what a server handler receives, and what the client sends.

    • headers, trailers: anything Headers accepts. They are copied unless copyheaders = false and they are Headers collections; the request then uses them directly, so do not touch them while the request is in use.
    • body: a String, a byte vector, an AbstractBody, or nothing.
    • host: the authority sent as the HTTP/1 Host header or HTTP/2 :authority.
    • content_length: the body length in bytes. -1 computes it for a String, byte-vector, or empty body, and means unknown for other bodies.
    • proto_major, proto_minor: the HTTP version.
    • close: close the connection after this request.
    • context: the request's RequestContext.

    req.context returns the context's application data as a Dict{Symbol,Any}; use get_request_context for the RequestContext itself.

    source
    HTTP.Response — Type
    Response(status, [body]; headers=Headers(), reason="", trailers=Headers(),
             content_length=-1, proto_major=1, proto_minor=1, close=false,
             request=nothing)
    Response(status, headers, body)
    Response(body)

    An HTTP response: what a server handler returns, and what the client returns.

    body, passed by position or as a keyword, may be a String, a byte vector, an AbstractBody, or nothing. A String or byte vector is stored as is, so one Response can be returned for many requests. content_length defaults to the length of such a body. request is the request that produced the response. Response(body) uses status 200.

    A client response also has response.url, the final URL after redirects.

    source
    HTTP.Headers — Type
    Headers()
    Headers(items)
    Headers(pairs...; kwargs...)

    An ordered vector of String => String header pairs.

    Header names match in any case (RFC 9110 §5.1): header, setheader, removeheader, haskey, and the other lookups ignore case, and each name keeps the spelling it was stored with. HTTP/1 sends names in that spelling; HTTP/2 sends them in lowercase. Headers read from the network are stored in canonical_header_key form, such as Content-Type, so a response looks the same over HTTP/1 and HTTP/2.

    items may be a vector, dictionary, or tuple of pairs, and keyword arguments add more headers. The input is copied, and a header with the same name as the one before it is joined onto it, as in appendheader. Headers(n::Integer) returns an empty collection with room for n headers.

    source
    HTTP.RequestContext — Type
    RequestContext(; deadline_ns=0)

    Cancellation, deadline, and application data for one request. Pass one to a client call with the context keyword; get_request_context returns the context of a request a server is handling.

    deadline_ns is an absolute time_ns() value, or 0 for no deadline. A client request still running at the deadline throws TimeoutError, and cancel! makes it throw CanceledError.

    Application data is stored under Symbol keys:

    ctx = HTTP.RequestContext()
    ctx[:request_id] = "abc"
    get(ctx, :request_id, nothing)
    source
    HTTP.HTTPError — Type
    HTTPError

    Abstract supertype for HTTP-specific exceptions raised by HTTP.jl.

    source
    HTTP.ParseError — Type
    ParseError

    Raised when byte-level HTTP syntax cannot be parsed. This is used for malformed request/status lines, invalid header syntax, truncated framed bodies, and other wire-format failures where the peer did not send valid HTTP.

    source
    HTTP.ProtocolError — Type
    ProtocolError

    Raised when the bytes are syntactically valid but violate higher-level HTTP rules. Examples include mismatched Content-Length values, impossible frame ordering, or unsupported control-flow states in the client/server stacks.

    source
    HTTP.CanceledError — Type
    CanceledError

    Raised when request processing is canceled explicitly through RequestContext. Unlike ParseError and ProtocolError, this usually reflects local control flow rather than a bad peer.

    source
    HTTP.TimeoutError — Type
    TimeoutError

    Raised when a client timeout or deadline expires.

    Fields:

    • operation::String: "connect" or "tls_handshake" when connect_timeout expired, "websocket handshake" for a WebSocket handshake, and "request" for the other timeouts and for deadlines.
    • timeout_ns::Int64: the timeout that expired, in nanoseconds, or 0 when it is not known.
    • elapsed_ns::Int64: the time spent before it expired, in nanoseconds, or 0 when it is not known.
    source
    HTTP.StatusError — Type
    StatusError

    Raised by request and the verb helpers for a response with status 300 or above that is not a redirect, unless status_exception = false.

    Fields:

    • status::Int16: the response status.
    • response::Response: the response, including its body.
    source
    HTTP.TooManyRedirectsError — Type
    TooManyRedirectsError

    Raised when a request reaches its redirect limit and gets another redirect. limit is the limit and response is the last redirect response.

    source
    HTTP.ConnectError — Type
    ConnectError(address, cause)

    Raised when the client cannot connect to address (host:port). cause is the underlying exception.

    source
    HTTP.DNSError — Type
    DNSError(hostname, cause)

    Raised when the client cannot resolve hostname. cause is the underlying exception.

    source
    HTTP.TLSTransportError — Type
    TLSTransportError(cause)

    Raised when TLS-level I/O fails on an established connection during a request — for example a connection reset or a truncated TLS stream while writing the request or reading the response. cause is the underlying Reseau.TLS.TLSError. TLS failures during connection setup surface as TLSHandshakeError (or TimeoutError for handshake timeouts) instead.

    source
    HTTP.AddressInUseError — Type
    AddressInUseError(address)

    Raised when a server cannot bind because the requested address is already in use. address records the bind target (host:port).

    source

    Header and Context Helpers

    HTTP.canonical_header_key — Function
    canonical_header_key(key) -> String

    Return the header name key in canonical form, such as Content-Type: the first letter and every letter after a - are uppercase, and the other ASCII letters are lowercase. key is not checked for validity.

    source
    HTTP.header — Function
    header(headers, key, default="")
    header(message, key, default="")

    Return the first value of header key, or default if there is none. key matches in any case. message is a Request or Response.

    source
    HTTP.headers — Function
    headers(headers, key) -> Vector{String}
    headers(message, key) -> Vector{String}

    Return every value of header key, in order, or String[] if there is none.

    source
    HTTP.hasheader — Function
    hasheader(headers, key) -> Bool
    hasheader(message, key) -> Bool

    Return true when header key is present and its first value is not empty.

    source
    hasheader(headers, key, value) -> Bool

    Return true when any stored header value for key matches value case-insensitively.

    source
    HTTP.headercontains — Function
    headercontains(headers, key, token) -> Bool
    headercontains(message, key, token) -> Bool

    Return true when a value of header key, read as a comma-separated list, contains token. Both the name and the token match in any case. Use it for list-valued headers such as Connection and Transfer-Encoding.

    source
    HTTP.setheader — Function
    setheader(headers, key => value) -> headers
    setheader(headers, key, value) -> headers
    setheader(message, key => value) -> message

    Replace every value of header key with value. The header keeps the position of its first occurrence and takes the spelling of key; a new header goes at the end. setheader! is the same function.

    source
    setheader(stream, key, value) -> nothing
    setheader(stream, key => value) -> nothing

    Set a header of the response on a server stream. Call it before the first write; after that it throws ArgumentError.

    source
    HTTP.setheader! — Function
    setheader!(headers, key => value) -> headers
    setheader!(headers, key, value) -> headers
    setheader!(message, key => value) -> message

    The same function as setheader.

    source
    HTTP.defaultheader! — Function
    defaultheader!(headers, key => value) -> headers
    defaultheader!(message, key => value) -> message

    Add key => value unless header key is already present.

    source
    HTTP.appendheader — Function
    appendheader(headers, key => value) -> headers
    appendheader(headers, key, value) -> headers
    appendheader(message, key => value) -> message

    Add a header value. When the last header has the same name, in any case, the value is joined onto it instead: with "; " for Cookie (RFC 6265 §5.4) and with "," for other names (RFC 9110 §5.3). Set-Cookie values always become separate headers. appendheader! is the same function.

    source
    HTTP.appendheader! — Function
    appendheader!(headers, key => value) -> headers
    appendheader!(headers, key, value) -> headers
    appendheader!(message, key => value) -> message

    The same function as appendheader.

    source
    HTTP.removeheader — Function
    removeheader(headers, key) -> headers
    removeheader(message, key) -> message

    Remove every value of header key. removeheader! is the same function.

    source
    HTTP.mkheaders — Function
    mkheaders(headers_input) -> Headers

    Convert headers_input to Headers. It may be nothing, a pair or 2-tuple, a dictionary, or an iterable of pairs or 2-tuples. A Headers is returned as is, without a copy. Each value, including each element of a vector value, is added with appendheader, which joins it onto the previous header when the names match.

    source
    HTTP.get_request_context — Function
    get_request_context(request) -> RequestContext

    Return the RequestContext of request, which holds its cancellation state and deadline. request.context returns only the context's application data.

    source
    HTTP.set_deadline! — Function
    set_deadline!(ctx, deadline_ns) -> ctx

    Set the deadline of ctx to deadline_ns, an absolute time_ns() value. 0 removes the deadline.

    source
    HTTP.cancel! — Function
    cancel!(ctx; message="request canceled") -> ctx

    Cancel the request that uses ctx. Its current read or write stops, and the request throws a CanceledError carrying message. cancel! does not throw itself.

    source
    HTTP.expired — Function
    expired(ctx, now_ns=time_ns()) -> Bool

    Return true when ctx has a deadline and now_ns has reached it.

    source

    Body Types and Streamed Payloads

    HTTP.CallbackBody — Type
    CallbackBody(read_cb, close_cb)

    A body produced by a function. read_cb(dst::Vector{UInt8}) fills the start of dst and returns the number of bytes written, or 0 at the end of the body. close_cb() runs once, when the body is closed. A CallbackBody can be read only once.

    source
    HTTP.nobody — Constant

    An empty Vector{UInt8} to pass as a body that has no bytes. It is shared, so do not modify it.

    source
    HTTP.body_read! — Function
    body_read!(body, dst) -> Int

    Read up to length(dst) bytes of body into dst and return how many were read, or 0 at the end of the body.

    source
    HTTP.body_close! — Function
    body_close!(body)

    Close body and release what it holds. Closing a closed body does nothing, so it is safe to call in a finally block.

    source
    HTTP.read_request — Function
    read_request(io; max_line_bytes=64*1024, max_header_bytes=1024*1024) -> Request

    Read one HTTP/1 request head from io and return it as a Request whose body reads the rest of the request from io. max_line_bytes limits each line and max_header_bytes the whole head. Throws ParseError or ProtocolError for an invalid request.

    source
    HTTP.write_request! — Function
    write_request!(io, request)

    Write request to io in HTTP/1.1 format, with its body.

    The Host header comes first (RFC 9110 §7.2), taken from the request's Host header or else from request.host. A body of known length is sent with Content-Length, and any other body with chunked encoding, the only framing that carries trailers.

    source
    HTTP.write_response! — Function
    write_response!(io, response, request=response.request)

    Write response to io in HTTP/1.1 format, with its body. No body is written for 1xx, 204, and 304 responses, or when request is a HEAD request.

    source
    HTTP.trailers — Function
    trailers(body)

    Return a copy of the trailers that ended a chunked body, or empty Headers for other bodies. Read the body to the end first.

    source

    Cookies, Forms, and Request Bodies

    HTTP.Cookies.Cookie — Type
    Cookie(name, value; kwargs...)

    A cookie, as sent in a request's Cookie header or a response's Set-Cookie header. Set its other fields, such as path, domain, expires, maxage, secure, httponly, and samesite (:lax, :strict, or :none), with keywords.

    source
    HTTP.Cookies.CookieJar — Type
    CookieJar()
    CookieJar(entries::Dict{String, Dict{String, Cookie}})

    An in-memory cookie store for a Client or the cookiejar keyword of a request. It stores cookies from responses and picks the ones to send by their domain, path, expiry, and Secure flag.

    jar.entries holds the cookies, keyed by host. To keep cookies across sessions, save jar.entries and later pass it to CookieJar(entries), which uses the Dict without copying it.

    source
    HTTP.Cookies.cookies — Function
    cookies(request_or_response) -> Vector{Cookie}

    Return the cookies in a request's Cookie header or a response's Set-Cookie headers.

    source
    HTTP.Cookies.stringify — Function
    stringify(cookie, isrequest=true) -> String
    stringify(prefix, cookies, isrequest=true) -> String

    Format cookies as header text. With isrequest = true the result is name=value, as in a Cookie header; with false it also has the attributes of a Set-Cookie header, such as Path, Domain, and HttpOnly. The second form appends cookies to the header text prefix, separated by "; ".

    source
    HTTP.Cookies.getcookies! — Function
    getcookies!(jar, scheme, host, path[, now]) -> Vector{Cookie}

    Return the cookies from jar to send with a request to scheme://host/path.

    source
    HTTP.Cookies.setcookies! — Function
    setcookies!(jar, scheme, host, path, headers) -> nothing

    Store the Set-Cookie headers of a response from scheme://host/path in jar.

    source
    HTTP.Cookies.addcookie! — Function
    addcookie!(message, cookie) -> message

    Add cookie to the Cookie header of a Request, or as a new Set-Cookie header of a Response.

    source
    HTTP.Form — Type
    Form(parts; boundary, type=:formdata) <: IO

    A multipart request body. parts is a collection of name => value pairs. An IO value is streamed (an open file is sent with its file name, and a Multipart with its own name and content type); any other value is sent as string(value). type = :mixed builds a multipart/mixed body instead of multipart/form-data. A request with a Form body gets the matching Content-Type header from content_type.

    source
    HTTP.Multipart — Type
    Multipart(filename, data, contenttype="", contenttransferencoding="", name="") <: IO

    One part of a multipart body, with its content in the IO data. filename may be nothing, and an empty contenttype is detected from the data when the part is sent. The parse_multipart functions return Multiparts, and Form accepts them as values.

    source
    HTTP.Batch — Function
    Batch(parts; boundary) -> Form

    Build a multipart/mixed body, the format of batch APIs such as OData $batch. parts is a vector of Multiparts or a collection of name => value pairs, as for Form with type = :mixed.

    parts = [
        HTTP.Multipart(nothing, IOBuffer("GET /users/1 HTTP/1.1\r\n\r\n"), "application/http"),
        HTTP.Multipart(nothing, IOBuffer("GET /users/2 HTTP/1.1\r\n\r\n"), "application/http"),
    ]
    response = HTTP.post(url, [], HTTP.Batch(parts))
    source
    HTTP.content_type — Function
    content_type(form) -> String

    Return the Content-Type header value for form: multipart/form-data or multipart/mixed, with the boundary.

    source
    HTTP.parse_multipart_form — Function
    parse_multipart_form(content_type_header, body) -> Union{Vector{Multipart}, Nothing}
    parse_multipart_form(message) -> Union{Vector{Multipart}, Nothing}

    Parse a multipart/form-data body, using the boundary in content_type_header. The message form reads the Content-Type header and body of a Request or Response, such as the request in a serve! handler.

    Returns nothing when the content type is not multipart/form-data or there is no body. Each Multipart has the part's name, filename (or nothing), contenttype, and its content as the IO data.

    Examples

    julia> body = Vector{UInt8}(
               "--boundary\r\n" *
               "Content-Disposition: form-data; name=\"greeting\"\r\n\r\n" *
               "hello\r\n" *
               "--boundary\r\n" *
               "Content-Disposition: form-data; name=\"file\"; filename=\"a.txt\"\r\n" *
               "Content-Type: text/plain\r\n\r\n" *
               "file contents\r\n" *
               "--boundary--\r\n");
    
    julia> parts = HTTP.parse_multipart_form("multipart/form-data; boundary=boundary", body);
    
    julia> length(parts)
    2
    
    julia> parts[1].name, String(read(parts[1].data))
    ("greeting", "hello")
    
    julia> parts[2].name, parts[2].filename, parts[2].contenttype
    ("file", "a.txt", "text/plain")
    
    julia> String(read(parts[2].data))
    "file contents"

    Inside a server handler, pass the request directly:

    HTTP.serve!("127.0.0.1", 8080) do request
        parts = HTTP.parse_multipart_form(request)
        parts === nothing && return HTTP.Response(415, "expected multipart/form-data")
        return HTTP.Response(200, "received $(length(parts)) part(s)")
    end
    source
    HTTP.parse_multipart — Function
    parse_multipart(content_type_header, body, required_type=nothing) -> Union{Vector{Multipart}, Nothing}
    parse_multipart(message, required_type=nothing) -> Union{Vector{Multipart}, Nothing}

    Parse a multipart body of any subtype, such as multipart/form-data or multipart/mixed, using the boundary in content_type_header. The message form reads the header and body of a Request or Response.

    required_type (:formdata or :mixed) accepts only that subtype. Returns nothing when the content type does not match or there is no body.

    source
    HTTP.parse_multipart_mixed — Function
    parse_multipart_mixed(content_type_header, body) -> Union{Vector{Multipart}, Nothing}
    parse_multipart_mixed(message) -> Union{Vector{Multipart}, Nothing}

    Parse a multipart/mixed body; see parse_multipart.

    source

    Proxy Configuration

    HTTP.ProxyConfig — Type
    ProxyConfig(url; no_proxy=nothing)
    ProxyConfig(; http=nothing, https=nothing, all=nothing, no_proxy=nothing, env=false)

    The proxy settings of a Transport or a request. ProxyConfig() connects directly.

    http is the proxy for http:// URLs, https the proxy for https:// URLs, and all the proxy for either when the other is not set; ProxyConfig(url) sets all. no_proxy is a NoProxy, or anything it accepts, naming hosts to reach directly. With env = true, settings that are not given come from the HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and NO_PROXY environment variables, in upper or lower case.

    Proxy URLs may use http://, socks5://, or socks5h://; with either SOCKS scheme, the proxy resolves host names. An https:// proxy URL is accepted, but a request through it throws ArgumentError.

    source
    HTTP.ProxyURL — Function
    ProxyURL(url; no_proxy=nothing) -> ProxyConfig

    Return a ProxyConfig that sends every request through the proxy at url, except requests to the hosts in no_proxy.

    source
    HTTP.ProxyFromEnvironment — Function
    ProxyFromEnvironment() -> ProxyConfig

    Return a ProxyConfig read from the HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and NO_PROXY environment variables, in upper or lower case. The variables are read once, when it is called. Requests to localhost and loopback addresses never use these proxies.

    source
    HTTP.NoProxy — Type
    NoProxy(spec)
    NoProxy()

    The hosts that a ProxyConfig reaches without its proxy, in the format of the NO_PROXY environment variable. spec is a comma-separated string or a vector of entries: host names, domain suffixes, IP addresses, CIDR ranges, or any of these with a :port. "*" matches every host. localhost and loopback addresses always match.

    source

    HTTP/2 Configuration

    HTTP.HTTP2Settings — Type
    HTTP2Settings(; initial_window_size=65535, connection_window_size=65535)

    HTTP/2 receive windows, passed as http2_settings to a Client or to serve! and listen!.

    • initial_window_size: the receive window of each stream, sent as SETTINGS_INITIAL_WINDOW_SIZE (RFC 9113 §6.5.2). Values from 1 to 2^31 - 1 are allowed, so it can also be lowered to slow down senders.
    • connection_window_size: the receive window shared by all streams on a connection, from 65535 to 2^31 - 1.

    Both default to 65535, the protocol default. One stream can move at most about window / round-trip time bytes per second, so raise them for large transfers over links with high latency.

    source