HTTP Guide

View Source

This guide covers hackney's HTTP features in depth.

Request Anatomy

hackney:request(Method, URL, Headers, Body, Options) ->
    {ok, StatusCode, RespHeaders, Ref} | {error, Reason}

Request Bodies

Binary Body

hackney:post(URL,
    [{<<"content-type">>, <<"application/json">>}],
    <<"{\"key\": \"value\"}">>
).

Form-Encoded Body

hackney:post(URL, [], {form, [{<<"key">>, <<"value">>}]}).

Multipart Body

hackney:post(URL, [], {multipart, [
    {<<"field">>, <<"value">>},
    {file, <<"/path/to/file.txt">>}
]}).

Streaming Body

{ok, Ref} = hackney:post(URL, Headers, stream),
ok = hackney:send_body(Ref, <<"chunk1">>),
ok = hackney:send_body(Ref, <<"chunk2">>),
ok = hackney:finish_send_body(Ref),
{ok, Status, RespHeaders, Ref} = hackney:start_response(Ref).

Response Handling

Read Full Body

{ok, 200, Headers, Ref} = hackney:get(URL),
{ok, Body} = hackney:body(Ref).

Stream Response Body

{ok, 200, Headers, Ref} = hackney:get(URL),
stream_body(Ref).

stream_body(Ref) ->
    case hackney:stream_body(Ref) of
        {ok, Data} -> process(Data), stream_body(Ref);
        done -> ok
    end.

HTTP/2 Support

Hackney automatically negotiates HTTP/2 for HTTPS connections via ALPN.

Automatic HTTP/2

%% HTTP/2 used automatically when server supports it
{ok, 200, Headers, Body} = hackney:get(
    <<"https://nghttp2.org/">>,
    [],
    <<>>,
    [with_body]
).

Force Protocol

%% HTTP/2 only
hackney:get(URL, [], <<>>, [{protocols, [http2]}]).

%% HTTP/1.1 only
hackney:get(URL, [], <<>>, [{protocols, [http1]}]).

Detect Protocol

HTTP/2 responses have lowercase header names:

case hd(Headers) of
    {<<"date">>, _} -> http2;
    {<<"Date">>, _} -> http1
end.

For details on multiplexing, server push, and architecture, see the HTTP/2 Guide.

Async Responses

{ok, Ref} = hackney:get(URL, [], <<>>, [async]),
receive
    {hackney_response, Ref, {status, Status, _}} -> ok
end,
receive
    {hackney_response, Ref, {headers, Headers}} -> ok
end,
receive
    {hackney_response, Ref, done} -> ok;
    {hackney_response, Ref, Bin} -> ok
end.

Async Once

{ok, Ref} = hackney:get(URL, [], <<>>, [{async, once}]),
receive {hackney_response, Ref, Msg} -> ok end,
hackney:stream_next(Ref).  %% Request next message

Connection Pooling

Default Pool

hackney:get(URL).  %% Uses default pool

Named Pools

hackney_pool:start_pool(my_api, [
    {max_connections, 100},
    {timeout, 150000}
]),
hackney:get(URL, [], <<>>, [{pool, my_api}]).

Redirects

{ok, 200, Headers, Ref} = hackney:get(URL, [], <<>>, [
    {follow_redirect, true},
    {max_redirect, 5}
]).

Proxies

HTTP Proxy

hackney:get(URL, [], <<>>, [
    {proxy, <<"http://proxy:8080">>}
]).

Environment Variables

hackney reads HTTP_PROXY, HTTPS_PROXY, NO_PROXY automatically.

SSL/TLS

Custom CA Certificate

hackney:get(URL, [], <<>>, [
    {ssl_options, [{cacertfile, "/path/to/ca.crt"}]}
]).

Skip Verification

hackney:get(URL, [], <<>>, [insecure]).

Timeouts

hackney:get(URL, [], <<>>, [
    {connect_timeout, 5000},
    {recv_timeout, 30000}
]).

Cookies

hackney:get(URL, [], <<>>, [{cookie, <<"session=abc">>}]).

%% Parse response cookies
{ok, 200, Headers, _} = hackney:get(URL),
Cookies = hackney:cookies(Headers).

Basic Authentication

hackney:get(URL, [], <<>>, [
    {basic_auth, {<<"user">>, <<"pass">>}}
]).

Next Steps