class HTTP::Client
An HTTP/1.1 client: requests and responses are values, bodies are
streamed, and kept connections are pooled per origin. Shareable: one
client serves a program's tasks (its pool lives in an Atom).
client = HTTP::Client.new(timeout: 30.seconds)
res = client.get("https://example.com/users/alice",
headers: {"Accept" => "application/activity+json"})
res.status # => 200
actor = res.json # the body read and parsed; the connection goes back to the pool
A response that is not 2xx is a value, not an error (ensure_success
raises for it). Redirects are followed (max_redirects), the proxy is
the environment's (Proxy.from_env) unless given.
Classes and modules
HTTP::Client::ConnectErrorThe connection could not be made: the name has no address, the connection was refused or unreachable, the TLS handshake failed. The message carries the cause's.HTTP::Client::ErrorWhat went wrong with a request (not HTTP::Error, whose status is for a server to answer with).HTTP::Client::ProtocolErrorThe response is not HTTP/1.x as it should be: a bad status line or header, bad framing, headers over max_header_bytes.HTTP::Client::ProxyErrorThe proxy refused the tunnel (CONNECT): status is its answer.HTTP::Client::RedirectErrorA redirect that cannot be followed: no usable Location, or a Content::Stream body to send again.HTTP::Client::RequestA request: a value, so that a program (or a cog signing requests) can build it, change it with #header and with, and send it with Client#request.HTTP::Client::ResponseA response: its status and headers, and its body, read from the connection as it is asked for. The connection goes back to the pool when the body has been read to its end (body.read, read_bytes, each_chunk, #close); a response dropped with its body unread closes its connection.HTTP::Client::ResponseTooLargeA body larger than max_body_bytes, read with read or read_bytes (each_chunk has no limit).HTTP::Client::StatusErrorA response that is not 2xx, from Response#ensure_success. An exception is Shareable and a response's body is not, so it carries the response's status, headers and URL, and its body when it could be read (up to max_body_bytes). The message says the status and the URL, never the body.HTTP::Client::TimeoutErrorThe request ran out of time (timeout, connect_timeout, read_timeout or write_timeout).HTTP::Client::TooManyRedirectsMore redirects than max_redirects. An exception is Shareable and a response's body is not, so it carries the last redirect's status, headers and URL (its body was read or dropped).
Constants
USER_AGENT: String
Sent when a request names no User-Agent.
Class methods
def self.new(*, timeout: Duration? = …, connect_timeout: Duration = …, read_timeout: Duration = …, write_timeout: Duration = …, max_header_bytes: Int = …, max_body_bytes: Int = …, max_redirects: Int = …, tls: TLS::Config = …, proxy: HTTP::Proxy? = …, max_idle_per_host: Int = …, idle_timeout: Duration = …, user_agent: String = …, fast_fallback: Bool = …) -> HTTP::Client
A client. timeout bounds a whole request (connecting, sending, the
response's headers, and the redirects), connect_timeout the
connection (the name's lookup, the connects, a proxy's tunnel, the
TLS handshake), read_timeout and write_timeout each read and
write. tls is what https connections trust (alpn defaults to
http/1.1); proxy defaults to the environment's. fast_fallback
is Socket.tcp's: false tries a name's addresses one after the
other, without Happy Eyeballs.
def self.default -> HTTP::Client
The client HTTP.get and the other module functions use: one with
the defaults, made on first use.
Methods
def request(req: HTTP::Client::Request) -> HTTP::Client::Response
Sends req and returns the response, its headers read and its body
not yet: follows redirects (max_redirects). Raises a
Client::Error (or ArgumentError for a request that cannot be
sent); a response that is not 2xx is returned as any other.
def get(url: String | URI, headers: HTTP::Headers | Hash[String, String] = …) -> HTTP::Client::Response
A GET request: request(Request.get(url, headers)).
def head(url: String | URI, headers: HTTP::Headers | Hash[String, String] = …) -> HTTP::Client::Response
A HEAD request.
def delete(url: String | URI, headers: HTTP::Headers | Hash[String, String] = …) -> HTTP::Client::Response
A DELETE request.
def post(url: String | URI, body: String | Bytes = …, content_type: String? = …, headers: HTTP::Headers | Hash[String, String] = …) -> HTTP::Client::Response
A POST request with body (Content-Type content_type when
given).
def put(url: String | URI, body: String | Bytes = …, content_type: String? = …, headers: HTTP::Headers | Hash[String, String] = …) -> HTTP::Client::Response
A PUT request, as #post.
def patch(url: String | URI, body: String | Bytes = …, content_type: String? = …, headers: HTTP::Headers | Hash[String, String] = …) -> HTTP::Client::Response
A PATCH request, as #post.
def close -> Void
Closes the kept connections and keeps no more: those in use are closed when their responses are done. The client can still send requests, each on a connection of its own.