Skip to content

Send Typhoeus proxy headers with Ethon 0.19 proxyheader - #45

Draft
proxymeshai wants to merge 1 commit into
mainfrom
cursor/typhoeus-proxyheader-0de4
Draft

proxymeshai wants to merge 1 commit into
mainfrom
cursor/typhoeus-proxyheader-0de4

Conversation

@proxymeshai

Copy link
Copy Markdown
Collaborator

Draft. Native libcurl proxy headers for the Typhoeus adapter, based on main.

Summary

RubyProxyHeaders::Typhoeus used to send HTTPS requests with proxy headers through RubyProxyHeaders::NetHTTP.request, which is not defined. Ethon 0.19 (Typhoeus 1.7, released 2026-10-28) exposes :proxyheader (CURLOPT_PROXYHEADER) and :headeropt (:unified / :separate).

The adapter now:

  • Builds an Ethon::Curl::Slist from proxy_headers and passes it as :proxyheader with headeropt: :separate, so those headers are sent only to the proxy. On HTTPS, that is the CONNECT request. Application :headers stay on the tunneled request.
  • Parses the CONNECT response from the first header block of response_headers (the block whose status line says Connection established) and exposes it as proxy_response_headers with lowercase names, the same shape Net::HTTP uses. Typhoeus's response.headers remains the origin response only, so X-ProxyMesh-IP is read from proxy_response_headers.
  • Rejects CR, LF, and NUL in proxy header names and values before they reach libcurl.

Dependencies

The gemspec still has no runtime dependency on Typhoeus or Ethon. Callers install Typhoeus themselves. Development dependencies are now typhoeus ~> 1.7 and ethon ~> 0.19 (the adapter builds the slist through Ethon::Curl::Slist). The lockfile resolves typhoeus 1.7.1 and ethon 0.19.1. Typhoeus 1.7.1 requires ethon >= 0.19.1 because 0.19.0 rejected Easy#cleanup from on_complete.

Typhoeus 1.7's upgrade notes (callback exceptions, fork safety, enum validation) do not change this adapter's call shape. It does rely on 1.7's response.headers being the last header block.

Overlap with #43

Draft PR #43 (cursor/fix-connect-headers-53ba) is behind main and also edits lib/ruby_proxy_headers/typhoeus.rb, DEFERRED.md, README.md, docs/typhoeus.md, the gemspec, Gemfile.lock, and test/test_proxy_headers.rb. That branch routes Typhoeus HTTPS through patched Net::HTTP because Ethon 0.18 did not expose CURLOPT_PROXYHEADER. This PR supersedes that Typhoeus path with the native option. The two drafts will conflict if both land; the Net::HTTP, Faraday, and CI work in #43 is otherwise separate.

Tests

Ruby 3.2.3, Typhoeus 1.7.1, Ethon 0.19.1, libcurl 8.5.0:

  • bundle exec rspec — 34 examples, 0 failures, 6 pending (the pending examples are the existing unimplemented Connection.parse_proxy_url / build_auth_header cases).
  • spec/typhoeus_spec.rb stubs Typhoeus for option wiring and CONNECT-block parsing, and runs a local mock proxy plus TLS origin. CONNECT carried X-ProxyMesh-Country and did not carry X-App-Secret; the origin request carried X-App-Secret and did not carry X-ProxyMesh-Country; proxy_response_headers['x-proxymesh-ip'] was 203.0.113.10 and that name was absent from response.headers.
  • test/test_proxy_headers.rb now includes a typhoeus module for the live PROXY_URL harness. That harness was not run here (no proxy secret in this environment).

Left unresolved

  • Live ProxyMesh PROXY_URL integration was not executed.
  • Excon still cannot read CONNECT response headers, and Mechanize is still deferred (DEFERRED.md).
  • Version stays 0.2.3. The change is recorded under Unreleased.
Open in Web Open in Cursor 

Ethon 0.19 exposes CURLOPT_PROXYHEADER. Pass proxy headers as a
proxyheader list with headeropt: :separate, and read the CONNECT
response from the first response_headers block.

Co-authored-by: ProxyMesh AI <proxymeshai@users.noreply.github.com>
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.

2 participants