rack-proxy 0.8.1 → 0.8.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rack/proxy.rb +5 -3
- data/test/rack_proxy_test.rb +53 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 47505271ab54cee7d324c7fdd22c22ba7edae1b99146ee081913668925ff61f4
|
|
4
|
+
data.tar.gz: 74afa4cf47b33eba1e12a8a4b5f8b499237fa6a6fabacbb46c0bc820e627b07b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ea871048c9cd7ceff7b13c7e59caad7d393947a9909e5372031cc51c85879d2e297b57c6245ea56dc7c104da3c5ed3bc5688e2ce7a8c006f68cba52c0ee1696
|
|
7
|
+
data.tar.gz: 1c3ee10747af4bc06e9a270ec21d1854f1112b82127940a198e075ee044c7be6e6c43847b83d5cfd6facfadd90a32e4260a2e8731665ced34d46ec7ffd2febc1
|
data/Gemfile.lock
CHANGED
data/lib/rack/proxy.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Rack
|
|
|
5
5
|
|
|
6
6
|
# Subclass and bring your own #rewrite_request and #rewrite_response
|
|
7
7
|
class Proxy
|
|
8
|
-
VERSION = "0.8.
|
|
8
|
+
VERSION = "0.8.3".freeze
|
|
9
9
|
|
|
10
10
|
HOP_BY_HOP_HEADERS = {
|
|
11
11
|
'connection' => true,
|
|
@@ -39,7 +39,9 @@ module Rack
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def build_header_hash(pairs)
|
|
42
|
-
|
|
42
|
+
# Pass inherit: false so we only check Rack's own constants — otherwise
|
|
43
|
+
# a top-level ::Headers defined by the host app would falsely match.
|
|
44
|
+
if Rack.const_defined?(:Headers, false)
|
|
43
45
|
# Rack::Headers is only available from Rack 3 onward
|
|
44
46
|
Headers.new.tap { |headers| pairs.each { |k, v| headers[k] = v } }
|
|
45
47
|
else
|
|
@@ -126,7 +128,7 @@ module Rack
|
|
|
126
128
|
target_request.body_stream = source_request.body
|
|
127
129
|
target_request.content_length = source_request.content_length.to_i
|
|
128
130
|
target_request.content_type = source_request.content_type if source_request.content_type
|
|
129
|
-
target_request.body_stream.rewind
|
|
131
|
+
target_request.body_stream.rewind if target_request.body_stream.respond_to?(:rewind)
|
|
130
132
|
end
|
|
131
133
|
|
|
132
134
|
# Use basic auth if we have to
|
data/test/rack_proxy_test.rb
CHANGED
|
@@ -120,6 +120,42 @@ class RackProxyTest < Test::Unit::TestCase
|
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
+
# An input stream that deliberately omits #rewind, mimicking
|
|
124
|
+
# Rackup::Handler::WEBrick::Input under Rack 3 (the Rack 3 SPEC no longer
|
|
125
|
+
# requires the input stream to respond to #rewind, only gets/each/read).
|
|
126
|
+
class NonRewindableInput
|
|
127
|
+
def initialize(string)
|
|
128
|
+
@io = StringIO.new(string)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def read(*args) = @io.read(*args)
|
|
132
|
+
def gets(*args) = @io.gets(*args)
|
|
133
|
+
def each(&block) = @io.each(&block)
|
|
134
|
+
# intentionally NO #rewind
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Issue #128: a non-rewindable body stream must not raise (it used to blow up
|
|
138
|
+
# with NoMethodError on #rewind, surfacing confusingly as a 500). The body
|
|
139
|
+
# must still be forwarded intact, since it is never read before Net::HTTP sends it.
|
|
140
|
+
def test_non_rewindable_body_is_forwarded_without_raising
|
|
141
|
+
with_webrick_proxy(streaming: false) do |port, proxy|
|
|
142
|
+
proxy.host = "127.0.0.1:#{port}"
|
|
143
|
+
|
|
144
|
+
body = NonRewindableInput.new("hello=world")
|
|
145
|
+
assert !body.respond_to?(:rewind), "fixture must not be rewindable to exercise the guard"
|
|
146
|
+
|
|
147
|
+
env = Rack::MockRequest.env_for("/echo-body", method: "POST")
|
|
148
|
+
env["rack.input"] = body
|
|
149
|
+
env["CONTENT_LENGTH"] = "hello=world".bytesize.to_s
|
|
150
|
+
env["CONTENT_TYPE"] = "text/plain"
|
|
151
|
+
|
|
152
|
+
status, _headers, response = nil
|
|
153
|
+
assert_nothing_raised { status, _headers, response = proxy.call(env) }
|
|
154
|
+
assert_equal 200, status.to_i
|
|
155
|
+
assert_equal "hello=world", response.to_a.join, "body must be forwarded intact"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
123
159
|
def test_response_header_included_Hop_by_hop
|
|
124
160
|
app({:streaming => true}).host = 'mockapi.io'
|
|
125
161
|
get 'https://example.com/oauth2/token/info?access_token=123'
|
|
@@ -250,6 +286,22 @@ class RackProxyTest < Test::Unit::TestCase
|
|
|
250
286
|
"expected debug output to include request line, got: #{sink.string.inspect}")
|
|
251
287
|
end
|
|
252
288
|
|
|
289
|
+
# Regression: build_header_hash must not match a top-level ::Headers
|
|
290
|
+
# constant defined by the host app (would happen with inherit: true).
|
|
291
|
+
def test_build_header_hash_ignores_toplevel_headers_constant
|
|
292
|
+
Object.send(:remove_const, :Headers) if Object.const_defined?(:Headers, false)
|
|
293
|
+
Object.const_set(:Headers, Class.new)
|
|
294
|
+
begin
|
|
295
|
+
result = Rack::Proxy.send(:build_header_hash, [['X-Test', 'value']])
|
|
296
|
+
# On Rack 3+ we get Rack::Headers; on Rack 2 we get Rack::Utils::HeaderHash.
|
|
297
|
+
# In neither case should we get the bogus top-level ::Headers.
|
|
298
|
+
assert_not_equal ::Headers, result.class,
|
|
299
|
+
"build_header_hash leaked into top-level ::Headers"
|
|
300
|
+
ensure
|
|
301
|
+
Object.send(:remove_const, :Headers)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
253
305
|
def test_no_logger_means_no_debug_output
|
|
254
306
|
# Without a :logger option, Net::HTTP's set_debug_output should never be
|
|
255
307
|
# called. We can't directly assert that, but we can confirm requests still
|
|
@@ -292,6 +344,7 @@ class RackProxyTest < Test::Unit::TestCase
|
|
|
292
344
|
res['x-custom'] = 'value-here'
|
|
293
345
|
res.body = 'ok'
|
|
294
346
|
end
|
|
347
|
+
server.mount_proc('/echo-body') { |req, res| res.body = req.body.to_s }
|
|
295
348
|
Thread.new { server.start }
|
|
296
349
|
port = server.config[:Port]
|
|
297
350
|
|