Skip to content

Commit cc74915

Browse files
authored
Merge pull request #842 from benoitc/refactor/http2-via-erlang-h2
refactor(http2): delegate HTTP/2 to erlang_h2 library
2 parents b98ebcd + c20fd1c commit cc74915

20 files changed

Lines changed: 285 additions & 10399 deletions

NEWS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ UNRELEASED
55

66
### Refactor
77

8+
- HTTP/2 is now delegated to the `erlang_h2` library (hex `h2` 0.3.0).
9+
Hackney no longer ships its own HTTP/2 framing, HPACK codec, or
10+
connection/stream state machine:
11+
- `hackney_http2.erl`, `hackney_http2_machine.erl`, `hackney_hpack.erl`
12+
and the `hackney_hpack_huffman*` headers have been removed.
13+
- `hackney_conn.erl` now starts an `h2_connection` gen_statem on the
14+
post-ALPN socket, transfers socket ownership, and translates
15+
`{h2, Conn, Event}` owner-messages into hackney's sync replies or
16+
`{hackney_response, Ref, _}` async events.
17+
- Server push handling (RFC 7540 §8.2, deprecated) is no longer exposed.
18+
The `enable_push` option is a no-op.
19+
- Public user-facing API is unchanged: `hackney:request/5`, streaming
20+
async responses, pooled HTTP/2 connections, and `request_async` all
21+
behave as before.
822
- HTTP/3 is now delegated to the `erlang_quic` library's `quic_h3` module
923
(hex `quic` 1.0.0). Hackney no longer ships its own HTTP/3 framing,
1024
QPACK codec, control-stream or unidirectional-stream handling:

guides/http2_guide.md

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ Hackney supports HTTP/2 with automatic protocol negotiation via ALPN (Applicatio
1313
- **Multiplexing** - Multiple requests share a single connection
1414
- **Header compression** - HPACK compression reduces overhead
1515
- **Flow control** - Automatic window management
16-
- **Server push** - Optional support for server-initiated streams
16+
- **Delegated to `erlang_h2`** - the underlying HTTP/2 stack is the `h2`
17+
hex package; hackney exposes the same request API it always did
1718

1819
## Quick Start
1920

@@ -243,20 +244,10 @@ end) || Path <- Paths].
243244

244245
## Server Push
245246

246-
Server push allows the server to send resources before the client requests them. By default, hackney rejects server pushes. To handle them:
247-
248-
```erlang
249-
%% Using low-level API with push handler
250-
{ok, Conn} = hackney_conn:start_link(#{
251-
host => "example.com",
252-
port => 443,
253-
transport => hackney_ssl,
254-
enable_push => self() %% Receive push notifications
255-
}),
256-
257-
%% Push notifications arrive as messages:
258-
%% {hackney_push, ConnPid, {PromisedStreamId, Method, Scheme, Authority, Path, Headers}}
259-
```
247+
Server push (RFC 7540 §8.2) is deprecated and no longer supported by the
248+
underlying `h2` library. The `enable_push` option is accepted for
249+
backwards-compatibility but is a no-op; pushes from the server are silently
250+
refused.
260251

261252
## Flow Control
262253

@@ -275,11 +266,14 @@ HTTP/2 specific errors:
275266
case hackney:get(URL) of
276267
{ok, Status, Headers, Body} ->
277268
ok;
278-
{error, {h2_connection_error, ErrorCode}} ->
279-
%% HTTP/2 connection-level error
280-
io:format("HTTP/2 error: ~p~n", [ErrorCode]);
281-
{error, closed} ->
282-
%% Connection closed (GOAWAY received)
269+
{error, {goaway, ErrorCode}} ->
270+
%% Peer sent GOAWAY
271+
io:format("HTTP/2 GOAWAY: ~p~n", [ErrorCode]);
272+
{error, {stream_error, ErrorCode}} ->
273+
%% Peer sent RST_STREAM for this request
274+
io:format("HTTP/2 stream reset: ~p~n", [ErrorCode]);
275+
{error, {closed, _Reason}} ->
276+
%% Connection closed
283277
ok;
284278
{error, Reason} ->
285279
io:format("Error: ~p~n", [Reason])

rebar.config

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
{deps, [
6060
%% Pure Erlang QUIC + HTTP/3 stack
6161
{quic, "1.0.0"},
62+
%% Pure Erlang HTTP/2 stack
63+
{h2, "0.3.0"},
6264
{idna, "~>7.1.0"},
6365
{mimerl, "~>1.4"},
6466
{certifi, "~>2.16.0"},
@@ -115,7 +117,7 @@
115117
{exclude_mods, [hackney_metrics_prometheus]},
116118
{base_plt_apps, [erts, stdlib, kernel, crypto, runtime_tools]},
117119
{plt_apps, top_level_deps},
118-
{plt_extra_apps, [quic]},
120+
{plt_extra_apps, [quic, h2]},
119121
{plt_location, local},
120122
{plt_prefix, "hackney"},
121123
{base_plt_location, "."},

src/hackney.app.src

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
idna,
1616
mimerl,
1717
certifi,
18-
ssl_verify_fun]},
18+
ssl_verify_fun,
19+
h2]},
1920
{included_applications, []},
2021
{mod, { hackney_app, []}},
2122
{env, [{timeout, 150000},

0 commit comments

Comments
 (0)