View Source erqwest
An erlang wrapper for reqwest using rustler. Map-based interface inspired by katipo.
Features
- HTTP/1.1 and HTTP/2 with connection keepalive/reuse
- Configurable SSL support, uses system root certificates by default
- Sync and async interfaces
- Proxy support
- Optional cookies support
- Optional gzip support
Prerequisites
- Erlang/OTP
- Rust
- OpenSSL (not required on mac)
Or use the provided shell.nix
if you have nix installed.
Usage
Start a client
ok = application:ensure_started(erqwest),
ok = erqwest:start_client(default).
This registers a client under the name default
. The client maintains an
internal connection pool.
Synchronous interface
No streaming
{ok, #{status := 200, body := Body}} =
erqwest:get(default, <<"https://httpbin.org/get">>),
{ok, #{status := 200, body := Body1}} =
erqwest:post(default, <<"https://httpbin.org/post">>,
#{body => <<"data">>}).
Stream request body
{handle, H} = erqwest:post(default, <<"https://httpbin.org/post">>,
#{body => stream}),
ok = erqwest:send(H, <<"data, ">>),
ok = erqwest:send(H, <<"more data.">>),
{ok, #{body := Body}} = erqwest:finish_send(H).
Stream response body
{ok, #{body := Handle}} = erqwest:get(default, <<"https://httpbin.org/stream-bytes/1000">>,
#{response_body => stream}),
ReadAll = fun Self() ->
case erqwest:read(Handle, #{length => 0}) of
{ok, Data} ->
[Data];
{more, Data} ->
[Data|Self()]
end
end,
1000 = iolist_size(ReadAll()).
Conditionally consume response body
{ok, Resp} = erqwest:get(default, <<"https://httpbin.org/status/200,500">>,
#{response_body => stream}),
case Resp of
#{status := 200, body := Handle} ->
{ok, <<>>} = erqwest:read(Handle),
#{status := BadStatus, body := Handle} ->
%% ensures the connection is closed/can be reused immediately
erqwest:cancel(Handle),
io:format("Status is ~p, not interested~n", [BadStatus])
end.
Asynchronous interface
erqwest_async:req(default, self(), Ref=make_ref(),
#{method => get, url => <<"https://httpbin.org/get">>}),
receive
{erqwest_response, Ref, reply, #{body := Body}} -> Body
end.
See the docs for more details and and the test suite for more examples.