Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ unreleased
- Unregistering a pooled HTTP/2 connection no longer leaks its per-host slot.
The pool dropped its monitor on the connection, so the slot was never
released when the connection stopped.
- A response that crosses a reset of its stream no longer closes the HTTP/2
connection. `h2` dropped the header block of that response without decoding
it, so the next response on the connection failed with COMPRESSION_ERROR.
- A request that races a peer-initiated close now returns `{error, closed}`
instead of `{error, invalid_state}`. A connection that sees the peer close
stays alive briefly so late calls get an answer, and during that window every
Expand All @@ -22,6 +25,10 @@ unreleased
was gone, `{error, invalid_state}` while it lingered. Callers can now tell a
closed connection from a misuse of the API (#932, #933, thanks @kpy3).

### Changed

- Update `h2` to 0.12.1.

4.7.4 - 2026-08-12
------------------

Expand Down
2 changes: 1 addition & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
%% Pure Erlang QUIC + HTTP/3 stack
{quic, "~>1.8.0"},
%% Pure Erlang HTTP/2 stack
{h2, "~>0.12.0"},
{h2, "~>0.12.1"},
%% WebTransport client (HTTP/3 and HTTP/2) - powers the wt_* API
{webtransport, "~>0.4.5"},
{idna, "~>7.1.0"},
Expand Down
8 changes: 5 additions & 3 deletions test/hackney_http2_shared_conn_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ dead_async_consumer() ->
receive stop -> ok end
end),
receive async_sent -> ok after 5000 -> error(no_async_request) end,
%% The handler never answers: a response crossing the client's
%% RST_STREAM is a separate h2 HPACK issue, not what this covers.
{_AsyncHandler, _} = started(<<"/async">>),
{AsyncHandler, _} = started(<<"/async">>),
Conn = shared_conn(Opts, Port),
?assert(lists:member(Consumer, monitored(Conn))),
exit(Consumer, kill),
ok = wait_until(fun() -> not lists:member(Consumer, monitored(Conn)) end),
%% Answer the reset stream: the response can cross the client's
%% RST_STREAM, and its header block must still be decoded or the
%% next response fails with COMPRESSION_ERROR (fixed in h2 0.12.1).
AsyncHandler ! respond,
?assertMatch({ok, 200, _, <<"ok">>},
hackney:request(get, <<URL/binary, "/fast">>, [], <<>>, Opts)),
?assertEqual(Conn, shared_conn(Opts, Port))
Expand Down
Loading