Skip to content

Fix NameError in async-http adapter on protocol-http1 >= 0.40 - #1130

Merged
koic merged 1 commit into
bblimke:masterfrom
lesleh:fix-async-http-status-description
Aug 20, 2026
Merged

Fix NameError in async-http adapter on protocol-http1 >= 0.40#1130
koic merged 1 commit into
bblimke:masterfrom
lesleh:fix-async-http-status-description

Conversation

@lesleh

@lesleh lesleh commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #1129

What

protocol-http1 0.40.0 removed Protocol::HTTP1::Reason in favour of Protocol::HTTP::Status, but the async-http adapter still reads Protocol::HTTP1::Reason::DESCRIPTIONS when building a WebMock response. Any real response passing through the adapter raises:

NameError: uninitialized constant Protocol::HTTP1::Reason
  async_http_client_adapter.rb:115 in `build_webmock_response'
  • Resolves the description table on first use rather than at load, so it does not depend on which of the two libraries has been required by then, and works either side of protocol-http1 0.40.0.
  • spec/acceptance/async_http_client/async_http_client_spec_helper.rb carried the same reference in build_hash_response; it now goes through the same method.
  • Adds a regression test covering the status message itself.

Why it went unnoticed

Almost everything in the async-http suite is stubbed, and stubbed responses never reach build_webmock_response.

One existing example does reach it: allows a response with multiple values for the same header to be recorded and played back exactly as-is, which records a real response from WebMockServer. Without this change it fails with the NameError above, and in a full-file run the connection pool then never drains, so the run hangs instead of reporting the failure. That example asserts header and body equality, so it would not catch a wrong-but-present status message. The new test pins that specifically.

It surfaced for us via a library that recently moved its HTTP transport to async-http. Every pass-through request raised, and because the adapter sits underneath the HTTP client, the failure looked nothing like a WebMock problem.

Testing

Ruby 3.4.7, async-http 0.99.0, protocol-http1 0.40.2, NO_CONNECTION=1 so only the local examples run.

without the adapter fix with it
existing "multiple values for the same header" example, in isolation NameError at async_http_client_adapter.rb:115 passes
full async_http_client_spec.rb run hangs after that failure on Waiting for Async::HTTP::Protocol::HTTP pool to drain 313 examples, 1 failure (below)
new regression test NameError at async_http_client_adapter.rb:115 passes

The single remaining failure, should raise exception if request was made to different scheme, reproduces in isolation on a clean master checkout, so it is pre-existing and untouched here.

Out of scope

The net_connect: true examples that reach httpstat.us fail with EOFError raised from @network_client.call on this machine. They reproduce identically on an unmodified master, before and after this change.

# status description.
let(:server_url) { "http://#{WebMockServer.instance.host_with_port}/" }

after { WebMock.reset_callbacks }

@koic koic Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebMock.allow_net_connect! leaks to subsequent examples, since WebMock.reset! does not restore the net connect setting. Can you restore it in the after hook?

Suggested change
after { WebMock.reset_callbacks }
after do
WebMock.reset_callbacks
WebMock.disable_net_connect!
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks. WebMock.reset! only clears the stub and request registries, so the config flag survives the example. Applied your suggestion.

@lesleh lesleh Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@koic Worth flagging that the same leak already exists elsewhere: the two callback examples just above this one both call allow_net_connect! with nothing restoring it, and so does complex_cross_concern_behaviors.rb:3, which runs for every adapter. Nothing visibly breaks today, since the examples that follow are either stubbed or re-enter a context that disables it. Leaving it out of this PR, but flagging it in case you think it is worth a look.

protocol-http1 0.40.0 removed Protocol::HTTP1::Reason in favour of
Protocol::HTTP::Status, but the async-http adapter still reads
Protocol::HTTP1::Reason::DESCRIPTIONS when building a WebMock response.
Any real response passing through the adapter raises:

  NameError: uninitialized constant Protocol::HTTP1::Reason
    async_http_client_adapter.rb:115 in `build_webmock_response'

Stubbed responses never reach that method, so a suite stays green until
something makes a real request. It surfaced for us via a library that
recently moved its HTTP transport to async-http: every pass-through
request raised, and the failure looked nothing like a WebMock problem.

Resolves the description table on first use rather than at load, so it
does not depend on which of the two libraries is required by then, and
keeps working either side of protocol-http1 0.40.0.

The spec helper's build_hash_response had the same reference and is
routed through the same method.

One existing example does reach the broken line, the cross-concern one
that records a real response from WebMockServer and plays it back: on
master it fails with the NameError, and in a full-file run the
connection pool then never drains and the run hangs. The added
regression test pins the status message itself, which that example does
not assert.
@lesleh
lesleh force-pushed the fix-async-http-status-description branch from 3a40e9b to a50557e Compare August 20, 2026 16:02
@koic
koic merged commit f685e7e into bblimke:master Aug 20, 2026
8 checks passed
@koic

koic commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

async_http_client_adapter: NameError, Protocol::HTTP1::Reason removed in protocol-http1 0.40

2 participants