rack-proxy 0.8.3 → 1.0.1
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 +184 -0
- data/LICENSE +1 -1
- data/README.md +254 -166
- data/SECURITY.md +52 -0
- data/lib/rack/http_streaming_response.rb +137 -17
- data/lib/rack/proxy/version.rb +7 -0
- data/lib/rack/proxy.rb +239 -63
- data/lib/rack-proxy.rb +3 -1
- data/rack-proxy.gemspec +20 -16
- metadata +24 -27
- data/.github/FUNDING.yml +0 -3
- data/.gitignore +0 -3
- data/.travis.yml +0 -18
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -31
- data/Rakefile +0 -14
- data/lib/net_http_hacked.rb +0 -90
- data/lib/rack_proxy_examples/example_service_proxy.rb +0 -40
- data/lib/rack_proxy_examples/forward_host.rb +0 -24
- data/lib/rack_proxy_examples/rack_php_proxy.rb +0 -37
- data/lib/rack_proxy_examples/trusting_proxy.rb +0 -25
- data/test/http_streaming_response_test.rb +0 -50
- data/test/net_http_hacked_test.rb +0 -36
- data/test/rack_proxy_test.rb +0 -358
- data/test/test_helper.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec993cb1f75831f1f7270d06634ba8c94b40246af6a622e239e29ddd2ff74e20
|
|
4
|
+
data.tar.gz: e5105cdc0ce7f69fb47b36e483dde1bad7799ff90f052566e526cc65d99fe7b5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 701b98893deaf804c09f965a6ad12d3a7c219be357bfd1d3457beeab4598af699863b44df149a0d4c5c433dab75cdb3ee080a9503e9916142adb7a60ba3b8bf8
|
|
7
|
+
data.tar.gz: e75ba8fe0ed1beaa2aa480f3f19805e3a8be98c8ed05af84e9b00e6812b420a67d8d102031afcff78c23026193a43354b20126477e40d9f41ab50514ec0b8acc
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project aims to
|
|
5
|
+
follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
Nothing yet.
|
|
10
|
+
|
|
11
|
+
## [1.0.1] - 2026-07-23
|
|
12
|
+
|
|
13
|
+
Docs and housekeeping — no library behavior changes.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- README modernized: badges, quick start, a "How it works" pipeline overview,
|
|
18
|
+
grouped options, and tightened recipes.
|
|
19
|
+
- Removed the internal modernization roadmap document, completed by 1.0.0.
|
|
20
|
+
- Development dependencies refreshed (rake 13.4.2, test-unit 3.7.8,
|
|
21
|
+
rack-test 2.2.0) and CI bumped to `actions/checkout@v7`. (#136–#139)
|
|
22
|
+
|
|
23
|
+
## [1.0.0] - 2026-07-18
|
|
24
|
+
|
|
25
|
+
The 2026 modernization + security-hardening release. From 1.0.0 on this
|
|
26
|
+
project follows SemVer strictly: breaking changes only in majors.
|
|
27
|
+
|
|
28
|
+
### Breaking changes
|
|
29
|
+
|
|
30
|
+
Read this list before upgrading from 0.8.x; everything else below is additive
|
|
31
|
+
or a compatible fix. See the README's "Upgrading" section for migration steps.
|
|
32
|
+
|
|
33
|
+
- **Host-derived (dynamic) backends are refused by default.** With no
|
|
34
|
+
`:backend` and no `env["rack.backend"]`, requests now get `502` unless you
|
|
35
|
+
pass `allow_dynamic_backend: true`. A bare `Rack::Proxy.new` is no longer an
|
|
36
|
+
open proxy. Combine the opt-in with a `backend_allowed?` allowlist.
|
|
37
|
+
- **`net_http_hacked` is gone** — the file, `require "net_http_hacked"`, and
|
|
38
|
+
the `begin_request_hacked`/`end_request_hacked` methods (see Removed).
|
|
39
|
+
- **The bundled examples left the gem** — `require "rack_proxy_examples/..."`
|
|
40
|
+
raises `LoadError`; copy the snippets from `examples/` instead (see Removed).
|
|
41
|
+
- **Backend failures no longer raise.** `OpenSSL::SSL::SSLError`, `EOFError`,
|
|
42
|
+
timeouts, resets, and malformed backend responses now become a `502` triplet
|
|
43
|
+
instead of an exception — `rescue`-based error handling around `proxy.call`
|
|
44
|
+
must inspect the status instead.
|
|
45
|
+
- **Hop-by-hop request headers are no longer forwarded** (`Connection`, `TE`,
|
|
46
|
+
`Transfer-Encoding`, `Proxy-Authorization`, `Upgrade`, anything named by
|
|
47
|
+
`Connection`).
|
|
48
|
+
- **gzip backend bodies are forwarded verbatim in `streaming: false` mode**
|
|
49
|
+
(previously they were transparently inflated); `rewrite_response` hooks that
|
|
50
|
+
read body text must inflate it themselves.
|
|
51
|
+
- **Supported runtimes: Ruby >= 3.0 and Rack >= 2.0, < 4** (was Ruby >= 2.6,
|
|
52
|
+
rack unpinned).
|
|
53
|
+
- Smaller wire/API changes: body-less POST/PUT sends `Content-Length: 0` on
|
|
54
|
+
the streaming path; the streaming body is thread-affine (iterate it on the
|
|
55
|
+
thread that called the app, as mainstream servers do); `HttpStreamingResponse`
|
|
56
|
+
raises `IOError` on use-after-close; early termination closes the backend
|
|
57
|
+
connection instead of draining it.
|
|
58
|
+
|
|
59
|
+
### Security
|
|
60
|
+
|
|
61
|
+
- Refuse Host-derived backends unless `allow_dynamic_backend: true` is set
|
|
62
|
+
(see Breaking changes) — closes the default open-proxy/SSRF pivot.
|
|
63
|
+
- Strip hop-by-hop headers from the **forwarded request** (Connection, TE,
|
|
64
|
+
Transfer-Encoding, Proxy-Authorization, …, plus any header named by the inbound
|
|
65
|
+
`Connection` header), closing a Content-Length/Transfer-Encoding request-smuggling
|
|
66
|
+
surface. Hop-by-hop headers were previously stripped only from the response.
|
|
67
|
+
- Add `backend_allowed?(backend)` — an overridable per-request allowlist hook,
|
|
68
|
+
consulted for every request (static backends included). A refused backend
|
|
69
|
+
responds `502`.
|
|
70
|
+
- Add `:max_response_length` to cap the backend response size (bounds memory
|
|
71
|
+
against a hostile/huge backend). Enforced incrementally while streaming.
|
|
72
|
+
- Add `:ca_file` / `:cert_store` so private-CA backends can be verified under the
|
|
73
|
+
default `VERIFY_PEER` instead of disabling verification.
|
|
74
|
+
- Add `:open_timeout` / `:write_timeout` to bound connect and per-write stalls
|
|
75
|
+
(previously only `:read_timeout` was configurable).
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- `:min_version` / `:max_version` TLS options (mapping to `Net::HTTP#min_version=`
|
|
80
|
+
/ `#max_version=`). `:ssl_version` still works but is deprecated (it pins an
|
|
81
|
+
exact protocol and forbids TLS 1.3).
|
|
82
|
+
- `HttpStreamingResponse#close` so Rack servers release the backend connection on
|
|
83
|
+
early termination (HEAD, 304, client disconnect) instead of leaking it until GC.
|
|
84
|
+
- Opt-in request hardening: `strip_credentials: true` drops the client's
|
|
85
|
+
`Cookie`/`Authorization` headers from the forwarded request, and
|
|
86
|
+
`replace_x_forwarded_for: true` forwards only this hop's `REMOTE_ADDR`
|
|
87
|
+
instead of appending to the client-supplied `X-Forwarded-For` chain.
|
|
88
|
+
- Project scaffolding: `SECURITY.md`, `CHANGELOG.md`, `CONTRIBUTING.md`,
|
|
89
|
+
`CLAUDE.md`/`AGENTS.md`, GitHub Actions CI (Ruby 3.1–3.4 × Rack 2/3),
|
|
90
|
+
Dependabot, issue/PR templates, SimpleCov with a ratcheted coverage floor
|
|
91
|
+
(`COVERAGE=1`), and Standard (`standardrb`) + `bundler-audit` enforced by a
|
|
92
|
+
CI lint job.
|
|
93
|
+
|
|
94
|
+
### Changed
|
|
95
|
+
|
|
96
|
+
- **The streaming path no longer monkey-patches `net/http`.**
|
|
97
|
+
`Rack::HttpStreamingResponse` now runs the public block form of
|
|
98
|
+
`Net::HTTP#request` inside a Fiber (pausing at the response head, resuming
|
|
99
|
+
per body chunk), replacing the 2010-era patch of private `net/http` internals
|
|
100
|
+
in `net_http_hacked.rb`. Behavioral notes: the streaming session sets
|
|
101
|
+
`max_retries = 0` so a transport error can never silently replay the request
|
|
102
|
+
mid-stream; early termination (client abort, HEAD, 204/304) now closes
|
|
103
|
+
the backend connection immediately instead of draining the remaining body;
|
|
104
|
+
and a body-less POST/PUT/PATCH on the streaming path now carries
|
|
105
|
+
`Content-Length: 0` (matching the non-streaming path and plain `Net::HTTP` —
|
|
106
|
+
the old patched path sent no `Content-Length` at all).
|
|
107
|
+
- Backend and construction failures now map to status codes instead of raising a
|
|
108
|
+
`500`: `400` (malformed request URI), `501` (unknown HTTP method), `502`
|
|
109
|
+
(broadened backend-error set incl. `ECONNRESET`, `EPIPE`, read/write timeouts,
|
|
110
|
+
`EOFError`, `OpenSSL::SSL::SSLError`, protocol errors, and malformed backend
|
|
111
|
+
responses — `Net::HTTPBadResponse` / `Net::HTTPHeaderSyntaxError`).
|
|
112
|
+
- gzip-encoded backend responses are forwarded verbatim (Content-Encoding and
|
|
113
|
+
Content-Length preserved) instead of being transparently inflated.
|
|
114
|
+
- Skip all `1xx` interim responses (including `103 Early Hints`) on the streaming
|
|
115
|
+
path, so a backend's `103` is no longer mistaken for the final response.
|
|
116
|
+
- `rack` dependency constrained to `>= 2.0, < 4`; the library now `require`s rack
|
|
117
|
+
itself.
|
|
118
|
+
- Test suite is fully offline (local WEBrick server); the previous live-host
|
|
119
|
+
tests are gated behind `LIVE=1`.
|
|
120
|
+
|
|
121
|
+
### Deprecated
|
|
122
|
+
|
|
123
|
+
- `:ssl_version` — use `:min_version` / `:max_version`.
|
|
124
|
+
|
|
125
|
+
### Removed
|
|
126
|
+
|
|
127
|
+
- `lib/net_http_hacked.rb` — the 2010-era monkey-patch of private `Net::HTTP`
|
|
128
|
+
internals. The library stopped using it when streaming moved to the public
|
|
129
|
+
`Net::HTTP` API (see Changed); `require "net_http_hacked"` and the
|
|
130
|
+
`begin_request_hacked` / `end_request_hacked` methods are gone. If external
|
|
131
|
+
code still depends on them, vendor the file from a 0.8.x release — and plan
|
|
132
|
+
to migrate; it breaks under modern net/http refactors.
|
|
133
|
+
|
|
134
|
+
- The bundled examples moved from the gem load path
|
|
135
|
+
(`lib/rack_proxy_examples/`) to [`examples/`](examples/) in the repository.
|
|
136
|
+
`require "rack_proxy_examples/..."` no longer works — copy the example class
|
|
137
|
+
into your app instead (they were never safe to require blindly: each one
|
|
138
|
+
installs itself into the Rails middleware stack when Rails is booted).
|
|
139
|
+
|
|
140
|
+
## [0.8.3] - 2025
|
|
141
|
+
|
|
142
|
+
### Fixed
|
|
143
|
+
|
|
144
|
+
- Handle non-rewindable request body streams (Rack 3 input streams need not
|
|
145
|
+
respond to `#rewind`). (#128)
|
|
146
|
+
|
|
147
|
+
## [0.8.2] - 2025
|
|
148
|
+
|
|
149
|
+
### Fixed
|
|
150
|
+
|
|
151
|
+
- Harden `build_header_hash` against a top-level `::Headers` constant defined by
|
|
152
|
+
the host app being picked up instead of `Rack::Headers`.
|
|
153
|
+
|
|
154
|
+
## [0.8.1] - 2025
|
|
155
|
+
|
|
156
|
+
### Added
|
|
157
|
+
|
|
158
|
+
- `:logger` option, wired to `Net::HTTP#set_debug_output` for wire-level debug
|
|
159
|
+
output. (#80)
|
|
160
|
+
|
|
161
|
+
## [0.8.0] - 2025
|
|
162
|
+
|
|
163
|
+
### Changed
|
|
164
|
+
|
|
165
|
+
- **BREAKING:** TLS certificate verification now defaults to `VERIFY_PEER`
|
|
166
|
+
(Ruby's `Net::HTTP` default). Previous versions silently used `VERIFY_NONE` for
|
|
167
|
+
HTTPS backends. Pass `ssl_verify_none: true` (or `verify_mode:`) to opt out. (#113)
|
|
168
|
+
|
|
169
|
+
### Fixed
|
|
170
|
+
|
|
171
|
+
- Return `502` on backend connection errors instead of raising; correct body
|
|
172
|
+
handling for empty responses and no-entity-body statuses (1xx/204/304). (#58, #122, #123)
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
Older releases (≤ 0.7.8) predate this changelog; see the git history and tags.
|
|
177
|
+
|
|
178
|
+
[Unreleased]: https://github.com/ncr/rack-proxy/compare/v1.0.1...HEAD
|
|
179
|
+
[1.0.1]: https://github.com/ncr/rack-proxy/compare/v1.0.0...v1.0.1
|
|
180
|
+
[1.0.0]: https://github.com/ncr/rack-proxy/compare/v0.8.3...v1.0.0
|
|
181
|
+
[0.8.3]: https://github.com/ncr/rack-proxy/compare/v0.8.2...v0.8.3
|
|
182
|
+
[0.8.2]: https://github.com/ncr/rack-proxy/compare/v0.8.1...v0.8.2
|
|
183
|
+
[0.8.1]: https://github.com/ncr/rack-proxy/compare/v0.8.0...v0.8.1
|
|
184
|
+
[0.8.0]: https://github.com/ncr/rack-proxy/compare/v0.7.8...v0.8.0
|
data/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2010-2026 Jacek Becela and contributors jacek.becela@gmail.com
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|