Skip to content

test(http-agent): cover HTTPS upstream proxies with real server - #742

Merged
bliuchak merged 3 commits into
masterfrom
claude/sharp-cannon-svll17
Nov 7, 2026
Merged

bliuchak merged 3 commits into
masterfrom
claude/sharp-cannon-svll17

Conversation

@bliuchak

@bliuchak bliuchak commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Closes #620

What

Replaces the HTTPS upstream smoke test in test/e2e/http-agent.ts, which pointed at a non-existent host, with three tests against a real local HTTPS upstream (proxy-chain itself with serverType: 'https'):

  • Forward mode pools connections. Three plain HTTP requests with a keepAlive httpsAgent reach the upstream over one TLS connection.
  • The agent from prepareRequestFunction is the one used. With keepAlive: false the same requests open three connections, so a regression that falls back to https.globalAgent fails.
  • Chain mode works through an HTTPS upstream. HTTPS targets are tunnelled via CONNECT, and every tunnel gets its own upstream connection.

Also adds a README note: pooling depends on the target URL, not on the upstream proxy's protocol. Requests for http:// URLs are pooled through both HTTP and HTTPS upstreams. Requests for https:// URLs go through CONNECT tunnels, and a connection that has carried a tunnel is never returned to the agent's pool, so each tunnel gets its own upstream connection. Requests inside one tunnel share its connection.

Why

#619 added agent pooling but left HTTPS upstreams untested in both forward and chain mode (see the review in #619 (comment)). The old test passed on any failure, so it proved only that the code path does not crash.

How

Testing

  • Full suite run in the Docker image (test/Dockerfile, Node 20): http-agent.ts 8/8 pass, and 5/5 repeated runs of the file pass. The only failures are the 3 SOCKS tests that also fail on master (they depend on example.com, see Replace example.com with api.apify.com/v2/browser-info in the SOCKS e2e tests #739 / test(socks): use api.apify.com/v2/browser-info instead of example.com #740).
  • pnpm run type-check and eslint pass.
  • Line coverage of src/ does not change meaningfully. The lines these tests exercise were already covered; what was missing were assertions that pooling over an HTTPS upstream actually works.
  • I checked the behaviour behind the README note with plain http(s).request CONNECT calls, shaped like the one in src/chain.ts, on Node 20, 22, 24 and 26, with HTTP and HTTPS upstreams and 200 and 407 responses. A tunnel connection was never reused afterwards. With an HTTP upstream, a CONNECT can take an idle pooled connection, which is then dedicated to that tunnel. "Each tunnel gets its own upstream connection" covers both cases.

Risks

Tests and docs only, no change in src/. The chain-mode test partly asserts Node.js behaviour (tunnel sockets leave the agent's pool), which matches what the README now documents.

🤖 Generated with Claude Code

Closes #620

Replace the smoke test that pointed at a non-existent HTTPS upstream with
tests against a local proxy-chain server running with serverType 'https':

- forward mode pools connections to the HTTPS upstream with a keepAlive agent
- keepAlive: false opens a connection per request, proving the agent from
  prepareRequestFunction is used instead of https.globalAgent
- chain mode tunnels HTTPS targets through the HTTPS upstream; each CONNECT
  gets its own upstream connection because Node.js detaches tunnel sockets
  from the agent

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEAC7cYnarj1ZUc9hEf
A connection that has carried a CONNECT tunnel is never returned to the
agent's pool, so HTTPS targets get a connection per tunnel even with
keepAlive. Sticky IPs through connection reuse apply to plain HTTP only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEAC7cYnarj1ZUc9hEf
@apify-service-account apify-service-account added the tested Temporary label used only programatically for some analytics. label Nov 7, 2026
@apify-service-account apify-service-account added the t-unblocking Issues with this label are in the ownership of the unblocking team. label Nov 7, 2026
…m protocol

The note said "HTTPS request", which reads as if HTTPS upstream proxies do
not pool. They do for http:// targets. Only https:// targets, sent as
CONNECT tunnels, get a connection per tunnel. Also drop the claim that
sticky IPs apply to plain HTTP only: requests inside one tunnel share its
connection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEAC7cYnarj1ZUc9hEf
@bliuchak
bliuchak merged commit cc00adb into master Nov 7, 2026
13 checks passed
@bliuchak
bliuchak deleted the claude/sharp-cannon-svll17 branch November 7, 2026 19:07
@bliuchak bliuchak added the validated Issues that are resolved and their solutions fulfill the acceptance criteria. label Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-unblocking Issues with this label are in the ownership of the unblocking team. tested Temporary label used only programatically for some analytics. validated Issues that are resolved and their solutions fulfill the acceptance criteria.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add HTTPS Test Coverage for HTTP Agent Pooling

4 participants