ruby-proxy-headers 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-proxy-headers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ProxyMesh
@@ -57,14 +57,14 @@ dependencies:
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '1.50'
60
+ version: '1.92'
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '1.50'
67
+ version: '1.92'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: yard
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -121,6 +121,20 @@ dependencies:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
123
  version: '3.4'
124
+ - !ruby/object:Gem::Dependency
125
+ name: http
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '6.0'
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '6.0'
124
138
  - !ruby/object:Gem::Dependency
125
139
  name: httparty
126
140
  requirement: !ruby/object:Gem::Requirement
@@ -149,20 +163,54 @@ dependencies:
149
163
  - - "~>"
150
164
  - !ruby/object:Gem::Version
151
165
  version: '2.14'
166
+ - !ruby/object:Gem::Dependency
167
+ name: rest-client
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '2.1'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '2.1'
180
+ - !ruby/object:Gem::Dependency
181
+ name: ethon
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: 0.19.1
187
+ - - "<"
188
+ - !ruby/object:Gem::Version
189
+ version: '0.20'
190
+ type: :development
191
+ prerelease: false
192
+ version_requirements: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: 0.19.1
197
+ - - "<"
198
+ - !ruby/object:Gem::Version
199
+ version: '0.20'
152
200
  - !ruby/object:Gem::Dependency
153
201
  name: typhoeus
154
202
  requirement: !ruby/object:Gem::Requirement
155
203
  requirements:
156
204
  - - "~>"
157
205
  - !ruby/object:Gem::Version
158
- version: '1.6'
206
+ version: '1.7'
159
207
  type: :development
160
208
  prerelease: false
161
209
  version_requirements: !ruby/object:Gem::Requirement
162
210
  requirements:
163
211
  - - "~>"
164
212
  - !ruby/object:Gem::Version
165
- version: '1.6'
213
+ version: '1.7'
166
214
  - !ruby/object:Gem::Dependency
167
215
  name: webmock
168
216
  requirement: !ruby/object:Gem::Requirement
@@ -186,11 +234,20 @@ extensions: []
186
234
  extra_rdoc_files: []
187
235
  files:
188
236
  - ".yardopts"
189
- - DEFERRED.md
190
- - IMPLEMENTATION_PRIORITY.md
191
- - LIBRARY_RESEARCH.md
237
+ - CHANGELOG.md
192
238
  - LICENSE
193
239
  - README.md
240
+ - docs/core-api.md
241
+ - docs/excon.md
242
+ - docs/faraday.md
243
+ - docs/getting-started.md
244
+ - docs/http-gem.md
245
+ - docs/httparty.md
246
+ - docs/index.md
247
+ - docs/net-http.md
248
+ - docs/rest-client.md
249
+ - docs/testing.md
250
+ - docs/typhoeus.md
194
251
  - lib/ruby_proxy_headers.rb
195
252
  - lib/ruby_proxy_headers/connection.rb
196
253
  - lib/ruby_proxy_headers/excon.rb
@@ -207,6 +264,9 @@ licenses:
207
264
  metadata:
208
265
  source_code_uri: https://github.com/proxymesh/ruby-proxy-headers
209
266
  documentation_uri: https://rubydoc.info/gems/ruby-proxy-headers
267
+ homepage_uri: https://github.com/proxymesh/ruby-proxy-headers
268
+ changelog_uri: https://github.com/proxymesh/ruby-proxy-headers/blob/main/CHANGELOG.md
269
+ bug_tracker_uri: https://github.com/proxymesh/ruby-proxy-headers/issues
210
270
  rdoc_options: []
211
271
  require_paths:
212
272
  - lib
@@ -214,14 +274,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
214
274
  requirements:
215
275
  - - ">="
216
276
  - !ruby/object:Gem::Version
217
- version: '3.1'
277
+ version: '3.2'
218
278
  required_rubygems_version: !ruby/object:Gem::Requirement
219
279
  requirements:
220
280
  - - ">="
221
281
  - !ruby/object:Gem::Version
222
282
  version: '0'
223
283
  requirements: []
224
- rubygems_version: 4.0.16
284
+ rubygems_version: 4.0.20
225
285
  specification_version: 4
226
286
  summary: Custom proxy CONNECT headers for Ruby HTTP clients (ProxyMesh, etc.)
227
287
  test_files: []
data/DEFERRED.md DELETED
@@ -1,29 +0,0 @@
1
- # Deferred / not fully supported
2
-
3
- ## Typhoeus / Ethon
4
-
5
- **Status:** Not implemented in this gem.
6
-
7
- [Ethon](https://github.com/typhoeus/ethon) does not expose `CURLOPT_PROXYHEADER` (or equivalent) in its `Ethon::Easy` option mapping as of ethon 0.18.x. Adding CONNECT response header capture would require Ethon/libcurl changes or a custom C extension.
8
-
9
- **Workaround:** Use `Net::HTTP` + {RubyProxyHeaders::NetHTTP.patch!} or Faraday with `ruby_proxy_headers_net_http` adapter.
10
-
11
- ---
12
-
13
- ## Mechanize
14
-
15
- **Status:** Not implemented.
16
-
17
- [Mechanize](https://github.com/sparklemotion/mechanize) uses [net-http-persistent](https://github.com/drbrain/net-http-persistent), which maintains its own connection layer on top of `Net::HTTP`. Our prepend patch targets `Net::HTTP#connect` on instances Mechanize creates, but verifying header propagation and lifecycle across the persistent pool needs dedicated work.
18
-
19
- **Workaround:** Use patched `Net::HTTP` or Faraday for fetches; use Mechanize only when custom CONNECT headers are not required.
20
-
21
- ---
22
-
23
- ## Excon — reading CONNECT response headers
24
-
25
- **Status:** Sending extra CONNECT headers is supported upstream via `:ssl_proxy_headers`.
26
-
27
- Excon’s public `Excon::Response` for the **origin** request does **not** include headers from the proxy’s `CONNECT` response (only the tunneled HTTPS response headers). Capturing `X-ProxyMesh-IP` from CONNECT would require patching Excon internals or a fork.
28
-
29
- **Workaround:** Use Net::HTTP / Faraday integrations in this gem, which merge CONNECT headers into the client response where applicable.
@@ -1,72 +0,0 @@
1
- # ruby-proxy-headers — implementation plan
2
-
3
- Prioritized roadmap for extension modules, aligned with [javascript-proxy-headers](https://github.com/proxymesh/javascript-proxy-headers) and [python-proxy-headers](https://github.com/proxymesh/python-proxy-headers).
4
-
5
- ## Architecture
6
-
7
- ```
8
- ┌─────────────────────────────────────────────────────────────┐
9
- │ ruby-proxy-headers │
10
- ├─────────────────────────────────────────────────────────────┤
11
- │ Faraday / HTTParty / Excon helpers │
12
- │ │ │
13
- │ ▼ │
14
- │ Net::HTTP patch — CONNECT send + capture + thread-local │
15
- └─────────────────────────────────────────────────────────────┘
16
- ```
17
-
18
- ## Phase 1 — Net::HTTP core (**done — v0.1+**)
19
-
20
- - `RubyProxyHeaders::NetHTTP.patch!` extends `Net::HTTP#connect` for HTTPS + proxy.
21
- - `last_proxy_connect_response_headers` on the `Net::HTTP` instance.
22
- - `Thread.current[:ruby_proxy_headers_connect_headers]` + `RubyProxyHeaders.proxy_connect_response_headers` for cross-library reads.
23
-
24
- **File:** `lib/ruby_proxy_headers/net_http.rb`
25
-
26
- ---
27
-
28
- ## Phase 2 — Faraday (**done — v0.2+**)
29
-
30
- - Adapter `ruby_proxy_headers_net_http` (subclass of `Faraday::Adapter::NetHttp`) merges CONNECT response headers into Faraday response headers.
31
- - Helper `RubyProxyHeaders::FaradayIntegration.connection(...)`.
32
-
33
- **File:** `lib/ruby_proxy_headers/faraday.rb`
34
-
35
- ---
36
-
37
- ## Phase 3 — HTTParty (**done — v0.2+**)
38
-
39
- - `RubyProxyHeaders::ProxyHeadersConnectionAdapter` — pass `proxy_connect_request_headers` in HTTParty options.
40
-
41
- **File:** `lib/ruby_proxy_headers/httparty.rb`
42
-
43
- ---
44
-
45
- ## Phase 4 — Typhoeus / Ethon (**deferred**)
46
-
47
- Ethon does not expose libcurl `CURLOPT_PROXYHEADER` in its option layer. See [DEFERRED.md](DEFERRED.md).
48
-
49
- ---
50
-
51
- ## Phase 5 — Excon (**partial — v0.2+**)
52
-
53
- - **Sending** extra CONNECT headers: supported upstream via `:ssl_proxy_headers`; `RubyProxyHeaders::ExconIntegration.get` passes them through.
54
- - **Reading** CONNECT response headers: not exposed on `Excon::Response` for the tunneled request. See [DEFERRED.md](DEFERRED.md).
55
-
56
- **File:** `lib/ruby_proxy_headers/excon.rb`
57
-
58
- ---
59
-
60
- ## Phase 6 — Mechanize (**deferred**)
61
-
62
- Uses `net-http-persistent`; needs dedicated integration. See [DEFERRED.md](DEFERRED.md).
63
-
64
- ---
65
-
66
- ## Testing
67
-
68
- `bundle exec ruby test/test_proxy_headers.rb` with `PROXY_URL` set. Modules: `net_http`, `faraday`, `httparty`, `excon` (excon is a smoke test; CONNECT response headers are not asserted).
69
-
70
- ---
71
-
72
- *Updated: March 2026*
data/LIBRARY_RESEARCH.md DELETED
@@ -1,71 +0,0 @@
1
- # Ruby library proxy header support (CONNECT tunnel)
2
-
3
- This document analyzes the Ruby HTTP / scraping stack used in [proxy-examples](https://github.com/proxymesh/proxy-examples/tree/main/ruby) for **custom headers on HTTPS `CONNECT`** and **reading the proxy `CONNECT` response headers**.
4
-
5
- ## Executive summary
6
-
7
- | Library | Native CONNECT header API | Extension approach |
8
- |---------|---------------------------|---------------------|
9
- | **Net::HTTP** (stdlib) | No — tunnel is hard-coded in `#connect` | **Implemented:** prepend patch; optional `proxy_connect_request_headers`; `last_proxy_connect_response_headers` |
10
- | **Faraday** | No — delegates to adapters (`net_http`, etc.) | **High:** use patched `Net::HTTP` with `Faraday.new(connection_options)` or custom adapter that sets `proxy_connect_request_headers` |
11
- | **HTTParty** | No — built on `Net::HTTP` | **High:** global or per-class `Net::HTTP` instances after `patch!`; or subclass `Connection` if needed |
12
- | **Mechanize** | No — uses `Net::HTTP` / persistent connections internally | **Medium–high:** ensure Mechanize’s internal HTTP object gets the same patched behavior and header accessors |
13
- | **Excon** | **Send:** yes — `:ssl_proxy_headers` on connection. **Read CONNECT response:** not exposed on origin `Excon::Response` | **Partial:** use `:ssl_proxy_headers` for sends; reading `X-ProxyMesh-IP` from CONNECT needs upstream Excon changes (see [DEFERRED.md](DEFERRED.md)) |
14
- | **Typhoeus / Ethon** | Partial — libcurl has proxy options | **Medium:** map headers to `CURLOPT_PROXYHEADER` / related options (libcurl version dependent); capture CONNECT response via callbacks or debug hooks where supported |
15
- | **Nokogiri** | N/A (XML/HTML parser only) | **N/A** — proxying is whatever HTTP client fetches the document (usually `Net::HTTP`) |
16
-
17
- As with Node and Python stacks, **none** of the high-level Ruby clients expose a first-class “proxy CONNECT request/response headers” API; extensions must hook **below** the HTTP library (stdlib `Net::HTTP`), **inside** Faraday’s adapter, or **at** the libcurl / Excon layer.
18
-
19
- ## Connection flow (HTTPS over HTTP proxy)
20
-
21
- ```
22
- Client -- CONNECT + custom headers --> Proxy
23
- Client <-- CONNECT response headers --- Proxy
24
- Client === TLS tunnel =================> Origin
25
- ```
26
-
27
- ## Net::HTTP (stdlib)
28
-
29
- MRI implements the tunnel in `Net::HTTP#connect` (see `net/http.rb`): it writes `CONNECT host:port`, `Host`, optional `Proxy-Authorization`, then reads the response with `Net::HTTPResponse.read_new` and calls `#value` without exposing headers to callers.
30
-
31
- **Feasibility:** High — same pattern as Python’s `HTTPSConnection._tunnel` override in `python-proxy-headers`.
32
-
33
- ## Faraday
34
-
35
- Uses adapters; default `net_http` adapter constructs `Net::HTTP`. If `Net::HTTP` is patched and exposes `proxy_connect_request_headers`, Faraday can pass options through `connection` / `request` options in a thin wrapper.
36
-
37
- **Feasibility:** High once `Net::HTTP` support is stable.
38
-
39
- ## HTTParty
40
-
41
- Uses `Net::HTTP` under the hood for sync requests. After `RubyProxyHeaders::NetHTTP.patch!`, new `Net::HTTP` objects support the new accessors.
42
-
43
- **Feasibility:** High — may need documented patterns for `default_options` and connection lifecycle.
44
-
45
- ## Mechanize
46
-
47
- Builds on `net/http` (often `net-http-persistent`). May require verifying that the patched `connect` runs for its connections and that response/header capture is visible on the right object.
48
-
49
- **Feasibility:** Medium.
50
-
51
- ## Excon
52
-
53
- Own implementation of proxy and TLS; does not use `Net::HTTP#connect`.
54
-
55
- **Feasibility:** Medium — requires a dedicated Excon middleware or socket layer similar to the JavaScript core agent.
56
-
57
- ## Typhoeus / Ethon (libcurl)
58
-
59
- libcurl can send additional headers to the proxy; exact options depend on libcurl version (e.g. proxy header lists). CONNECT response header visibility may require `CURLOPT_DEBUGFUNCTION` or version-specific features.
60
-
61
- **Feasibility:** Medium — needs research per libcurl version and Ethon API surface.
62
-
63
- ## Nokogiri
64
-
65
- Parsing only; no network layer.
66
-
67
- **Feasibility:** N/A — combine with `Net::HTTP` + patch or another extended client.
68
-
69
- ---
70
-
71
- *Last updated: March 2026*