rack-reverse-proxy 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +26 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/rack/reverse_proxy.rb +16 -2
- data/rack-reverse-proxy.gemspec +10 -9
- data/spec/rack/reverse_proxy_spec.rb +31 -6
- data/spec/spec_helper.rb +1 -0
- metadata +24 -7
data/README
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
A Reverse Proxy for Rack
|
2
|
+
|
3
|
+
This is a simple reverse proxy for Rack that pretty heavily rips off Rack Forwarder. It is not meant for production systems (although it may work), as the webserver fronting your app is generally much better at this sort of thing.
|
4
|
+
|
5
|
+
Matchers can be a regex or a string. If a regex is used, you can use the subcaptures in your forwarding url by denoting them with a $.
|
6
|
+
|
7
|
+
Right now if more than one matcher matches any given route, it throws an exception for an ambiguous match. This will probably change later. If no match is found, the call is forwarded to your application.
|
8
|
+
|
9
|
+
Below is an example for configuring the middleware:
|
10
|
+
|
11
|
+
require 'lib/rack/reverse_proxy'
|
12
|
+
|
13
|
+
use Rack::ReverseProxy do
|
14
|
+
# Forward the path /test* to http://example.com/test*
|
15
|
+
reverse_proxy '/test', 'http://example.com/'
|
16
|
+
|
17
|
+
# Forward the path /foo/* to http://example.com/bar/*
|
18
|
+
reverse_proxy /^\/foo(\/.*)$/, 'http://example.com/bar$1'
|
19
|
+
end
|
20
|
+
|
21
|
+
app = proc do |env|
|
22
|
+
[ 200, {'Content-Type' => 'text/plain'}, "b" ]
|
23
|
+
end
|
24
|
+
run app
|
25
|
+
|
26
|
+
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
gem.authors = ["Jon Swope"]
|
13
13
|
gem.add_development_dependency "rspec", ">= 0"
|
14
14
|
gem.add_development_dependency "rack-test", ">= 0"
|
15
|
-
gem.add_development_dependency "webmock", "
|
15
|
+
gem.add_development_dependency "webmock", "~> 1.5.0"
|
16
16
|
gem.add_dependency "rack", ">= 1.0.0"
|
17
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
18
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/rack/reverse_proxy.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'net/http'
|
2
|
+
require 'net/https'
|
2
3
|
|
3
4
|
module Rack
|
4
5
|
class ReverseProxy
|
@@ -20,8 +21,12 @@ module Rack
|
|
20
21
|
headers[$1] = value
|
21
22
|
end
|
22
23
|
}
|
24
|
+
headers['HOST'] = uri.host
|
23
25
|
|
24
|
-
|
26
|
+
session = Net::HTTP.new(uri.host, uri.port)
|
27
|
+
session.use_ssl = (uri.scheme == 'https')
|
28
|
+
session.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
29
|
+
session.start { |http|
|
25
30
|
m = rackreq.request_method
|
26
31
|
case m
|
27
32
|
when "GET", "HEAD", "DELETE", "OPTIONS", "TRACE"
|
@@ -40,7 +45,8 @@ module Rack
|
|
40
45
|
body << segment
|
41
46
|
end
|
42
47
|
end
|
43
|
-
|
48
|
+
|
49
|
+
[res.code, create_response_headers(res), [body]]
|
44
50
|
}
|
45
51
|
end
|
46
52
|
|
@@ -60,6 +66,14 @@ module Rack
|
|
60
66
|
end
|
61
67
|
end
|
62
68
|
|
69
|
+
def create_response_headers http_response
|
70
|
+
response_headers = Rack::Utils::HeaderHash.new(http_response.to_hash)
|
71
|
+
# handled by Rack
|
72
|
+
response_headers.delete('status')
|
73
|
+
# TODO: Verify Content Length, and required Rack headers
|
74
|
+
response_headers
|
75
|
+
end
|
76
|
+
|
63
77
|
def match_path(path, matcher)
|
64
78
|
if matcher.is_a?(Regexp)
|
65
79
|
path.match(matcher)
|
data/rack-reverse-proxy.gemspec
CHANGED
@@ -5,15 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rack-reverse-proxy}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jon Swope"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-07}
|
13
13
|
s.description = %q{A Rack based reverse proxy for basic needs. Useful for testing or in cases where webserver configuration is unavailable.}
|
14
14
|
s.email = %q{jaswope@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
+
"README",
|
17
18
|
"README.rdoc"
|
18
19
|
]
|
19
20
|
s.files = [
|
@@ -32,32 +33,32 @@ Gem::Specification.new do |s|
|
|
32
33
|
s.homepage = %q{http://github.com/jaswope/rack-reverse-proxy}
|
33
34
|
s.rdoc_options = ["--charset=UTF-8"]
|
34
35
|
s.require_paths = ["lib"]
|
35
|
-
s.rubygems_version = %q{1.3.
|
36
|
+
s.rubygems_version = %q{1.3.7}
|
36
37
|
s.summary = %q{A Simple Reverse Proxy for Rack}
|
37
38
|
s.test_files = [
|
38
|
-
"spec/
|
39
|
-
"spec/
|
39
|
+
"spec/spec_helper.rb",
|
40
|
+
"spec/rack/reverse_proxy_spec.rb"
|
40
41
|
]
|
41
42
|
|
42
43
|
if s.respond_to? :specification_version then
|
43
44
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
45
|
s.specification_version = 3
|
45
46
|
|
46
|
-
if Gem::Version.new(Gem::
|
47
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
47
48
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
48
49
|
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
49
|
-
s.add_development_dependency(%q<webmock>, ["
|
50
|
+
s.add_development_dependency(%q<webmock>, ["~> 1.5.0"])
|
50
51
|
s.add_runtime_dependency(%q<rack>, [">= 1.0.0"])
|
51
52
|
else
|
52
53
|
s.add_dependency(%q<rspec>, [">= 0"])
|
53
54
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
54
|
-
s.add_dependency(%q<webmock>, ["
|
55
|
+
s.add_dependency(%q<webmock>, ["~> 1.5.0"])
|
55
56
|
s.add_dependency(%q<rack>, [">= 1.0.0"])
|
56
57
|
end
|
57
58
|
else
|
58
59
|
s.add_dependency(%q<rspec>, [">= 0"])
|
59
60
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
60
|
-
s.add_dependency(%q<webmock>, ["
|
61
|
+
s.add_dependency(%q<webmock>, ["~> 1.5.0"])
|
61
62
|
s.add_dependency(%q<rack>, [">= 1.0.0"])
|
62
63
|
end
|
63
64
|
end
|
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe Rack::ReverseProxy do
|
4
4
|
include Rack::Test::Methods
|
5
|
-
include WebMock
|
5
|
+
include WebMock::API
|
6
6
|
|
7
7
|
def app
|
8
8
|
Rack::ReverseProxy.new
|
@@ -31,6 +31,18 @@ describe Rack::ReverseProxy do
|
|
31
31
|
last_response.body.should == "Proxied App"
|
32
32
|
end
|
33
33
|
|
34
|
+
it "the response header should never contain Status" do
|
35
|
+
stub_request(:any, 'example.com/test/stuff').to_return(:headers => {'Status' => '200 OK'})
|
36
|
+
get '/test/stuff'
|
37
|
+
last_response.headers['Status'].should == nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set the Host header" do
|
41
|
+
stub_request(:any, 'example.com/test/stuff')
|
42
|
+
get '/test/stuff'
|
43
|
+
a_request(:get, 'http://example.com/test/stuff').with(:headers => {"Host" => "example.com"}).should have_been_made
|
44
|
+
end
|
45
|
+
|
34
46
|
describe "with ambiguous routes" do
|
35
47
|
def app
|
36
48
|
Rack::ReverseProxy.new(dummy_app) do
|
@@ -58,6 +70,21 @@ describe Rack::ReverseProxy do
|
|
58
70
|
end
|
59
71
|
end
|
60
72
|
|
73
|
+
describe "with a https route" do
|
74
|
+
def app
|
75
|
+
Rack::ReverseProxy.new(dummy_app) do
|
76
|
+
reverse_proxy '/test', 'https://example.com'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should make a secure request" do
|
81
|
+
stub_request(:get, 'https://example.com/test/stuff').to_return({:body => "Proxied Secure App"})
|
82
|
+
get '/test/stuff'
|
83
|
+
last_response.body.should == "Proxied Secure App"
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
61
88
|
describe "with a route as a string" do
|
62
89
|
def app
|
63
90
|
Rack::ReverseProxy.new(dummy_app) do
|
@@ -103,11 +130,9 @@ describe Rack::ReverseProxy do
|
|
103
130
|
|
104
131
|
if %w|put post|.include?(method)
|
105
132
|
it "should forward the request payload" do
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
last_response.body.should == "test=test"
|
110
|
-
end
|
133
|
+
stub_request(method.to_sym, 'http://example.com/test').to_return { |req| {:body => req.body} }
|
134
|
+
eval "#{method} '/test', {:test => 'test'}"
|
135
|
+
last_response.body.should == "test=test"
|
111
136
|
end
|
112
137
|
end
|
113
138
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-reverse-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
+
- 4
|
8
9
|
- 0
|
9
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Jon Swope
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-11-07 00:00:00 -04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: rspec
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
27
30
|
segments:
|
28
31
|
- 0
|
29
32
|
version: "0"
|
@@ -33,9 +36,11 @@ dependencies:
|
|
33
36
|
name: rack-test
|
34
37
|
prerelease: false
|
35
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
36
40
|
requirements:
|
37
41
|
- - ">="
|
38
42
|
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
39
44
|
segments:
|
40
45
|
- 0
|
41
46
|
version: "0"
|
@@ -45,21 +50,27 @@ dependencies:
|
|
45
50
|
name: webmock
|
46
51
|
prerelease: false
|
47
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
48
54
|
requirements:
|
49
|
-
- -
|
55
|
+
- - ~>
|
50
56
|
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
51
58
|
segments:
|
59
|
+
- 1
|
60
|
+
- 5
|
52
61
|
- 0
|
53
|
-
version:
|
62
|
+
version: 1.5.0
|
54
63
|
type: :development
|
55
64
|
version_requirements: *id003
|
56
65
|
- !ruby/object:Gem::Dependency
|
57
66
|
name: rack
|
58
67
|
prerelease: false
|
59
68
|
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
60
70
|
requirements:
|
61
71
|
- - ">="
|
62
72
|
- !ruby/object:Gem::Version
|
73
|
+
hash: 23
|
63
74
|
segments:
|
64
75
|
- 1
|
65
76
|
- 0
|
@@ -75,6 +86,7 @@ extensions: []
|
|
75
86
|
|
76
87
|
extra_rdoc_files:
|
77
88
|
- LICENSE
|
89
|
+
- README
|
78
90
|
- README.rdoc
|
79
91
|
files:
|
80
92
|
- .document
|
@@ -88,6 +100,7 @@ files:
|
|
88
100
|
- spec/rack/reverse_proxy_spec.rb
|
89
101
|
- spec/spec.opts
|
90
102
|
- spec/spec_helper.rb
|
103
|
+
- README
|
91
104
|
has_rdoc: true
|
92
105
|
homepage: http://github.com/jaswope/rack-reverse-proxy
|
93
106
|
licenses: []
|
@@ -98,26 +111,30 @@ rdoc_options:
|
|
98
111
|
require_paths:
|
99
112
|
- lib
|
100
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
101
115
|
requirements:
|
102
116
|
- - ">="
|
103
117
|
- !ruby/object:Gem::Version
|
118
|
+
hash: 3
|
104
119
|
segments:
|
105
120
|
- 0
|
106
121
|
version: "0"
|
107
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
108
124
|
requirements:
|
109
125
|
- - ">="
|
110
126
|
- !ruby/object:Gem::Version
|
127
|
+
hash: 3
|
111
128
|
segments:
|
112
129
|
- 0
|
113
130
|
version: "0"
|
114
131
|
requirements: []
|
115
132
|
|
116
133
|
rubyforge_project:
|
117
|
-
rubygems_version: 1.3.
|
134
|
+
rubygems_version: 1.3.7
|
118
135
|
signing_key:
|
119
136
|
specification_version: 3
|
120
137
|
summary: A Simple Reverse Proxy for Rack
|
121
138
|
test_files:
|
122
|
-
- spec/rack/reverse_proxy_spec.rb
|
123
139
|
- spec/spec_helper.rb
|
140
|
+
- spec/rack/reverse_proxy_spec.rb
|