hackney_conn (hackney v4.0.1)

View Source

gen_statem process for managing a single HTTP connection.

This module implements a state machine for HTTP connections, handling connection establishment, request/response cycles, and connection reuse.

States: - idle: Process started, not connected - connecting: TCP/SSL handshake in progress - connected: Ready for requests - sending: Sending request data - receiving: Awaiting/streaming response - closed: Connection terminated

Summary

Functions

Get the full response body.

Close the connection. This is a low-level function that closes the socket but keeps the process.

Connect to the target host. Blocks until connected or timeout.

Finish sending the request body.

Get the stored location (final URL after redirects).

Get the negotiated protocol for this connection. Returns http1, http2, or http3 based on ALPN negotiation (SSL connections), QUIC (HTTP/3), or http1 for plain TCP connections.

Get current state name for debugging.

Check if this connection should not be reused/pooled. SOCKS5 proxy connections set this flag since each establishes a unique tunnel.

Check if the connection is ready for a new request. Returns {ok, connected} if ready, or error/closed status. This combines state check and socket verification in one call.

Check if this connection was upgraded from TCP to SSL. Upgraded connections should be closed after use, not returned to pool.

Pause async streaming (hibernate the stream).

Get the peer SSL certificate. Returns {ok, Cert} where Cert is the DER-encoded certificate binary, or {error, Reason} if the connection is not SSL or the certificate is unavailable.

Get the remote address and port.

Receive data from the connection process. This is a low-level function used by hackney_response.

Release the connection back to the pool. This notifies the pool that the connection is available for reuse. Uses a synchronous call to ensure the pool has processed the checkin.

Send an HTTP request and wait for the response status and headers. Returns {ok, Status, Headers} for HTTP/1.1 or {ok, Status, Headers, Body} for HTTP/2. For HTTP/1.1, use body/1 or stream_body/1 to get the response body.

Make an HTTP request with additional request options. Options: - inform_fun: fun(Status, Reason, Headers) - callback for 1xx responses

Send an HTTP request asynchronously. Returns {ok, Ref} immediately. Response is sent as messages: - {hackney_response, Ref, {status, Status, Reason}} - {hackney_response, Ref, {headers, Headers}} - {hackney_response, Ref, Data} (body chunks) - {hackney_response, Ref, done} - {hackney_response, Ref, {error, Reason}} When follow_redirect is true and response is a redirect: - {hackney_response, Ref, {redirect, Location, Headers}} for 301,302,307,308 - {hackney_response, Ref, {see_other, Location, Headers}} for 303 with POST AsyncMode: true (continuous) or once (one message at a time, use stream_next/1)

Send an HTTP/3 request and return headers immediately. Returns {ok, Status, Headers} and allows subsequent stream_body/1 calls. This is for pull-based body streaming over HTTP/3.

Get the last response headers.

Resume paused async streaming.

Send data through the connection process. This is a low-level function used by hackney_request.

Send a chunk of the request body.

Send only the request headers (for streaming body mode). After this, use send_body_chunk/2 and finish_send_body/1 to send the body, then start_response/1 to receive the response.

Set the location (used after following redirects).

Set a new owner for this connection (sync). This updates the process being monitored - if the new owner crashes, the connection will terminate. Used by the pool when checking out a connection to a new requester.

Set a new owner for this connection (async). Same as set_owner/2 but non-blocking. Used when the caller cannot block (e.g., during pool checkin to avoid deadlock).

Set socket options on the underlying socket.

Get the local address and port.

Start a connection process. Options: - host: Target host (string) - port: Target port (integer) - transport: hackney_tcp or hackney_ssl - connect_timeout: Connection timeout (default 8000ms) - recv_timeout: Receive timeout (default 5000ms) - idle_timeout: Idle timeout before closing (default infinity) - connect_options: Options passed to transport connect - ssl_options: Additional SSL options

Start receiving the response after sending the full body.

Stop the connection process. Returns ok even if the process has already terminated.

Stop async mode and return to sync mode.

Stream the response body in chunks. Returns {ok, Data} for each chunk, {done, Pid} when complete.

Request the next message in {async, once} mode.

Upgrade a TCP connection to SSL. This performs an SSL handshake on the existing TCP socket. After upgrade, the connection is marked as upgraded_ssl and should NOT be returned to the pool (SSL connections are not pooled for security).

Check if the connection's socket is still healthy. Returns ok if socket is open, {error, closed} otherwise.

Functions

body(Pid)

-spec body(pid()) -> {ok, binary()} | {error, term()}.

Get the full response body.

body(Pid, Timeout)

-spec body(pid(), timeout()) -> {ok, binary()} | {error, term()}.

callback_mode()

close(Pid)

-spec close(pid()) -> ok.

Close the connection. This is a low-level function that closes the socket but keeps the process.

closed(EventType, OldState, Conn_data)

code_change(OldVsn, State, Data, Extra)

connect(Pid)

-spec connect(pid()) -> ok | {error, term()}.

Connect to the target host. Blocks until connected or timeout.

connect(Pid, Timeout)

-spec connect(pid(), timeout()) -> ok | {error, term()}.

connected(EventType, OldState, Conn_data)

connecting(EventType, OldState, Data)

finish_send_body(Pid)

-spec finish_send_body(pid()) -> ok | {error, term()}.

Finish sending the request body.

get_location(Pid)

-spec get_location(pid()) -> binary() | undefined.

Get the stored location (final URL after redirects).

get_protocol(Pid)

-spec get_protocol(pid()) -> http1 | http2 | http3.

Get the negotiated protocol for this connection. Returns http1, http2, or http3 based on ALPN negotiation (SSL connections), QUIC (HTTP/3), or http1 for plain TCP connections.

get_state(Pid)

-spec get_state(pid()) -> {ok, atom()} | {error, term()}.

Get current state name for debugging.

idle(EventType, OldState, Data)

init(_)

is_no_reuse(Pid)

-spec is_no_reuse(pid()) -> boolean().

Check if this connection should not be reused/pooled. SOCKS5 proxy connections set this flag since each establishes a unique tunnel.

is_ready(Pid)

-spec is_ready(pid()) -> {ok, connected} | {ok, closed} | {error, term()}.

Check if the connection is ready for a new request. Returns {ok, connected} if ready, or error/closed status. This combines state check and socket verification in one call.

is_upgraded_ssl(Pid)

-spec is_upgraded_ssl(pid()) -> boolean().

Check if this connection was upgraded from TCP to SSL. Upgraded connections should be closed after use, not returned to pool.

pause_stream(Pid)

-spec pause_stream(pid()) -> ok | {error, term()}.

Pause async streaming (hibernate the stream).

peercert(Pid)

-spec peercert(pid()) -> {ok, binary()} | {error, term()}.

Get the peer SSL certificate. Returns {ok, Cert} where Cert is the DER-encoded certificate binary, or {error, Reason} if the connection is not SSL or the certificate is unavailable.

peername(Pid)

-spec peername(pid()) -> {ok, {inet:ip_address(), inet:port_number()}} | {error, term()}.

Get the remote address and port.

receiving(EventType, Event, Data)

recv(Pid, Timeout)

-spec recv(pid(), timeout()) -> {ok, binary()} | {error, term()}.

Receive data from the connection process. This is a low-level function used by hackney_response.

recv(Pid, Length, Timeout)

-spec recv(pid(), non_neg_integer(), timeout()) -> {ok, binary()} | {error, term()}.

release_to_pool(Pid)

-spec release_to_pool(pid()) -> ok.

Release the connection back to the pool. This notifies the pool that the connection is available for reuse. Uses a synchronous call to ensure the pool has processed the checkin.

request(Pid, Method, Path, Headers, Body)

-spec request(pid(), binary(), binary(), list(), binary() | iolist()) ->
                 {ok, integer(), list()} | {ok, integer(), list(), binary()} | {error, term()}.

Send an HTTP request and wait for the response status and headers. Returns {ok, Status, Headers} for HTTP/1.1 or {ok, Status, Headers, Body} for HTTP/2. For HTTP/1.1, use body/1 or stream_body/1 to get the response body.

request(Pid, Method, Path, Headers, Body, Timeout)

-spec request(pid(), binary(), binary(), list(), binary() | iolist(), timeout()) ->
                 {ok, integer(), list()} | {ok, integer(), list(), binary()} | {error, term()}.

request(Pid, Method, Path, Headers, Body, Timeout, ReqOpts)

-spec request(pid(), binary(), binary(), list(), binary() | iolist(), timeout(), list()) ->
                 {ok, integer(), list()} | {ok, integer(), list(), binary()} | {error, term()}.

Make an HTTP request with additional request options. Options: - inform_fun: fun(Status, Reason, Headers) - callback for 1xx responses

request_async(Pid, Method, Path, Headers, Body, AsyncMode)

-spec request_async(pid(), binary(), binary(), list(), binary() | iolist(), true | once) ->
                       {ok, reference()} | {error, term()}.

Send an HTTP request asynchronously. Returns {ok, Ref} immediately. Response is sent as messages: - {hackney_response, Ref, {status, Status, Reason}} - {hackney_response, Ref, {headers, Headers}} - {hackney_response, Ref, Data} (body chunks) - {hackney_response, Ref, done} - {hackney_response, Ref, {error, Reason}} When follow_redirect is true and response is a redirect: - {hackney_response, Ref, {redirect, Location, Headers}} for 301,302,307,308 - {hackney_response, Ref, {see_other, Location, Headers}} for 303 with POST AsyncMode: true (continuous) or once (one message at a time, use stream_next/1)

request_async(Pid, Method, Path, Headers, Body, AsyncMode, StreamTo)

-spec request_async(pid(), binary(), binary(), list(), binary() | iolist(), true | once, pid()) ->
                       {ok, reference()} | {error, term()}.

request_async(Pid, Method, Path, Headers, Body, AsyncMode, StreamTo, FollowRedirect)

-spec request_async(pid(),
                    binary(),
                    binary(),
                    list(),
                    binary() | iolist(),
                    true | once,
                    pid(),
                    boolean()) ->
                       {ok, reference()} | {error, term()}.

request_async(Pid, Method, Path, Headers, Body, AsyncMode, StreamTo, FollowRedirect, ReqOpts)

-spec request_async(pid(),
                    binary(),
                    binary(),
                    list(),
                    binary() | iolist(),
                    true | once,
                    pid(),
                    boolean(),
                    list()) ->
                       {ok, reference()} | {error, term()}.

request_streaming(Pid, Method, Path, Headers, Body)

-spec request_streaming(pid(), binary(), binary(), list(), binary() | iolist()) ->
                           {ok, integer(), list()} | {error, term()}.

Send an HTTP/3 request and return headers immediately. Returns {ok, Status, Headers} and allows subsequent stream_body/1 calls. This is for pull-based body streaming over HTTP/3.

response_headers(Pid)

-spec response_headers(pid()) -> list() | undefined.

Get the last response headers.

resume_stream(Pid)

-spec resume_stream(pid()) -> ok | {error, term()}.

Resume paused async streaming.

send(Pid, Data)

-spec send(pid(), iodata()) -> ok | {error, term()}.

Send data through the connection process. This is a low-level function used by hackney_request.

send_body_chunk(Pid, Data)

-spec send_body_chunk(pid(), iodata()) -> ok | {error, term()}.

Send a chunk of the request body.

send_request_headers(Pid, Method, Path, Headers)

-spec send_request_headers(pid(), binary(), binary(), list()) -> ok | {error, term()}.

Send only the request headers (for streaming body mode). After this, use send_body_chunk/2 and finish_send_body/1 to send the body, then start_response/1 to receive the response.

sending(EventType, Event, Conn_data)

set_location(Pid, Location)

-spec set_location(pid(), binary()) -> ok.

Set the location (used after following redirects).

set_owner(Pid, NewOwner)

-spec set_owner(pid(), pid()) -> ok.

Set a new owner for this connection (sync). This updates the process being monitored - if the new owner crashes, the connection will terminate. Used by the pool when checking out a connection to a new requester.

set_owner_async(Pid, NewOwner)

-spec set_owner_async(pid(), pid()) -> ok.

Set a new owner for this connection (async). Same as set_owner/2 but non-blocking. Used when the caller cannot block (e.g., during pool checkin to avoid deadlock).

setopts(Pid, Opts)

-spec setopts(pid(), list()) -> ok | {error, term()}.

Set socket options on the underlying socket.

sockname(Pid)

-spec sockname(pid()) -> {ok, {inet:ip_address(), inet:port_number()}} | {error, term()}.

Get the local address and port.

start_link(Opts)

-spec start_link(map()) -> {ok, pid()} | {error, term()}.

Start a connection process. Options: - host: Target host (string) - port: Target port (integer) - transport: hackney_tcp or hackney_ssl - connect_timeout: Connection timeout (default 8000ms) - recv_timeout: Receive timeout (default 5000ms) - idle_timeout: Idle timeout before closing (default infinity) - connect_options: Options passed to transport connect - ssl_options: Additional SSL options

start_response(Pid)

-spec start_response(pid()) -> {ok, integer(), list(), pid()} | {error, term()}.

Start receiving the response after sending the full body.

stop(Pid)

-spec stop(pid()) -> ok.

Stop the connection process. Returns ok even if the process has already terminated.

stop_async(Pid)

-spec stop_async(pid()) -> ok | {error, term()}.

Stop async mode and return to sync mode.

stream_body(Pid)

-spec stream_body(pid()) -> {ok, binary()} | done | {error, term()}.

Stream the response body in chunks. Returns {ok, Data} for each chunk, {done, Pid} when complete.

stream_next(Pid)

-spec stream_next(pid()) -> ok | {error, term()}.

Request the next message in {async, once} mode.

streaming(EventType, Event, Data)

streaming_body(EventType, Event, Conn_data)

streaming_once(EventType, OldState, Data)

terminate(Reason, State, Conn_data)

upgrade_to_ssl(Pid, SslOpts)

-spec upgrade_to_ssl(pid(), list()) -> ok | {error, term()}.

Upgrade a TCP connection to SSL. This performs an SSL handshake on the existing TCP socket. After upgrade, the connection is marked as upgraded_ssl and should NOT be returned to the pool (SSL connections are not pooled for security).

verify_socket(Pid)

-spec verify_socket(pid()) -> ok | {error, closed | term()}.

Check if the connection's socket is still healthy. Returns ok if socket is open, {error, closed} otherwise.