ruby-proxy-headers 0.2.2 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +49 -0
- data/README.md +48 -1
- data/docs/core-api.md +184 -0
- data/docs/excon.md +29 -0
- data/docs/faraday.md +29 -0
- data/docs/getting-started.md +66 -0
- data/docs/http-gem.md +126 -0
- data/docs/httparty.md +35 -0
- data/docs/index.md +109 -0
- data/docs/net-http.md +29 -0
- data/docs/rest-client.md +96 -0
- data/docs/testing.md +105 -0
- data/docs/typhoeus.md +47 -0
- data/lib/ruby_proxy_headers/connection.rb +1 -8
- data/lib/ruby_proxy_headers/faraday.rb +19 -16
- data/lib/ruby_proxy_headers/http_gem.rb +61 -40
- data/lib/ruby_proxy_headers/net_http.rb +76 -131
- data/lib/ruby_proxy_headers/rest_client.rb +76 -60
- data/lib/ruby_proxy_headers/typhoeus.rb +81 -74
- data/lib/ruby_proxy_headers/version.rb +1 -1
- data/lib/ruby_proxy_headers.rb +45 -0
- metadata +70 -10
- data/DEFERRED.md +0 -29
- data/IMPLEMENTATION_PRIORITY.md +0 -72
- data/LIBRARY_RESEARCH.md +0 -71
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
-
|
|
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.
|
|
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.
|
|
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.
|
data/IMPLEMENTATION_PRIORITY.md
DELETED
|
@@ -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*
|