Default the :http backend to HTTP/1.1 on HTTP.jl 2.x#100
Merged
Conversation
HTTP.jl 2.x defaults to prefer_http2=true and its :auto ALPN silently upgrades any capable TLS server to HTTP/2. The streaming abort model added in #98 (interrupt the read task + close the stream when the consumer closes the channel) assumes one request per connection, as in HTTP/1.1. Over a reused HTTP/2 connection each aborted watch/streaming cycle leaves per-stream state behind, and after a few cycles the shared connection read loop wedges (observed as a hung Kubernetes watch: the socket in CLOSE-WAIT with the h2 read loop parked in read_frame!). Pin the transport to HTTP/1.1 (protocol=:h1) for both the plain and streaming request paths, guarded by the existing _HTTP_V2 check (1.x has no protocol keyword). The choice is overridable per client via the :http_protocol option (:auto or :h2) for callers who want the 2.x default.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
HTTP.jl 2.x defaults to
prefer_http2=true, and its:autoALPN transparently upgrades any capable TLS server to HTTP/2 — callers (and generated clients like Kuber.jl) never ask for it.The streaming-abort model added in #98 — interrupt the read task and
closethe stream when the consumer closes the channel — assumes one request per connection, which holds on HTTP/1.1. Over a reused, multiplexed HTTP/2 connection, each aborted watch/streaming cycle leaves per-stream state behind. After a few cycles the shared connection's read loop wedges.Fix
Pin the transport to HTTP/1.1 (
protocol=:h1) for both request paths (_http_requestand_http_streaming_request), guarded by the existing_HTTP_V2check (HTTP 1.x has noprotocolkeyword).HTTP.openforwards kwargs to the request layer, so it threads through the streaming path too.The choice is overridable per client via a new
:http_protocolclient option (:autoor:h2) for callers who want the 2.x default:No change required in downstream callers — the
:h1default carries the fix.Why default to h1 rather than scope it to streaming
The evidence directly implicates the streaming/abort path, but I default both paths to
:h1: they share one connection pool, HTTP/1.1 is the conventional and well-tested transport. Callers who want HTTP/2 opt back in explicitly.