httpc(3)
π NAME π
httpc β an HTTP/1.1 client, bestie. That's the whole vibe. (This is the httpc(3) Erlang module definition, you're in the right place π)
β¨ DESCRIPTION β¨
okay so. This module hands you the API to an HTTP/1.1 compatible client, built according to RFC 2616. And the tea is: caching is not supported. Not a single byte of cache. Periodt.
NOTE: when you start the Inets application, a manager process for the default profile gets started too π«Ά. The functions in this API that don't explicitly use a profile will access the default profile. A profile keeps track of proxy options, cookies, and other options that can be applied to more than one request. If the schemehttpsis used, the SSL application must be started. Whenhttpslinks need to go through a proxy, theCONNECTmethod extension to HTTP-1.1 is used to establish a tunnel and then the connection is upgraded to TLS. However, "TLS upgrade" according to RFC 2817 is not supported. Pipelining is only used if the pipeline time-out is set, otherwise persistent connections without pipelining are used β meaning the client always waits for the previous response before sending the next request. That's just how it is, no cap π§
Some examples are provided in the Inets User's Guide. Go look, they ate π
π¦ HTTP client service start & stop π¦
An HTTP client can be configured to start when you start the Inets application, or it can be started dynamically at runtime by calling the Inets application API:
inets:start(httpc, ServiceConfig)inets:start(httpc, ServiceConfig, How)
see inets. The configuration options are as follows, and they are mandatory reading, no skipping π
{profile, Profile :: atom() | pid()}β the name of the profile. This option is mandatory. Not optional. Not a suggestion. Mandatory.{data_dir, Path :: string()}β the directory where the profile can save persistent data. If you omit it, all cookies are treated as session cookies π.Pathrepresents a file path or directory path.
The client can be stopped using inets:stop(httpc, Pid) or inets:stop(httpc, Profile). Slay, goodbye π
WARNING: please note thathttpcnormalizes input URIs before internal processing, and special care shall be taken when the URI has percent ("%") characters. A percent serves as the indicator for percent-encoded octets, and it must be percent-encoded as"%25"for that octet to be used as data within the URI. For example, in order to send an HTTP GET request with the URIhttp://localhost/foo%25bar, the percent character must be percent-encoded when creating the request:httpc:request("http://localhost/foo%2525bar"). Read that twice bestie, it's giving β¨footgunβ¨ π
πΈ See also πΈ
RFC 2616, inets, gen_tcp, ssl β the whole squad π«Ά
π₯ FUNCTIONS π₯
cancel_request/2
cancel_request(RequestId, Profile) -> ok
when
RequestId :: any(),
Profile :: atom() | pid().
Cancels an asynchronous HTTP request. But listen β this does not guarantee that the request response is not delivered. Because it's asynchronous, the request can already have been completed by the time the cancellation arrives π it's a race, and sometimes the race wins.
cookie_header/2
cookie_header(Url, ProfileOrOpts) -> HttpHeader | {error, Reason}
when
Url :: uri_string:uri_string(),
HttpHeader ::
{Field :: [byte()],
Value :: binary() | iolist()},
ProfileOrOpts :: Profile | Opts,
Profile :: atom() | pid(),
Opts :: [CookieHeaderOpt],
CookieHeaderOpt ::
{ipv6_host_with_brackets, boolean()},
Reason :: term().
Returns the cookie header that would have been sent when making a request to Url using profile Profile. If no profile is specified, the default profile is used. π
Option ipv6_host_with_bracket deals with how to parse IPv6 addresses. For details, see argument Options of request/4,5.
cookie_header/3
cookie_header(Url, Opts, Profile) -> HttpHeader | {error, Reason}
when
Url :: uri_string:uri_string(),
HttpHeader ::
{Field :: [byte()],
Value :: binary() | iolist()},
Profile :: atom() | pid(),
Opts :: [CookieHeaderOpt],
CookieHeaderOpt ::
{ipv6_host_with_brackets, boolean()},
Reason :: term().
Returns the cookie header that would have been sent when making a request to Url using profile Profile. If no profile is specified, the default profile is used. (Same energy as above, just with the args in a different order β iconic, honestly π
)
Option ipv6_host_with_bracket deals with how to parse IPv6 addresses. For details, see argument Options of request/4,5.
get_options/2
get_options(OptionItems, Profile) ->
{ok, Values} | {error, Reason}
when
OptionItems :: all | [OptionItem],
OptionItem ::
proxy | https_proxy | max_sessions |
max_connections_open | keep_alive_timeout |
max_keep_alive_length | pipeline_timeout |
max_pipeline_length | cookies | ipfamily |
ip | port | socket_opts | verbose |
unix_socket,
Values :: [{OptionItem, term()}],
Profile :: atom() | pid(),
Reason :: term().
Retrieves the options currently used by the client. Peek behind the curtain, bestie π
info/1
info(Profile) -> list() | {error, Reason}
when Reason :: term(), Profile :: atom() | pid().
Produces a list of miscellaneous information. Intended for debugging. If no profile is specified, the default profile is used. It's the "what is going on in there" function π¦
request/2
request(Url, Profile) -> {ok, Result} | {error, term()}
when
Url :: uri_string:uri_string(),
Profile :: atom() | pid(),
Result ::
{StatusLine, [HttpHeader], HttpBodyResult} |
{StatusCode, HttpBodyResult} |
RequestId | saved_to_file,
HttpHeader ::
{Field :: [byte()],
Value :: binary() | iolist()},
HttpBodyResult :: string() | binary(),
StatusLine :: {HttpVersion, StatusCode, string()},
HttpVersion :: string(),
StatusCode :: non_neg_integer(),
RequestId :: any().
Equivalent to httpc:request(get, {Url, []}, [], []). A lil shortcut. A lil treat. β¨
request/5
request(Method, Request, HttpOptions, Options, Profile) ->
{ok, Result} | {error, term()}
when
Method ::
head | get | put | patch | post | trace |
options | delete,
Request ::
{uri_string:uri_string(), [HttpHeader]} |
{uri_string:uri_string(),
[HttpHeader],
ContentType :: string(),
HttpBody},
HttpBody ::
iolist() |
binary() |
{fun((Accumulator :: term()) ->
eof |
{ok, iolist(), Accumulator :: term()}),
Accumulator :: term()} |
{chunkify,
fun((Accumulator :: term()) ->
eof |
{ok, iolist(), Accumulator :: term()}),
Accumulator :: term()},
HttpHeader ::
{Field :: [byte()],
Value :: binary() | iolist()},
HttpOptions :: [HttpOption],
HttpOption ::
{timeout, timeout()} |
{connect_timeout, timeout()} |
{ssl, [ssl:tls_option()]} |
{autoredirect, boolean()} |
{autoretry, timeout()} |
{proxy_auth, {string(), string()}} |
{version, HttpVersion} |
{relaxed, boolean()},
Options :: [OptionRequest],
OptionRequest ::
{sync, boolean()} |
{stream, StreamTo} |
{body_format, BodyFormat} |
{full_result, boolean()} |
{headers_as_is, boolean()} |
{socket_opts, [SocketOpt]} |
{receiver, Receiver} |
{ipv6_host_with_brackets, boolean()} |
{max_header_size, MaxSize} |
{max_body_size, MaxSize},
StreamTo ::
none | self | {self, once} | file:name_all(),
BodyFormat :: string | binary,
SocketOpt :: term(),
Receiver ::
pid() |
fun((term()) -> term()) |
{ReceiverModule :: atom(),
ReceiverFunction :: atom(),
ReceiverArgs :: list()},
MaxSize :: non_neg_integer() | nolimit,
Profile :: atom() | pid(),
HttpVersion :: string(),
Result ::
{StatusLine, [HttpHeader], HttpBodyResult} |
{StatusCode, HttpBodyResult} |
RequestId | saved_to_file,
StatusLine :: {HttpVersion, StatusCode, string()},
StatusCode :: non_neg_integer(),
HttpBodyResult :: string() | binary(),
RequestId :: any().
Sends an HTTP request π¨. This function can be both synchronous and asynchronous. In the latter case, the function returns {ok, RequestId} and then the information is delivered to the receiver depending on that value.
When Profile is stand_alone only the pid can be used. (So don't come at it with an atom name, it's not the vibe π)
HTTP options:
timeoutβ time-out time for the request.- The clock starts ticking when the request is sent β°
- Time is in milliseconds.
- Default is
infinity.
β³ and bestieβ¦ that's not even all the HTTP options. there's more coming, don't go anywhere π
connect_timeoutβ the connection time-out time π, used during the initial request, back when the client is still busy connecting to the server.
Time is in milliseconds.
Default is the value of option timeout.
sslβ this is the SSL/TLS connecting configuration option πβ¨
Default value is obtained by calling httpc:ssl_verify_host_options(true). See ssl:connect/2,3,4 for available options.
autoredirectβ the client just goes and grabs the info from the new URI itself and hands you that as the result, instead of giving you a 30X-result code. no extra work for you, bestie π
For some 30X-result codes, automatic redirect is not allowed. In these cases the 30X-result is always returned.
Default is true.
autoretryβ the client automatically retries the request once after getting aRetry-Afterheader from the server. π
Sometimes servers suggest a value that just does not work for your app, so this option lets you limit the wait time (in milliseconds) in between requests, or turn the retry all the way off with a value of 0. If a value of Retry-After header exceeds the set value, no retry will be done.
Default is atom infinity.
Since OTP 28.4
proxy_authβ a proxy-authorization header, given as a tuple where the first element is the username and the second element of the tuple is the password added to the request. π«Άversionβ can be used to make the client act as an HTTP/1.0 client. By default this is an HTTP/1.1 client. When using HTTP/1.0 persistent connections are not used. π°οΈ
Default is the string "HTTP/1.1".
relaxedβ if set totrue, workarounds for known server deviations from the HTTP-standard are enabled. (yes, servers be wilding like that π)
Default is false.
π« Options details π«
syncβ option for the request to be synchronous or asynchronous.
Default is true.
streamβ streams the body of a 200 or 206 response to the calling process or to a file. When streaming to the calling process using optionself, the following stream messages are sent to that process:
{http, {RequestId, stream_start, Headers}}
{http, {RequestId, stream, BinBodyPart}}
{http, {RequestId, stream_end, Headers}}
When streaming to the calling processes using option {self, once}, the first message has an extra element, that is, {http, {RequestId, stream_start, Headers, Pid}}. This is the process id to be used as an argument to httpc:stream_next/1 to trigger the next message to be sent to the calling process. π
Notice that chunked encoding can add headers so that there are more headers in the stream_end message than in stream_start. When streaming to a file and the request is asynchronous, the message {http, {RequestId, saved_to_file}} is sent.
Default is none.
body_formatβ defines if the body is to be delivered as astringorbinary. This option is only valid for the synchronous request.
Default is string. Asynchronous requests always use binary.
full_resultβ defines if a "full result" is to be returned to the caller (that is, the body, the headers, and the entire status line) or not (the body and the status code). π
Default is true.
headers_as_isβ defines if the headers provided by the user are to be made lower case or to be regarded as case sensitive.
The HTTP standard requires them to be case insensitive. Use this feature only if there is no other way to communicate with the server or for testing purpose. When this option is used, no headers are automatically added. All necessary headers must be provided by the user.
Default is false.
socket_optsβ socket options to be used for this request.
See the options used by gen_tcp and ssl.
Overrides any value set by function set_options.
The validity of the options is not checked by the HTTP client β they are assumed to be correct and passed on to ssl application and inet driver, which may reject them if they are not correct. π¬
NOTE: Persistent connections are not supported when setting thesocket_optsoption. Whensocket_optsis not set the current implementation assumes the requests to the same host, port combination will use the same socket options.
By default the socket options set by function set_options/1,2 are used when establishing a connection.
receiverβ defines how the client delivers the result of an asynchronous request (synchas the valuefalse). π¬pid/0
Messages are sent to this process in the format {http, ReplyInfo}.
alias/0
Messages are sent to this special reference in the format {http, ReplyInfo}.
function/1
Information is delivered to the receiver through calls to the provided fun Receiver(ReplyInfo).
{Module, Function, Args}
Information is delivered to the receiver through calls to the callback function apply(Module, Function, [ReplyInfo | Args]).
In all of these cases, ReplyInfo has the following structure:
{RequestId, saved_to_file}
{RequestId, {error, Reason}}
{RequestId, Result}
{RequestId, stream_start, Headers}
{RequestId, stream_start, Headers, HandlerPid}
{RequestId, stream, BinBodyPart}
{RequestId, stream_end, Headers}
Default is the pid of the process calling the request function (self/0).
ipv6_host_with_brackets
Defines when parsing the Host-Port part of an URI with an IPv6 address with brackets, if those brackets are to be retained (true) or stripped (false).
Default is false.
max_header_size
Maximum total number of bytes allowed for the response headers (cumulative across all header lines). If the server sends headers exceeding this limit, the request fails with {error, {header_too_long, {max, MaxSize}}}. π
The atom nolimit disables the check (not recommended).
Default is 10240 (same as the max_header_size configuration for httpd).
max_body_size
Maximum number of bytes allowed for the response body. If the Content-Length of the response exceeds this limit, the request fails with {error, body_too_big}.
The atom nolimit disables the check.
Default is nolimit.
reset_cookies(Profile) -> Void πͺ
reset_cookies(Profile) -> Void
when Profile :: atom() | pid(), Void :: term().
Resets (clears) the cookie database for the specified Profile. If no profile is specified the default profile is used. bye bye lil cookies π
set_options(Options, Profile) -> ok | {error, Reason} βοΈ
set_options(Options, Profile) -> ok | {error, Reason}
when
Options :: [Option],
Option ::
{proxy, {Proxy, NoProxy}} |
{https_proxy, {Proxy, NoProxy}} |
{max_connections_open, MaxConnectionsOpen} |
{max_sessions, MaxSessions} |
{max_keep_alive_length, MaxKeepAlive} |
{keep_alive_timeout, KeepAliveTimeout} |
{max_pipeline_length, MaxPipeline} |
{pipeline_timeout, PipelineTimeout} |
{cookies, CookieMode} |
{ipfamily, IpFamily} |
{ip, IpAddress} |
{port, Port} |
{socket_opts, [SocketOpt]} |
{verbose, VerboseMode} |
{unix_socket, UnixSocket},
Profile :: atom() | pid(),
SocketOpt :: term(),
Proxy :: {HostName, Port},
Port :: non_neg_integer(),
NoProxy :: [DomainDesc | HostName | IpAddressDesc],
MaxConnectionsOpen :: integer() | infinity,
MaxSessions :: integer(),
MaxKeepAlive :: integer(),
KeepAliveTimeout :: integer(),
MaxPipeline :: integer(),
PipelineTimeout :: integer(),
CookieMode :: enabled | disabled | verify,
IpFamily :: inet | inet6 | local | inet6fb4,
IpAddressDesc :: string(),
IpAddress :: inet:ip_address(),
VerboseMode :: false | verbose | debug | trace,
UnixSocket :: string(),
Reason :: term(),
DomainDesc :: string(),
HostName :: string().
Sets options to be used for subsequent requests. set it once, slay forever π
HostName
Example: "localhost" or "foo.bar.se"
DomainDesc
Example "*.Domain" or "*.ericsson.se"
IpAddressDesc
Example: "134.138" or "[FEDC:BA98" (all IP addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP address). proxy defaults to {undefined, []}, that is, no proxy is configured and https_proxy defaults to the value of proxy. π
MaxConnectionsOpenβMaxConnectionsOpenMaximum number of handlers that can be opened at the same time. Default isinfinitywhich means that it's not limited. π«ΆMaxSessionsβMaxSessionsMaximum number of persistent connections to a host. Default is2.MaxKeepAliveβMaxKeepAliveMaximum number of outstanding requests on the same connection to a host. Default is5.
and bestie, that is not the end of the list β keep scrolling π
KeepAliveTimeoutβ if a persistent connection is idle longer than thekeep_alive_timeoutin milliseconds, the client closes the connection. Bye bye, idle socket π . The server can also have such a time-out, but do not take that for granted. Default is120000(=2 min).MaxPipelineβ maximum number of outstanding requests on a pipelined connection to a host. Default is2. Queue 'em up, but only a lil bit.PipelineTimeoutβ if a persistent connection is idle longer than thepipeline_timeoutin milliseconds, the client closes the connection. Default is0, which results in pipelining not being used. Zero pipelining, zero drama π«.CookieModeβ if cookies are enabled, all valid cookies are automatically saved in the cookie database of the client manager πͺ. If optionverifyis used, functionstore_cookies/2has to be called for the cookies to be saved. Default isdisabled. No sneaky cookie saving unless you ask.IpFamilyβ default isinet. Withinet6fb4option, IPv6 will be preferred but if connection fails, an IPv4 fallback connection attempt will be made. dual-stack realness β¨.IpAddressβ if the host has several network interfaces, this option specifies which one to use. Seegen_tcp:connect/3,4for details. Pick your interface like you pick your font π.Portβ Example:8080. Local port number to use. Seegen_tcp:connect/3,4for details. Local port, local queen π.SocketOptsβ the options are appended to the socket options used by the client. These are the default values when a new request handler is started (for the initial connect). They are passed directly to the underlying transport (gen_tcpor SSL) without verification. See the options used bygen_tcpandssl. No verification, just trust π.VerboseModeβ default isfalse. This option is used to switch on (or off) different levels of Erlang trace on the client. It is a debug feature. Turn it on when you need the full behind-the-scenes commentary βοΈ.Profileβ when startedstand_aloneonly the pid can be used. Solo mode? Bring the pid, bestie.UnixSocketβ experimental option for sending HTTP requests over a unix domain socket π§. The value ofunix_socketshall be the full path to a unix domain socket file with read/write permissions for the erlang process. Default isundefined. Experimental, so handle with care.
NOTE: If possible, the client keeps its connections alive and uses persistent connections with or without pipeline depending on configuration and current circumstances. The HTTP/1.1 specification does not provide a guideline for how many requests that are ideal to be sent on a persistent connection. This depends much on the application. A long queue of requests can cause a user-perceived delay, as earlier requests can take a long time to complete. The HTTP/1.1 specification suggests a limit of two persistent connections per server, which is the default value of option max_sessions. The current implementation assumes the requests to the same host, port combination will use the same socket options.
ssl_verify_host_options(WildcardHostName) -> list()
when WildcardHostName :: boolean().
Returns ssl options which can be used to verify the host, uses public_key:cacerts_get() to read CA certicates and if WildcardHostName is true adds the hostname check from public_key:public_key:pkix_verify_hostname_match_fun(https) to the options. Host verification but make it Erlang π.
store_cookies(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}
when
SetCookieHeaders :: [HttpHeader],
HttpHeader ::
{Field :: [byte()],
Value :: binary() | iolist()},
Url :: term(),
Profile :: atom() | pid(),
Reason :: term().
Saves the cookies defined in SetCookieHeaders in the client profile cookie database. Call this function if option cookies is set to verify. If no profile is specified, the default profile is used. Cookie archive unlocked πͺ.
stream_next(Pid) -> ok
when Pid :: pid().
Triggers the next message to be streamed, that is, the same behavior as active ones for sockets. Next, next, next π .
which_cookies(Profile) -> [CookieStores]
when
Profile :: atom() | pid(),
CookieStores ::
{cookies, Cookies} |
{session_cookies, Cookies},
Cookies :: [term()].
Produces a list of the entire cookie database. Intended for debugging/testing purposes. If no profile is specified, the default profile is used. Peek the cookie vault π.
which_sessions(Profile) -> SessionInfo
when
Profile :: atom() | pid(),
SessionInfo ::
{GoodSession, BadSessions, NonSessions},
GoodSession :: [Session],
BadSessions :: [term()],
NonSessions :: [term()],
Session :: term().
This function is intended for debugging only. It produces a slightly processed dump of the session database. The first list of the session information tuple will contain session information on an internal format. The last two lists of the session information tuple should always be empty if the code is working as intended. If no profile is specified, the default profile is used. Debug dump, but make it session tea βοΈ.
that's the whole httpc(3) page, bestie! source: Ericsson AB, version: inets 9.7.2, manual: httpc(3). periodt π
β¨
π¦ where this page comes from
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms