rack-proxy 0.7.7 → 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 +271 -164
- data/SECURITY.md +52 -0
- data/lib/rack/http_streaming_response.rb +138 -17
- data/lib/rack/proxy/version.rb +7 -0
- data/lib/rack/proxy.rb +266 -72
- data/lib/rack-proxy.rb +3 -1
- data/rack-proxy.gemspec +21 -16
- metadata +35 -27
- data/.github/FUNDING.yml +0 -3
- data/.gitignore +0 -3
- data/.travis.yml +0 -18
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -28
- 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 -24
- data/test/http_streaming_response_test.rb +0 -48
- data/test/net_http_hacked_test.rb +0 -36
- data/test/rack_proxy_test.rb +0 -127
- data/test/test_helper.rb +0 -11
data/rack-proxy.gemspec
CHANGED
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
1
|
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
-
require "rack
|
|
2
|
+
require "rack/proxy/version"
|
|
4
3
|
|
|
5
4
|
Gem::Specification.new do |s|
|
|
6
|
-
s.name
|
|
7
|
-
s.version
|
|
8
|
-
s.platform
|
|
9
|
-
s.license
|
|
10
|
-
s.authors
|
|
11
|
-
s.email
|
|
12
|
-
s.homepage
|
|
13
|
-
s.summary
|
|
14
|
-
s.description =
|
|
15
|
-
s.required_ruby_version =
|
|
5
|
+
s.name = "rack-proxy"
|
|
6
|
+
s.version = Rack::Proxy::VERSION
|
|
7
|
+
s.platform = Gem::Platform::RUBY
|
|
8
|
+
s.license = "MIT"
|
|
9
|
+
s.authors = ["Jacek Becela"]
|
|
10
|
+
s.email = ["jacek.becela@gmail.com"]
|
|
11
|
+
s.homepage = "https://github.com/ncr/rack-proxy"
|
|
12
|
+
s.summary = "A request/response rewriting HTTP proxy. A Rack app."
|
|
13
|
+
s.description = "A Rack app that provides request/response rewriting proxy capabilities with streaming."
|
|
14
|
+
s.required_ruby_version = ">= 3.0"
|
|
16
15
|
|
|
17
|
-
s.
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
s.metadata = {
|
|
17
|
+
"source_code_uri" => "https://github.com/ncr/rack-proxy",
|
|
18
|
+
"changelog_uri" => "https://github.com/ncr/rack-proxy/blob/master/CHANGELOG.md",
|
|
19
|
+
"bug_tracker_uri" => "https://github.com/ncr/rack-proxy/issues",
|
|
20
|
+
"rubygems_mfa_required" => "true"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
s.files = Dir["lib/**/*.rb"] + %w[README.md LICENSE CHANGELOG.md SECURITY.md rack-proxy.gemspec]
|
|
20
24
|
s.require_paths = ["lib"]
|
|
21
25
|
|
|
22
|
-
s.add_dependency("rack")
|
|
26
|
+
s.add_dependency("rack", ">= 2.0", "< 4")
|
|
23
27
|
s.add_development_dependency("rack-test")
|
|
24
28
|
s.add_development_dependency("test-unit")
|
|
29
|
+
s.add_development_dependency("webrick")
|
|
25
30
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-proxy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jacek Becela
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-07-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -16,14 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
19
|
+
version: '2.0'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '4'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
29
|
+
version: '2.0'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '4'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: rack-test
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,6 +58,20 @@ dependencies:
|
|
|
52
58
|
- - ">="
|
|
53
59
|
- !ruby/object:Gem::Version
|
|
54
60
|
version: '0'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: webrick
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
55
75
|
description: A Rack app that provides request/response rewriting proxy capabilities
|
|
56
76
|
with streaming.
|
|
57
77
|
email:
|
|
@@ -60,31 +80,23 @@ executables: []
|
|
|
60
80
|
extensions: []
|
|
61
81
|
extra_rdoc_files: []
|
|
62
82
|
files:
|
|
63
|
-
-
|
|
64
|
-
- ".gitignore"
|
|
65
|
-
- ".travis.yml"
|
|
66
|
-
- Gemfile
|
|
67
|
-
- Gemfile.lock
|
|
83
|
+
- CHANGELOG.md
|
|
68
84
|
- LICENSE
|
|
69
85
|
- README.md
|
|
70
|
-
-
|
|
71
|
-
- lib/net_http_hacked.rb
|
|
86
|
+
- SECURITY.md
|
|
72
87
|
- lib/rack-proxy.rb
|
|
73
88
|
- lib/rack/http_streaming_response.rb
|
|
74
89
|
- lib/rack/proxy.rb
|
|
75
|
-
- lib/
|
|
76
|
-
- lib/rack_proxy_examples/forward_host.rb
|
|
77
|
-
- lib/rack_proxy_examples/rack_php_proxy.rb
|
|
78
|
-
- lib/rack_proxy_examples/trusting_proxy.rb
|
|
90
|
+
- lib/rack/proxy/version.rb
|
|
79
91
|
- rack-proxy.gemspec
|
|
80
|
-
- test/http_streaming_response_test.rb
|
|
81
|
-
- test/net_http_hacked_test.rb
|
|
82
|
-
- test/rack_proxy_test.rb
|
|
83
|
-
- test/test_helper.rb
|
|
84
92
|
homepage: https://github.com/ncr/rack-proxy
|
|
85
93
|
licenses:
|
|
86
94
|
- MIT
|
|
87
|
-
metadata:
|
|
95
|
+
metadata:
|
|
96
|
+
source_code_uri: https://github.com/ncr/rack-proxy
|
|
97
|
+
changelog_uri: https://github.com/ncr/rack-proxy/blob/master/CHANGELOG.md
|
|
98
|
+
bug_tracker_uri: https://github.com/ncr/rack-proxy/issues
|
|
99
|
+
rubygems_mfa_required: 'true'
|
|
88
100
|
post_install_message:
|
|
89
101
|
rdoc_options: []
|
|
90
102
|
require_paths:
|
|
@@ -93,19 +105,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
93
105
|
requirements:
|
|
94
106
|
- - ">="
|
|
95
107
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
108
|
+
version: '3.0'
|
|
97
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
110
|
requirements:
|
|
99
111
|
- - ">="
|
|
100
112
|
- !ruby/object:Gem::Version
|
|
101
113
|
version: '0'
|
|
102
114
|
requirements: []
|
|
103
|
-
rubygems_version: 3.
|
|
115
|
+
rubygems_version: 3.5.22
|
|
104
116
|
signing_key:
|
|
105
117
|
specification_version: 4
|
|
106
118
|
summary: A request/response rewriting HTTP proxy. A Rack app.
|
|
107
|
-
test_files:
|
|
108
|
-
- test/http_streaming_response_test.rb
|
|
109
|
-
- test/net_http_hacked_test.rb
|
|
110
|
-
- test/rack_proxy_test.rb
|
|
111
|
-
- test/test_helper.rb
|
|
119
|
+
test_files: []
|
data/.github/FUNDING.yml
DELETED
data/.gitignore
DELETED
data/.travis.yml
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
cache: bundler
|
|
2
|
-
language: ruby
|
|
3
|
-
before_install:
|
|
4
|
-
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
|
5
|
-
- gem install bundler
|
|
6
|
-
- gem update bundler
|
|
7
|
-
script: bundle exec rake test
|
|
8
|
-
rvm:
|
|
9
|
-
- 2.0.0
|
|
10
|
-
- 2.1.5
|
|
11
|
-
- 2.2.2
|
|
12
|
-
- 2.2.3
|
|
13
|
-
- 2.3.0
|
|
14
|
-
- 2.3.1
|
|
15
|
-
env:
|
|
16
|
-
- RAILS_ENV=test RACK_ENV=test
|
|
17
|
-
notifications:
|
|
18
|
-
email: false
|
data/Gemfile
DELETED
data/Gemfile.lock
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
rack-proxy (0.7.7)
|
|
5
|
-
rack
|
|
6
|
-
|
|
7
|
-
GEM
|
|
8
|
-
remote: https://rubygems.org/
|
|
9
|
-
specs:
|
|
10
|
-
power_assert (2.0.3)
|
|
11
|
-
rack (3.0.8)
|
|
12
|
-
rack-test (2.1.0)
|
|
13
|
-
rack (>= 1.3)
|
|
14
|
-
rake (13.0.6)
|
|
15
|
-
test-unit (3.6.1)
|
|
16
|
-
power_assert
|
|
17
|
-
|
|
18
|
-
PLATFORMS
|
|
19
|
-
arm64-darwin-22
|
|
20
|
-
|
|
21
|
-
DEPENDENCIES
|
|
22
|
-
rack-proxy!
|
|
23
|
-
rack-test
|
|
24
|
-
rake
|
|
25
|
-
test-unit
|
|
26
|
-
|
|
27
|
-
BUNDLED WITH
|
|
28
|
-
2.4.17
|
data/Rakefile
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'bundler'
|
|
3
|
-
Bundler::GemHelper.install_tasks
|
|
4
|
-
|
|
5
|
-
require "rake/testtask"
|
|
6
|
-
task :test do
|
|
7
|
-
Rake::TestTask.new do |t|
|
|
8
|
-
t.libs << "test"
|
|
9
|
-
t.test_files = FileList['test/*_test.rb']
|
|
10
|
-
t.verbose = true
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
task :default => :test
|
data/lib/net_http_hacked.rb
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# We are hacking net/http to change semantics of streaming handling
|
|
2
|
-
# from "block" semantics to regular "return" semantics.
|
|
3
|
-
# We need it to construct a streamable rack triplet:
|
|
4
|
-
#
|
|
5
|
-
# [status, headers, streamable_body]
|
|
6
|
-
#
|
|
7
|
-
# See http://github.com/zerowidth/rack-streaming-proxy
|
|
8
|
-
# for alternative that uses additional process.
|
|
9
|
-
#
|
|
10
|
-
# BTW I don't like monkey patching either
|
|
11
|
-
# but this is not real monkey patching.
|
|
12
|
-
# I just added some methods and named them very uniquely
|
|
13
|
-
# to avoid eventual conflicts. You're safe. Trust me.
|
|
14
|
-
#
|
|
15
|
-
# Also, in Ruby 1.9.2 you could use Fibers to avoid hacking net/http.
|
|
16
|
-
|
|
17
|
-
require 'net/https'
|
|
18
|
-
|
|
19
|
-
class Net::HTTP
|
|
20
|
-
# Original #request with block semantics.
|
|
21
|
-
#
|
|
22
|
-
# def request(req, body = nil, &block)
|
|
23
|
-
# unless started?
|
|
24
|
-
# start {
|
|
25
|
-
# req['connection'] ||= 'close'
|
|
26
|
-
# return request(req, body, &block)
|
|
27
|
-
# }
|
|
28
|
-
# end
|
|
29
|
-
# if proxy_user()
|
|
30
|
-
# unless use_ssl?
|
|
31
|
-
# req.proxy_basic_auth proxy_user(), proxy_pass()
|
|
32
|
-
# end
|
|
33
|
-
# end
|
|
34
|
-
#
|
|
35
|
-
# req.set_body_internal body
|
|
36
|
-
# begin_transport req
|
|
37
|
-
# req.exec @socket, @curr_http_version, edit_path(req.path)
|
|
38
|
-
# begin
|
|
39
|
-
# res = HTTPResponse.read_new(@socket)
|
|
40
|
-
# end while res.kind_of?(HTTPContinue)
|
|
41
|
-
# res.reading_body(@socket, req.response_body_permitted?) {
|
|
42
|
-
# yield res if block_given?
|
|
43
|
-
# }
|
|
44
|
-
# end_transport req, res
|
|
45
|
-
#
|
|
46
|
-
# res
|
|
47
|
-
# end
|
|
48
|
-
|
|
49
|
-
def begin_request_hacked(req)
|
|
50
|
-
begin_transport req
|
|
51
|
-
req.exec @socket, @curr_http_version, edit_path(req.path)
|
|
52
|
-
begin
|
|
53
|
-
res = Net::HTTPResponse.read_new(@socket)
|
|
54
|
-
end while res.kind_of?(Net::HTTPContinue)
|
|
55
|
-
res.begin_reading_body_hacked(@socket, req.response_body_permitted?)
|
|
56
|
-
@req_hacked, @res_hacked = req, res
|
|
57
|
-
@res_hacked
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def end_request_hacked
|
|
61
|
-
@res_hacked.end_reading_body_hacked
|
|
62
|
-
end_transport @req_hacked, @res_hacked
|
|
63
|
-
@res_hacked
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
class Net::HTTPResponse
|
|
68
|
-
# Original #reading_body with block semantics
|
|
69
|
-
#
|
|
70
|
-
# def reading_body(sock, reqmethodallowbody) #:nodoc: internal use only
|
|
71
|
-
# @socket = sock
|
|
72
|
-
# @body_exist = reqmethodallowbody && self.class.body_permitted?
|
|
73
|
-
# begin
|
|
74
|
-
# yield
|
|
75
|
-
# self.body # ensure to read body
|
|
76
|
-
# ensure
|
|
77
|
-
# @socket = nil
|
|
78
|
-
# end
|
|
79
|
-
# end
|
|
80
|
-
|
|
81
|
-
def begin_reading_body_hacked(sock, reqmethodallowbody)
|
|
82
|
-
@socket = sock
|
|
83
|
-
@body_exist = reqmethodallowbody && self.class.body_permitted?
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def end_reading_body_hacked
|
|
87
|
-
self.body
|
|
88
|
-
@socket = nil
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
###
|
|
2
|
-
# This is an example of how to use Rack-Proxy in a Rails application.
|
|
3
|
-
#
|
|
4
|
-
# Setup:
|
|
5
|
-
# 1. rails new test_app
|
|
6
|
-
# 2. cd test_app
|
|
7
|
-
# 3. install Rack-Proxy in `Gemfile`
|
|
8
|
-
# a. `gem 'rack-proxy', '~> 0.7.7'`
|
|
9
|
-
# 4. install gem: `bundle install`
|
|
10
|
-
# 5. create `config/initializers/proxy.rb` adding this line `require 'rack_proxy_examples/example_service_proxy'`
|
|
11
|
-
# 6. run: `SERVICE_URL=http://guides.rubyonrails.org rails server`
|
|
12
|
-
# 7. open in browser: `http://localhost:3000/example_service`
|
|
13
|
-
#
|
|
14
|
-
###
|
|
15
|
-
ENV['SERVICE_URL'] ||= 'http://guides.rubyonrails.org'
|
|
16
|
-
|
|
17
|
-
class ExampleServiceProxy < Rack::Proxy
|
|
18
|
-
def perform_request(env)
|
|
19
|
-
request = Rack::Request.new(env)
|
|
20
|
-
|
|
21
|
-
# use rack proxy for anything hitting our host app at /example_service
|
|
22
|
-
if request.path =~ %r{^/example_service}
|
|
23
|
-
backend = URI(ENV['SERVICE_URL'])
|
|
24
|
-
# most backends required host set properly, but rack-proxy doesn't set this for you automatically
|
|
25
|
-
# even when a backend host is passed in via the options
|
|
26
|
-
env["HTTP_HOST"] = backend.host
|
|
27
|
-
|
|
28
|
-
# This is the only path that needs to be set currently on Rails 5 & greater
|
|
29
|
-
env['PATH_INFO'] = ENV['SERVICE_PATH'] || '/configuring.html'
|
|
30
|
-
|
|
31
|
-
# don't send your sites cookies to target service, unless it is a trusted internal service that can parse all your cookies
|
|
32
|
-
env['HTTP_COOKIE'] = ''
|
|
33
|
-
super(env)
|
|
34
|
-
else
|
|
35
|
-
@app.call(env)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
Rails.application.config.middleware.use ExampleServiceProxy, backend: ENV['SERVICE_URL'], streaming: false
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
class ForwardHost < Rack::Proxy
|
|
2
|
-
|
|
3
|
-
def rewrite_env(env)
|
|
4
|
-
env["HTTP_HOST"] = "example.com"
|
|
5
|
-
env
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def rewrite_response(triplet)
|
|
9
|
-
status, headers, body = triplet
|
|
10
|
-
|
|
11
|
-
# example of inserting an additional header
|
|
12
|
-
headers["X-Foo"] = "Bar"
|
|
13
|
-
|
|
14
|
-
# if you rewrite env, it appears that content-length isn't calculated correctly
|
|
15
|
-
# resulting in only partial responses being sent to users
|
|
16
|
-
# you can remove it or recalculate it here
|
|
17
|
-
headers["content-length"] = nil
|
|
18
|
-
|
|
19
|
-
triplet
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
Rails.application.config.middleware.use ForwardHost, backend: 'http://example.com', streaming: false
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
###
|
|
2
|
-
# Open http://localhost:3000/test.php to trigger proxy
|
|
3
|
-
###
|
|
4
|
-
class RackPhpProxy < Rack::Proxy
|
|
5
|
-
|
|
6
|
-
def perform_request(env)
|
|
7
|
-
request = Rack::Request.new(env)
|
|
8
|
-
if request.path =~ %r{\.php}
|
|
9
|
-
env["HTTP_HOST"] = ENV["HTTP_HOST"] ? URI(ENV["HTTP_HOST"]).host : "localhost"
|
|
10
|
-
ENV["PHP_PATH"] ||= '/manual/en/tutorial.firstpage.php'
|
|
11
|
-
|
|
12
|
-
# Rails 3 & 4
|
|
13
|
-
env["REQUEST_PATH"] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
|
|
14
|
-
# Rails 5 and above
|
|
15
|
-
env['PATH_INFO'] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
|
|
16
|
-
|
|
17
|
-
env['content-length'] = nil
|
|
18
|
-
|
|
19
|
-
super(env)
|
|
20
|
-
else
|
|
21
|
-
@app.call(env)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def rewrite_response(triplet)
|
|
26
|
-
status, headers, body = triplet
|
|
27
|
-
|
|
28
|
-
# if you proxy depending on the backend, it appears that content-length isn't calculated correctly
|
|
29
|
-
# resulting in only partial responses being sent to users
|
|
30
|
-
# you can remove it or recalculate it here
|
|
31
|
-
headers["content-length"] = nil
|
|
32
|
-
|
|
33
|
-
triplet
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
Rails.application.config.middleware.use RackPhpProxy, backend: ENV["HTTP_HOST"]='http://php.net', streaming: false
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
class TrustingProxy < Rack::Proxy
|
|
2
|
-
|
|
3
|
-
def rewrite_env(env)
|
|
4
|
-
env["HTTP_HOST"] = "self-signed.badssl.com"
|
|
5
|
-
|
|
6
|
-
# We are going to trust the self-signed SSL
|
|
7
|
-
env["rack.ssl_verify_none"] = true
|
|
8
|
-
env
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def rewrite_response(triplet)
|
|
12
|
-
status, headers, body = triplet
|
|
13
|
-
|
|
14
|
-
# if you rewrite env, it appears that content-length isn't calculated correctly
|
|
15
|
-
# resulting in only partial responses being sent to users
|
|
16
|
-
# you can remove it or recalculate it here
|
|
17
|
-
headers["content-length"] = nil
|
|
18
|
-
|
|
19
|
-
triplet
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
Rails.application.config.middleware.use TrustingProxy, backend: 'https://self-signed.badssl.com', streaming: false
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
require "rack/http_streaming_response"
|
|
3
|
-
|
|
4
|
-
class HttpStreamingResponseTest < Test::Unit::TestCase
|
|
5
|
-
|
|
6
|
-
def setup
|
|
7
|
-
host, req = "example.com", Net::HTTP::Get.new("/")
|
|
8
|
-
@response = Rack::HttpStreamingResponse.new(req, host, 443)
|
|
9
|
-
@response.use_ssl = true
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_streaming
|
|
13
|
-
# Response status
|
|
14
|
-
assert_equal 200, @response.status
|
|
15
|
-
assert_equal 200, @response.status
|
|
16
|
-
|
|
17
|
-
# Headers
|
|
18
|
-
headers = @response.headers
|
|
19
|
-
|
|
20
|
-
assert headers.size.positive?
|
|
21
|
-
|
|
22
|
-
assert_match %r{text/html; ?charset=utf-8}, headers["content-type"].first.downcase
|
|
23
|
-
assert_equal headers["content-type"], headers["CoNtEnT-TyPe"]
|
|
24
|
-
assert headers["content-length"].first.to_i.positive?
|
|
25
|
-
|
|
26
|
-
# Body
|
|
27
|
-
chunks = []
|
|
28
|
-
@response.body.each do |chunk|
|
|
29
|
-
chunks << chunk
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
assert chunks.size.positive?
|
|
33
|
-
chunks.each do |chunk|
|
|
34
|
-
assert chunk.is_a?(String)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def test_to_s
|
|
40
|
-
assert_equal @response.headers["Content-Length"].first.to_i, @response.body.to_s.bytesize
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def test_to_s_called_twice
|
|
44
|
-
body = @response.body
|
|
45
|
-
assert_equal body.to_s, body.to_s
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
end
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
require "net_http_hacked"
|
|
3
|
-
|
|
4
|
-
class NetHttpHackedTest < Test::Unit::TestCase
|
|
5
|
-
|
|
6
|
-
def test_net_http_hacked
|
|
7
|
-
req = Net::HTTP::Get.new("/")
|
|
8
|
-
http = Net::HTTP.start("www.iana.org", "80")
|
|
9
|
-
|
|
10
|
-
# Response code
|
|
11
|
-
res = http.begin_request_hacked(req)
|
|
12
|
-
assert res.code == "200"
|
|
13
|
-
|
|
14
|
-
# Headers
|
|
15
|
-
headers = {}
|
|
16
|
-
res.each_header { |k, v| headers[k] = v }
|
|
17
|
-
|
|
18
|
-
assert headers.size > 0
|
|
19
|
-
assert headers["content-type"] == "text/html; charset=UTF-8"
|
|
20
|
-
assert !headers["date"].nil?
|
|
21
|
-
|
|
22
|
-
# Body
|
|
23
|
-
chunks = []
|
|
24
|
-
res.read_body do |chunk|
|
|
25
|
-
chunks << chunk
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
assert chunks.size > 0
|
|
29
|
-
chunks.each do |chunk|
|
|
30
|
-
assert chunk.is_a?(String)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
http.end_request_hacked
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
end
|
data/test/rack_proxy_test.rb
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
require "test_helper"
|
|
2
|
-
require "rack/proxy"
|
|
3
|
-
|
|
4
|
-
class RackProxyTest < Test::Unit::TestCase
|
|
5
|
-
class HostProxy < Rack::Proxy
|
|
6
|
-
attr_accessor :host
|
|
7
|
-
|
|
8
|
-
def rewrite_env(env)
|
|
9
|
-
env["HTTP_HOST"] = self.host || 'example.com'
|
|
10
|
-
env
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def app(opts = {})
|
|
15
|
-
return @app ||= HostProxy.new(opts)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def test_http_streaming
|
|
19
|
-
get "/"
|
|
20
|
-
assert last_response.ok?
|
|
21
|
-
|
|
22
|
-
assert_match(/Example Domain/, last_response.body)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def test_http_full_request
|
|
26
|
-
app(:streaming => false)
|
|
27
|
-
get "/"
|
|
28
|
-
assert last_response.ok?
|
|
29
|
-
assert_match(/Example Domain/, last_response.body)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def test_http_full_request_headers
|
|
33
|
-
app(:streaming => false)
|
|
34
|
-
app.host = 'www.google.com'
|
|
35
|
-
get "/"
|
|
36
|
-
assert !Array(last_response['Set-Cookie']).empty?, 'Google always sets a cookie, yo. Where my cookies at?!'
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def test_https_streaming
|
|
40
|
-
app.host = 'www.apple.com'
|
|
41
|
-
get 'https://example.com'
|
|
42
|
-
assert last_response.ok?
|
|
43
|
-
assert_match(/(itunes|iphone|ipod|mac|ipad)/, last_response.body)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def test_https_streaming_tls
|
|
47
|
-
app(:ssl_version => :TLSv1).host = 'www.apple.com'
|
|
48
|
-
get 'https://example.com'
|
|
49
|
-
assert last_response.ok?
|
|
50
|
-
assert_match(/(itunes|iphone|ipod|mac|ipad)/, last_response.body)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def test_https_full_request
|
|
54
|
-
app(:streaming => false).host = 'www.apple.com'
|
|
55
|
-
get 'https://example.com'
|
|
56
|
-
assert last_response.ok?
|
|
57
|
-
assert_match(/(itunes|iphone|ipod|mac|ipad)/, last_response.body)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def test_https_full_request_tls
|
|
61
|
-
app({:streaming => false, :ssl_version => :TLSv1}).host = 'www.apple.com'
|
|
62
|
-
get 'https://example.com'
|
|
63
|
-
assert last_response.ok?
|
|
64
|
-
assert_match(/(itunes|iphone|ipod|mac|ipad)/, last_response.body)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def test_normalize_headers
|
|
68
|
-
proxy_class = Rack::Proxy
|
|
69
|
-
headers = { 'header_array' => ['first_entry'], 'header_non_array' => :entry }
|
|
70
|
-
|
|
71
|
-
normalized_headers = proxy_class.send(:normalize_headers, headers)
|
|
72
|
-
assert normalized_headers.instance_of?(Rack::Utils::HeaderHash)
|
|
73
|
-
assert normalized_headers['header_array'] == 'first_entry'
|
|
74
|
-
assert normalized_headers['header_non_array'] == :entry
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def test_header_reconstruction
|
|
78
|
-
proxy_class = Rack::Proxy
|
|
79
|
-
|
|
80
|
-
header = proxy_class.send(:reconstruct_header_name, "HTTP_ABC")
|
|
81
|
-
assert header == "Abc"
|
|
82
|
-
|
|
83
|
-
header = proxy_class.send(:reconstruct_header_name, "HTTP_ABC_D")
|
|
84
|
-
assert header == "Abc-D"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def test_extract_http_request_headers
|
|
88
|
-
proxy_class = Rack::Proxy
|
|
89
|
-
env = {
|
|
90
|
-
'NOT-HTTP-HEADER' => 'test-value',
|
|
91
|
-
'HTTP_ACCEPT' => 'text/html',
|
|
92
|
-
'HTTP_CONNECTION' => nil,
|
|
93
|
-
'HTTP_CONTENT_MD5' => 'deadbeef',
|
|
94
|
-
'HTTP_HEADER.WITH.PERIODS' => 'stillmooing'
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
headers = proxy_class.extract_http_request_headers(env)
|
|
98
|
-
assert headers.key?('ACCEPT')
|
|
99
|
-
assert headers.key?('CONTENT-MD5')
|
|
100
|
-
assert headers.key?('HEADER.WITH.PERIODS')
|
|
101
|
-
assert !headers.key?('CONNECTION')
|
|
102
|
-
assert !headers.key?('NOT-HTTP-HEADER')
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def test_duplicate_headers
|
|
106
|
-
proxy_class = Rack::Proxy
|
|
107
|
-
env = { 'Set-Cookie' => ["cookie1=foo", "cookie2=bar"] }
|
|
108
|
-
|
|
109
|
-
headers = proxy_class.normalize_headers(env)
|
|
110
|
-
assert headers['Set-Cookie'].include?('cookie1=foo'), "Include the first value"
|
|
111
|
-
assert headers['Set-Cookie'].include?("\n"), "Join multiple cookies with newlines"
|
|
112
|
-
assert headers['Set-Cookie'].include?('cookie2=bar'), "Include the second value"
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def test_handles_missing_content_length
|
|
117
|
-
assert_nothing_thrown do
|
|
118
|
-
post "/", nil, "CONTENT_LENGTH" => nil
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def test_response_header_included_Hop_by_hop
|
|
123
|
-
app({:streaming => true}).host = 'mockapi.io'
|
|
124
|
-
get 'https://example.com/oauth2/token/info?access_token=123'
|
|
125
|
-
assert !last_response.headers.key?('transfer-encoding')
|
|
126
|
-
end
|
|
127
|
-
end
|