Repository navigation
feat(net-http): keep-alive + timeouts + proxy - #183
Merged
Merged
Conversation
Extend the Net::HTTP transport binding with the deferred features, built on the existing socket/TLS transport: - Keep-alive: within Net::HTTP.start's block a single connection is reused across requests, each response framed by exact Content-Length / chunked encoding so the next request reads at the right offset; the connection is closed on #finish / block end, or when the server sends Connection: close. - Timeouts: open_timeout / read_timeout / write_timeout accessors set socket deadlines (open_timeout bounds the dial + TLS handshake); a timed-out open/read/write raises Net::OpenTimeout / Net::ReadTimeout / Net::WriteTimeout as MRI does. - Proxy: Net::HTTP.new(host, port, p_addr, p_port[, user, pass]) and the matching Net::HTTP.start proxy args; plain http emits an absolute-URI request-line to the proxy, https tunnels via CONNECT then TLS through it. proxy? / proxy_address / proxy_port / proxy_user / proxy_pass accessors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Route the class-level URL conveniences (get/post/...) through the same nethttpDoXfer transport as instance requests, removing the now-redundant one-shot nethttpDo / nethttpRoundTrip / nethttpDial / httpExchange so there is a single, fully-exercised request path. - Add hermetic proofs: keep-alive (3 requests, 1 accepted TCP connection), server-Connection:close fallback, stale-connection redial retry, read timeout (Net::ReadTimeout), open timeout, http proxy (absolute-URI request-line + Proxy-Authorization routed through a forwarding proxy) and https-via-CONNECT tunnel, plus unit coverage of every transport helper and error arm. 100% coverage on nethttp_bind.go. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nethttpExchangeFramed now reports which half (write/read) failed so a write-deadline timeout raises Net::WriteTimeout instead of being misreported as Net::ReadTimeout, matching MRI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hostHdr omits the port for a default-port target; CONNECT requires an explicit host:port, so build it from host + port. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tannevaled
added a commit
that referenced
this pull request
Jul 6, 2026
…y) (#198) Net::HTTP's p_addr now defaults to MRI's :ENV, resolving the proxy from the environment at request time instead of leaving the instance proxy-less (the item deferred by #183). - p_addr :ENV / omitted -> resolve from the environment against the instance's scheme (@use_ssl) and target host; nil/false -> no proxy; an explicit host String -> that fixed proxy (unchanged). - http requests read http_proxy/HTTP_PROXY, https requests read https_proxy/HTTPS_PROXY; the resolved userinfo becomes the Proxy-Authorization credentials. - no_proxy/NO_PROXY (comma/space list of hosts, leading-dot or bare domain suffixes, host:port qualifiers and CIDRs/IPs) forces a direct connection, mirroring URI::Generic.use_proxy?. - CGI-safety: when REQUEST_METHOD is set, the attacker-controllable uppercase HTTP_PROXY is ignored and only the lowercase http_proxy is honored (MRI's find_proxy rule). - proxy?/proxy_address/proxy_port/proxy_user/proxy_pass reflect the effective (explicit or env-resolved) proxy. Proven end-to-end through the VM against in-process httptest proxies (plain-http routing, https CONNECT tunnelling, no_proxy bypass, nil opt-out, CGI-safety) plus unit coverage of the resolver and no_proxy matcher; 100% coverage on the new code. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.
Extends the
Net::HTTPtransport binding (internal/vm/nethttp_bind.go, from #181) with the deferred features, MRI-faithful, on top of the existing socket/TLS transport.Keep-alive / persistent connections
Within
Net::HTTP.start(host, port) { |http| ... }a single connection is reused across requests. Each response is framed by its exact Content-Length or chunked Transfer-Encoding (a dedicated framed reader,nethttpReadResponse, that leaves following bytes buffered for the next request), so pipelined requests read at the right offset. The connection is cached on the instance (@conn), closed on#finish/ start-block teardown, and dropped when the server sendsConnection: close(or the body is unframed and read to EOF). A cached connection that fails a write/read is redialed once.Timeouts
open_timeout/read_timeout/write_timeoutaccessors (seconds; default 60, MRI's defaults) set socket deadlines.open_timeoutbounds the TCP dial and the TLS handshake. A timed-out open/read/write raisesNet::OpenTimeout/Net::ReadTimeout/Net::WriteTimeout.Proxy
Net::HTTP.new(host, port, p_addr, p_port[, user, pass])and the matchingNet::HTTP.startproxy args. Plain HTTP emits an absolute-URI request-line to the proxy (withProxy-Authorizationwhen credentials are given); HTTPS tunnels via CONNECT then runs TLS through the tunnel.proxy?/proxy_address/proxy_port/proxy_user/proxy_passaccessors.Proofs (hermetic, in-VM)
Extends the binding test suite with in-process
httptestservers: keep-alive asserts 3 requests in onestartblock share exactly 1 accepted TCP connection; a slow handler + shortread_timeoutraisesNet::ReadTimeout; a tiny in-test forwarding proxy asserts routing (plain HTTP) and a CONNECT tunnel.Deferred: environment-proxy (
:ENV) resolution.🤖 Generated with Claude Code