rack-reverse-proxy 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/rack/reverse_proxy.rb +8 -2
- data/rack-reverse-proxy.gemspec +15 -18
- data/spec/rack/reverse_proxy_spec.rb +35 -1
- metadata +55 -90
- data/.gitignore +0 -21
- data/README +0 -26
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
data/lib/rack/reverse_proxy.rb
CHANGED
@@ -6,6 +6,7 @@ module Rack
|
|
6
6
|
def initialize(app = nil, &b)
|
7
7
|
@app = app || lambda { [404, [], []] }
|
8
8
|
@paths = {}
|
9
|
+
@opts = {:preserve_host => false}
|
9
10
|
instance_eval &b if block_given?
|
10
11
|
end
|
11
12
|
|
@@ -21,7 +22,7 @@ module Rack
|
|
21
22
|
headers[$1] = value
|
22
23
|
end
|
23
24
|
}
|
24
|
-
headers['HOST'] = uri.host
|
25
|
+
headers['HOST'] = uri.host if @opts[:preserve_host]
|
25
26
|
|
26
27
|
session = Net::HTTP.new(uri.host, uri.port)
|
27
28
|
session.use_ssl = (uri.scheme == 'https')
|
@@ -31,8 +32,10 @@ module Rack
|
|
31
32
|
case m
|
32
33
|
when "GET", "HEAD", "DELETE", "OPTIONS", "TRACE"
|
33
34
|
req = Net::HTTP.const_get(m.capitalize).new(uri.request_uri, headers)
|
35
|
+
req.basic_auth @opts[:username], @opts[:password] if @opts[:username] and @opts[:password]
|
34
36
|
when "PUT", "POST"
|
35
37
|
req = Net::HTTP.const_get(m.capitalize).new(uri.request_uri, headers)
|
38
|
+
req.basic_auth @opts[:username], @opts[:password] if @opts[:username] and @opts[:password]
|
36
39
|
req.content_length = rackreq.body.length
|
37
40
|
req.body_stream = rackreq.body
|
38
41
|
else
|
@@ -70,6 +73,8 @@ module Rack
|
|
70
73
|
response_headers = Rack::Utils::HeaderHash.new(http_response.to_hash)
|
71
74
|
# handled by Rack
|
72
75
|
response_headers.delete('status')
|
76
|
+
# TODO: figure out how to handle chunked responses
|
77
|
+
response_headers.delete('transfer-encoding')
|
73
78
|
# TODO: Verify Content Length, and required Rack headers
|
74
79
|
response_headers
|
75
80
|
end
|
@@ -91,9 +96,10 @@ module Rack
|
|
91
96
|
end
|
92
97
|
end
|
93
98
|
|
94
|
-
def reverse_proxy matcher, url
|
99
|
+
def reverse_proxy matcher, url, opts={}
|
95
100
|
raise GenericProxyURI.new(url) if matcher.is_a?(String) && URI(url).class == URI::Generic
|
96
101
|
@paths.merge!(matcher => url)
|
102
|
+
@opts.merge!(opts)
|
97
103
|
end
|
98
104
|
end
|
99
105
|
|
data/rack-reverse-proxy.gemspec
CHANGED
@@ -1,43 +1,40 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rack-reverse-proxy}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.1"
|
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{
|
12
|
+
s.date = %q{2011-04-04}
|
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
|
-
|
18
|
-
"README.rdoc"
|
17
|
+
"README.rdoc"
|
19
18
|
]
|
20
19
|
s.files = [
|
21
20
|
".document",
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
"spec/spec_helper.rb"
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/rack/reverse_proxy.rb",
|
26
|
+
"rack-reverse-proxy.gemspec",
|
27
|
+
"spec/rack/reverse_proxy_spec.rb",
|
28
|
+
"spec/spec.opts",
|
29
|
+
"spec/spec_helper.rb"
|
32
30
|
]
|
33
31
|
s.homepage = %q{http://github.com/jaswope/rack-reverse-proxy}
|
34
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
35
32
|
s.require_paths = ["lib"]
|
36
33
|
s.rubygems_version = %q{1.3.7}
|
37
34
|
s.summary = %q{A Simple Reverse Proxy for Rack}
|
38
35
|
s.test_files = [
|
39
|
-
"spec/
|
40
|
-
|
36
|
+
"spec/rack/reverse_proxy_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
41
38
|
]
|
42
39
|
|
43
40
|
if s.respond_to? :specification_version then
|
@@ -15,7 +15,7 @@ describe Rack::ReverseProxy do
|
|
15
15
|
describe "as middleware" do
|
16
16
|
def app
|
17
17
|
Rack::ReverseProxy.new(dummy_app) do
|
18
|
-
reverse_proxy '/test', 'http://example.com/'
|
18
|
+
reverse_proxy '/test', 'http://example.com/', {:preserve_host => true}
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -37,12 +37,46 @@ describe Rack::ReverseProxy do
|
|
37
37
|
last_response.headers['Status'].should == nil
|
38
38
|
end
|
39
39
|
|
40
|
+
it "the response header should never transfer-encoding" do
|
41
|
+
stub_request(:any, 'example.com/test/stuff').to_return(:headers => {'transfer-encoding' => 'Chunked'})
|
42
|
+
get '/test/stuff'
|
43
|
+
last_response.headers['transfer-encoding'].should == nil
|
44
|
+
end
|
45
|
+
|
40
46
|
it "should set the Host header" do
|
41
47
|
stub_request(:any, 'example.com/test/stuff')
|
42
48
|
get '/test/stuff'
|
43
49
|
a_request(:get, 'http://example.com/test/stuff').with(:headers => {"Host" => "example.com"}).should have_been_made
|
44
50
|
end
|
45
51
|
|
52
|
+
describe "with preserve host turned off" do
|
53
|
+
def app
|
54
|
+
Rack::ReverseProxy.new(dummy_app) do
|
55
|
+
reverse_proxy '/test', 'http://example.com/'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not set the Host header" do
|
60
|
+
stub_request(:any, 'example.com/test/stuff')
|
61
|
+
get '/test/stuff'
|
62
|
+
a_request(:get, 'http://example.com/test/stuff').should have_been_made
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "with basic auth turned on" do
|
67
|
+
def app
|
68
|
+
Rack::ReverseProxy.new(dummy_app) do
|
69
|
+
reverse_proxy '/test', 'http://example.com/', {:username => "joe", :password => "shmoe"}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should make request with basic auth" do
|
74
|
+
stub_request(:get, "http://joe:shmoe@example.com/test/stuff").to_return(:body => "secured content")
|
75
|
+
get '/test/stuff'
|
76
|
+
last_response.body.should == "secured content"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
46
80
|
describe "with ambiguous routes" do
|
47
81
|
def app
|
48
82
|
Rack::ReverseProxy.new(dummy_app) do
|
metadata
CHANGED
@@ -1,96 +1,71 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-reverse-proxy
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 0
|
10
|
-
version: 0.4.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.1
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Jon Swope
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2010-11-07 00:00:00 -04:00
|
12
|
+
date: 2011-04-04 00:00:00.000000000 -04:00
|
19
13
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
22
16
|
name: rspec
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &20805780 !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
33
23
|
type: :development
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: rack-test
|
37
24
|
prerelease: false
|
38
|
-
|
25
|
+
version_requirements: *20805780
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rack-test
|
28
|
+
requirement: &20805260 !ruby/object:Gem::Requirement
|
39
29
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
version: "0"
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
47
34
|
type: :development
|
48
|
-
version_requirements: *id002
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: webmock
|
51
35
|
prerelease: false
|
52
|
-
|
36
|
+
version_requirements: *20805260
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: webmock
|
39
|
+
requirement: &20804660 !ruby/object:Gem::Requirement
|
53
40
|
none: false
|
54
|
-
requirements:
|
41
|
+
requirements:
|
55
42
|
- - ~>
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
hash: 3
|
58
|
-
segments:
|
59
|
-
- 1
|
60
|
-
- 5
|
61
|
-
- 0
|
43
|
+
- !ruby/object:Gem::Version
|
62
44
|
version: 1.5.0
|
63
45
|
type: :development
|
64
|
-
version_requirements: *id003
|
65
|
-
- !ruby/object:Gem::Dependency
|
66
|
-
name: rack
|
67
46
|
prerelease: false
|
68
|
-
|
47
|
+
version_requirements: *20804660
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rack
|
50
|
+
requirement: &20804080 !ruby/object:Gem::Requirement
|
69
51
|
none: false
|
70
|
-
requirements:
|
71
|
-
- -
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
hash: 23
|
74
|
-
segments:
|
75
|
-
- 1
|
76
|
-
- 0
|
77
|
-
- 0
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
78
55
|
version: 1.0.0
|
79
56
|
type: :runtime
|
80
|
-
|
81
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *20804080
|
59
|
+
description: A Rack based reverse proxy for basic needs. Useful for testing or in
|
60
|
+
cases where webserver configuration is unavailable.
|
82
61
|
email: jaswope@gmail.com
|
83
62
|
executables: []
|
84
|
-
|
85
63
|
extensions: []
|
86
|
-
|
87
|
-
extra_rdoc_files:
|
64
|
+
extra_rdoc_files:
|
88
65
|
- LICENSE
|
89
|
-
- README
|
90
66
|
- README.rdoc
|
91
|
-
files:
|
67
|
+
files:
|
92
68
|
- .document
|
93
|
-
- .gitignore
|
94
69
|
- LICENSE
|
95
70
|
- README.rdoc
|
96
71
|
- Rakefile
|
@@ -100,41 +75,31 @@ files:
|
|
100
75
|
- spec/rack/reverse_proxy_spec.rb
|
101
76
|
- spec/spec.opts
|
102
77
|
- spec/spec_helper.rb
|
103
|
-
- README
|
104
78
|
has_rdoc: true
|
105
79
|
homepage: http://github.com/jaswope/rack-reverse-proxy
|
106
80
|
licenses: []
|
107
|
-
|
108
81
|
post_install_message:
|
109
|
-
rdoc_options:
|
110
|
-
|
111
|
-
require_paths:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
112
84
|
- lib
|
113
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
86
|
none: false
|
115
|
-
requirements:
|
116
|
-
- -
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
|
119
|
-
|
120
|
-
- 0
|
121
|
-
version: "0"
|
122
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
92
|
none: false
|
124
|
-
requirements:
|
125
|
-
- -
|
126
|
-
- !ruby/object:Gem::Version
|
127
|
-
|
128
|
-
segments:
|
129
|
-
- 0
|
130
|
-
version: "0"
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
131
97
|
requirements: []
|
132
|
-
|
133
98
|
rubyforge_project:
|
134
|
-
rubygems_version: 1.
|
99
|
+
rubygems_version: 1.6.1
|
135
100
|
signing_key:
|
136
101
|
specification_version: 3
|
137
102
|
summary: A Simple Reverse Proxy for Rack
|
138
|
-
test_files:
|
139
|
-
- spec/spec_helper.rb
|
103
|
+
test_files:
|
140
104
|
- spec/rack/reverse_proxy_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
data/.gitignore
DELETED
data/README
DELETED
@@ -1,26 +0,0 @@
|
|
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
|
-
|