rack-proxy 0.8.2 → 1.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40c24e4b559fc7669c3b675184af8d7f0b9ba693d3a7b41e6433274c16429adc
4
- data.tar.gz: 6f8790c5c391e102275c11225a869e2572d109f2e52e4783cdc5cbbb50733579
3
+ metadata.gz: 3c875bfa1e0a111ffd460f491dd469b647b8eec3aeed9fe6fab60db8b7d40f27
4
+ data.tar.gz: cdecda577e3d8f9a5216822792f4e406b58168e82e151f9c876dbfeb1a84f66d
5
5
  SHA512:
6
- metadata.gz: 2885f787b2f08c712c99b938218749d7f5d35348588290414f058c446104e10ba80b7f0b439ea60c3fc4daea1a0b0f991c92e853a3a9de4ef238d5f864d85d20
7
- data.tar.gz: 3f70b5ab5eee94517d10e82f72f517a7e4cd3fec346ba78142ed6d93bd34bb7d175f6e857c037c7b0beffd710889651f15d107920e38da7208bdc132f246f712
6
+ metadata.gz: d5c20ab2119c472da460237bc3b731d09023e7805fe6a7f3a122209b3ce8a694ca1d1f5f6c328694b0b440628f08854507b2618e506ff35343fc6cc189cce52e
7
+ data.tar.gz: 745e5f847a9514d1524d11e272c4866576530c3734d106ef7818de84d9718d38ac5ffef664d86c8fe9e468dda19868ce2250bf847dc4e71e0124ea604e69cf08
data/CHANGELOG.md ADDED
@@ -0,0 +1,221 @@
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.3] - 2026-09-25
12
+
13
+ ### Security
14
+
15
+ - Reject backend responses carrying both `Transfer-Encoding` and
16
+ `Content-Length` with `502` in streaming and non-streaming mode. This prevents
17
+ an attacker-controlled length from framing a dechunked downstream response
18
+ (GHSA-42qh-8mx8-7wqm). Rejected streaming responses close the backend connection.
19
+ - Strip response headers named by all backend `Connection` fields, in addition
20
+ to the standard hop-by-hop headers.
21
+
22
+ This is a targeted security backport for 1.x; successful response status types,
23
+ header representations, request framing, and retry behavior remain unchanged.
24
+ Versions 2.0.0 and later already reject the ambiguous response framing.
25
+
26
+ ## [1.0.2] - 2026-09-01
27
+
28
+ Housekeeping — no library behavior changes. **No action is needed by users:**
29
+ the shipped gem does not depend on `json` and was never affected by the
30
+ advisory below.
31
+
32
+ ### Security
33
+
34
+ - Development dependency `json` bumped 2.21.1 → 2.21.2 to clear
35
+ CVE-2026-71847 / GHSA-9hj4-r449-hfvc (`JSON::ResumableParser#partial_value`
36
+ dereferences a freed input buffer on truncated duplicate-key streams).
37
+ `json` reaches this repo only transitively (`standard` → `rubocop` → `json`)
38
+ and lives solely in the development `Gemfile.lock`; the bump keeps the CI
39
+ `bundler-audit` gate green.
40
+
41
+ ### Changed
42
+
43
+ - Release workflow: the laggy rubygems full-index await was replaced with a
44
+ versions-API check, so a successful publish no longer fails the run. (#142)
45
+
46
+ ## [1.0.1] - 2026-07-23
47
+
48
+ Docs and housekeeping — no library behavior changes.
49
+
50
+ ### Changed
51
+
52
+ - README modernized: badges, quick start, a "How it works" pipeline overview,
53
+ grouped options, and tightened recipes.
54
+ - Removed the internal modernization roadmap document, completed by 1.0.0.
55
+ - Development dependencies refreshed (rake 13.4.2, test-unit 3.7.8,
56
+ rack-test 2.2.0) and CI bumped to `actions/checkout@v7`. (#136–#139)
57
+
58
+ ## [1.0.0] - 2026-07-18
59
+
60
+ The 2026 modernization + security-hardening release. From 1.0.0 on this
61
+ project follows SemVer strictly: breaking changes only in majors.
62
+
63
+ ### Breaking changes
64
+
65
+ Read this list before upgrading from 0.8.x; everything else below is additive
66
+ or a compatible fix. See the README's "Upgrading" section for migration steps.
67
+
68
+ - **Host-derived (dynamic) backends are refused by default.** With no
69
+ `:backend` and no `env["rack.backend"]`, requests now get `502` unless you
70
+ pass `allow_dynamic_backend: true`. A bare `Rack::Proxy.new` is no longer an
71
+ open proxy. Combine the opt-in with a `backend_allowed?` allowlist.
72
+ - **`net_http_hacked` is gone** — the file, `require "net_http_hacked"`, and
73
+ the `begin_request_hacked`/`end_request_hacked` methods (see Removed).
74
+ - **The bundled examples left the gem** — `require "rack_proxy_examples/..."`
75
+ raises `LoadError`; copy the snippets from `examples/` instead (see Removed).
76
+ - **Backend failures no longer raise.** `OpenSSL::SSL::SSLError`, `EOFError`,
77
+ timeouts, resets, and malformed backend responses now become a `502` triplet
78
+ instead of an exception — `rescue`-based error handling around `proxy.call`
79
+ must inspect the status instead.
80
+ - **Hop-by-hop request headers are no longer forwarded** (`Connection`, `TE`,
81
+ `Transfer-Encoding`, `Proxy-Authorization`, `Upgrade`, anything named by
82
+ `Connection`).
83
+ - **gzip backend bodies are forwarded verbatim in `streaming: false` mode**
84
+ (previously they were transparently inflated); `rewrite_response` hooks that
85
+ read body text must inflate it themselves.
86
+ - **Supported runtimes: Ruby >= 3.0 and Rack >= 2.0, < 4** (was Ruby >= 2.6,
87
+ rack unpinned).
88
+ - Smaller wire/API changes: body-less POST/PUT sends `Content-Length: 0` on
89
+ the streaming path; the streaming body is thread-affine (iterate it on the
90
+ thread that called the app, as mainstream servers do); `HttpStreamingResponse`
91
+ raises `IOError` on use-after-close; early termination closes the backend
92
+ connection instead of draining it.
93
+
94
+ ### Security
95
+
96
+ - Refuse Host-derived backends unless `allow_dynamic_backend: true` is set
97
+ (see Breaking changes) — closes the default open-proxy/SSRF pivot.
98
+ - Strip hop-by-hop headers from the **forwarded request** (Connection, TE,
99
+ Transfer-Encoding, Proxy-Authorization, …, plus any header named by the inbound
100
+ `Connection` header), closing a Content-Length/Transfer-Encoding request-smuggling
101
+ surface. Hop-by-hop headers were previously stripped only from the response.
102
+ - Add `backend_allowed?(backend)` — an overridable per-request allowlist hook,
103
+ consulted for every request (static backends included). A refused backend
104
+ responds `502`.
105
+ - Add `:max_response_length` to cap the backend response size (bounds memory
106
+ against a hostile/huge backend). Enforced incrementally while streaming.
107
+ - Add `:ca_file` / `:cert_store` so private-CA backends can be verified under the
108
+ default `VERIFY_PEER` instead of disabling verification.
109
+ - Add `:open_timeout` / `:write_timeout` to bound connect and per-write stalls
110
+ (previously only `:read_timeout` was configurable).
111
+
112
+ ### Added
113
+
114
+ - `:min_version` / `:max_version` TLS options (mapping to `Net::HTTP#min_version=`
115
+ / `#max_version=`). `:ssl_version` still works but is deprecated (it pins an
116
+ exact protocol and forbids TLS 1.3).
117
+ - `HttpStreamingResponse#close` so Rack servers release the backend connection on
118
+ early termination (HEAD, 304, client disconnect) instead of leaking it until GC.
119
+ - Opt-in request hardening: `strip_credentials: true` drops the client's
120
+ `Cookie`/`Authorization` headers from the forwarded request, and
121
+ `replace_x_forwarded_for: true` forwards only this hop's `REMOTE_ADDR`
122
+ instead of appending to the client-supplied `X-Forwarded-For` chain.
123
+ - Project scaffolding: `SECURITY.md`, `CHANGELOG.md`, `CONTRIBUTING.md`,
124
+ `CLAUDE.md`/`AGENTS.md`, GitHub Actions CI (Ruby 3.1–3.4 × Rack 2/3),
125
+ Dependabot, issue/PR templates, SimpleCov with a ratcheted coverage floor
126
+ (`COVERAGE=1`), and Standard (`standardrb`) + `bundler-audit` enforced by a
127
+ CI lint job.
128
+
129
+ ### Changed
130
+
131
+ - **The streaming path no longer monkey-patches `net/http`.**
132
+ `Rack::HttpStreamingResponse` now runs the public block form of
133
+ `Net::HTTP#request` inside a Fiber (pausing at the response head, resuming
134
+ per body chunk), replacing the 2010-era patch of private `net/http` internals
135
+ in `net_http_hacked.rb`. Behavioral notes: the streaming session sets
136
+ `max_retries = 0` so a transport error can never silently replay the request
137
+ mid-stream; early termination (client abort, HEAD, 204/304) now closes
138
+ the backend connection immediately instead of draining the remaining body;
139
+ and a body-less POST/PUT/PATCH on the streaming path now carries
140
+ `Content-Length: 0` (matching the non-streaming path and plain `Net::HTTP` —
141
+ the old patched path sent no `Content-Length` at all).
142
+ - Backend and construction failures now map to status codes instead of raising a
143
+ `500`: `400` (malformed request URI), `501` (unknown HTTP method), `502`
144
+ (broadened backend-error set incl. `ECONNRESET`, `EPIPE`, read/write timeouts,
145
+ `EOFError`, `OpenSSL::SSL::SSLError`, protocol errors, and malformed backend
146
+ responses — `Net::HTTPBadResponse` / `Net::HTTPHeaderSyntaxError`).
147
+ - gzip-encoded backend responses are forwarded verbatim (Content-Encoding and
148
+ Content-Length preserved) instead of being transparently inflated.
149
+ - Skip all `1xx` interim responses (including `103 Early Hints`) on the streaming
150
+ path, so a backend's `103` is no longer mistaken for the final response.
151
+ - `rack` dependency constrained to `>= 2.0, < 4`; the library now `require`s rack
152
+ itself.
153
+ - Test suite is fully offline (local WEBrick server); the previous live-host
154
+ tests are gated behind `LIVE=1`.
155
+
156
+ ### Deprecated
157
+
158
+ - `:ssl_version` — use `:min_version` / `:max_version`.
159
+
160
+ ### Removed
161
+
162
+ - `lib/net_http_hacked.rb` — the 2010-era monkey-patch of private `Net::HTTP`
163
+ internals. The library stopped using it when streaming moved to the public
164
+ `Net::HTTP` API (see Changed); `require "net_http_hacked"` and the
165
+ `begin_request_hacked` / `end_request_hacked` methods are gone. If external
166
+ code still depends on them, vendor the file from a 0.8.x release — and plan
167
+ to migrate; it breaks under modern net/http refactors.
168
+
169
+ - The bundled examples moved from the gem load path
170
+ (`lib/rack_proxy_examples/`) to [`examples/`](examples/) in the repository.
171
+ `require "rack_proxy_examples/..."` no longer works — copy the example class
172
+ into your app instead (they were never safe to require blindly: each one
173
+ installs itself into the Rails middleware stack when Rails is booted).
174
+
175
+ ## [0.8.3] - 2025
176
+
177
+ ### Fixed
178
+
179
+ - Handle non-rewindable request body streams (Rack 3 input streams need not
180
+ respond to `#rewind`). (#128)
181
+
182
+ ## [0.8.2] - 2025
183
+
184
+ ### Fixed
185
+
186
+ - Harden `build_header_hash` against a top-level `::Headers` constant defined by
187
+ the host app being picked up instead of `Rack::Headers`.
188
+
189
+ ## [0.8.1] - 2025
190
+
191
+ ### Added
192
+
193
+ - `:logger` option, wired to `Net::HTTP#set_debug_output` for wire-level debug
194
+ output. (#80)
195
+
196
+ ## [0.8.0] - 2025
197
+
198
+ ### Changed
199
+
200
+ - **BREAKING:** TLS certificate verification now defaults to `VERIFY_PEER`
201
+ (Ruby's `Net::HTTP` default). Previous versions silently used `VERIFY_NONE` for
202
+ HTTPS backends. Pass `ssl_verify_none: true` (or `verify_mode:`) to opt out. (#113)
203
+
204
+ ### Fixed
205
+
206
+ - Return `502` on backend connection errors instead of raising; correct body
207
+ handling for empty responses and no-entity-body statuses (1xx/204/304). (#58, #122, #123)
208
+
209
+ ---
210
+
211
+ Older releases (≤ 0.7.8) predate this changelog; see the git history and tags.
212
+
213
+ [Unreleased]: https://github.com/ncr/rack-proxy/compare/v1.0.3...HEAD
214
+ [1.0.3]: https://github.com/ncr/rack-proxy/compare/v1.0.2...v1.0.3
215
+ [1.0.2]: https://github.com/ncr/rack-proxy/compare/v1.0.1...v1.0.2
216
+ [1.0.1]: https://github.com/ncr/rack-proxy/compare/v1.0.0...v1.0.1
217
+ [1.0.0]: https://github.com/ncr/rack-proxy/compare/v0.8.3...v1.0.0
218
+ [0.8.3]: https://github.com/ncr/rack-proxy/compare/v0.8.2...v0.8.3
219
+ [0.8.2]: https://github.com/ncr/rack-proxy/compare/v0.8.1...v0.8.2
220
+ [0.8.1]: https://github.com/ncr/rack-proxy/compare/v0.8.0...v0.8.1
221
+ [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) 2013 Jacek Becela jacek.becela@gmail.com
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