Skip to content

Commit 580cf86

Browse files
committed
Merge pull request #10 from markbates/proxy-by-lambda
Add Rack request to Matcher class
2 parents a587935 + d69923e commit 580cf86

File tree

6 files changed

+147
-11
lines changed

6 files changed

+147
-11
lines changed

Gemfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@ source "https://rubygems.org"
22

33
gemspec
44

5-
gem "rack-proxy", :git => 'https://github.com/tstmedia/rack-proxy.git'
5+
gem "rack-proxy", :git => 'https://github.com/tstmedia/rack-proxy.git'
6+
gem 'rb-fsevent'
7+
gem 'guard'
8+
gem 'guard-rspec'
9+
gem 'guard-shell'
10+
gem 'guard-bundler'
11+
gem 'terminal-notifier-guard'

Gemfile.lock

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,61 @@ GIT
88
PATH
99
remote: .
1010
specs:
11-
rack-reverse-proxy (0.6.0)
11+
rack-reverse-proxy (0.7.0)
1212
rack (>= 1.0.0)
1313

1414
GEM
1515
remote: https://rubygems.org/
1616
specs:
1717
addressable (2.2.6)
18+
coderay (1.0.9)
1819
crack (0.1.8)
20+
ffi (1.9.0)
21+
ffi (1.9.0-java)
22+
formatador (0.2.4)
23+
guard (1.8.1)
24+
formatador (>= 0.2.4)
25+
listen (>= 1.0.0)
26+
lumberjack (>= 1.0.2)
27+
pry (>= 0.9.10)
28+
thor (>= 0.14.6)
29+
guard-bundler (1.0.0)
30+
bundler (~> 1.0)
31+
guard (~> 1.1)
32+
guard-rspec (1.2.1)
33+
guard (>= 1.1)
34+
guard-shell (0.5.1)
35+
guard (>= 1.1.0)
36+
listen (1.2.2)
37+
rb-fsevent (>= 0.9.3)
38+
rb-inotify (>= 0.9)
39+
rb-kqueue (>= 0.2)
40+
lumberjack (1.0.4)
41+
method_source (0.8.1)
42+
pry (0.9.12.2)
43+
coderay (~> 1.0.5)
44+
method_source (~> 0.8)
45+
slop (~> 3.4)
46+
pry (0.9.12.2-java)
47+
coderay (~> 1.0.5)
48+
method_source (~> 0.8)
49+
slop (~> 3.4)
50+
spoon (~> 0.0)
1951
rack (1.4.1)
2052
rack-test (0.5.7)
2153
rack (>= 1.0)
2254
rake (0.8.7)
55+
rb-fsevent (0.9.3)
56+
rb-inotify (0.9.0)
57+
ffi (>= 0.5.0)
58+
rb-kqueue (0.2.0)
59+
ffi (>= 0.5.0)
2360
rspec (1.3.2)
61+
slop (3.4.5)
62+
spoon (0.0.4)
63+
ffi
64+
terminal-notifier-guard (1.5.3)
65+
thor (0.18.1)
2466
webmock (1.5.0)
2567
addressable (>= 2.2.2)
2668
crack (>= 0.1.7)
@@ -30,9 +72,15 @@ PLATFORMS
3072
ruby
3173

3274
DEPENDENCIES
75+
guard
76+
guard-bundler
77+
guard-rspec
78+
guard-shell
3379
rack-proxy!
3480
rack-reverse-proxy!
3581
rack-test (~> 0.5.7)
3682
rake (~> 0.8.7)
83+
rb-fsevent
3784
rspec (~> 1.3.2)
85+
terminal-notifier-guard
3886
webmock (~> 1.5.0)

Guardfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# A sample Guardfile
2+
# More info at https://github.com/guard/guard#readme
3+
4+
guard 'rspec', :version => 1 do
5+
watch(%r{^spec/.+_spec\.rb$})
6+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7+
watch('spec/spec_helper.rb') { "spec" }
8+
9+
# Rails example
10+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec" }
11+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14+
watch('config/routes.rb') { "spec/routing" }
15+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
16+
17+
# Capybara request specs
18+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
19+
20+
# Turnip features and steps
21+
watch(%r{^spec/acceptance/(.+)\.feature$})
22+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23+
end
24+
25+
26+
# Add files and commands to this file, like the example:
27+
# watch(%r{file/path}) { `command(s)` }
28+
#
29+
guard 'shell' do
30+
watch(/(.*).txt/) {|m| `tail #{m[0]}` }
31+
end

lib/rack/reverse_proxy.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def initialize(app = nil, &b)
1717

1818
def call(env)
1919
rackreq = Rack::Request.new(env)
20-
matcher = get_matcher(rackreq.fullpath, extract_http_request_headers(rackreq.env))
20+
matcher = get_matcher(rackreq.fullpath, extract_http_request_headers(rackreq.env), rackreq)
2121
return @app.call(env) if matcher.nil?
2222

2323
if @global_options[:newrelic_instrumentation]
@@ -34,6 +34,9 @@ def call(env)
3434

3535
def proxy(env, source_request, matcher)
3636
uri = matcher.get_uri(source_request.fullpath,env)
37+
if uri.nil?
38+
return @app.call(env)
39+
end
3740
options = @global_options.dup.merge(matcher.options)
3841

3942
# Initialize request
@@ -97,9 +100,9 @@ def reconstruct_header_name(name)
97100
name.sub(/^HTTP_/, "").gsub("_", "-")
98101
end
99102

100-
def get_matcher(path, headers)
103+
def get_matcher(path, headers, rackreq)
101104
matches = @matchers.select do |matcher|
102-
matcher.match?(path, headers)
105+
matcher.match?(path, headers, rackreq)
103106
end
104107

105108
if matches.length < 1

lib/rack/reverse_proxy_matcher.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ def initialize(matcher,url=nil,options)
1616

1717
attr_reader :matcher,:url, :default_url,:options
1818

19-
def match?(path, headers)
20-
match_path(path, headers) ? true : false
19+
def match?(path, *args)
20+
match_path(path, *args) ? true : false
2121
end
2222

2323
def get_uri(path,env)
24+
return nil if url.nil?
2425
_url=(url.respond_to?(:call) ? url.call(env) : url.clone)
2526
if _url =~/\$\d/
2627
match_path(path).to_a.each_with_index { |m, i| _url.gsub!("$#{i.to_s}", m) }
@@ -35,11 +36,15 @@ def to_s
3536
end
3637

3738
private
38-
def match_path(path, headers=nil)
39-
if @options[:accept_headers]
40-
match = matcher.match(path, headers)
41-
else
39+
def match_path(path, *args)
40+
headers = args[0]
41+
rackreq = args[1]
42+
arity = matcher.method(:match).arity
43+
if arity == -1
4244
match = matcher.match(path)
45+
else
46+
params = [path, (@options[:accept_headers] ? headers : nil), rackreq]
47+
match = matcher.match(*params[0..(arity - 1)])
4348
end
4449
@url = match.url(path) if match && default_url.nil?
4550
match

spec/rack/reverse_proxy_spec.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,49 @@ def app
262262
end
263263
end
264264

265+
describe "with a matching class" do
266+
class RequestMatcher
267+
attr_accessor :rackreq
268+
269+
def initialize(rackreq)
270+
self.rackreq = rackreq
271+
end
272+
273+
def self.match(path, headers, rackreq)
274+
if path.match(/^\/(test|users)/)
275+
RequestMatcher.new(rackreq)
276+
end
277+
end
278+
279+
def url(path)
280+
if rackreq.params["user"] == 'omer'
281+
'http://users-example.com' + path
282+
end
283+
end
284+
end
285+
286+
def app
287+
Rack::ReverseProxy.new(dummy_app) do
288+
reverse_proxy RequestMatcher
289+
end
290+
end
291+
292+
it "should forward requests to the calling app when the path is not matched" do
293+
get '/'
294+
last_response.body.should == "Dummy App"
295+
last_response.should be_ok
296+
end
297+
298+
it "should proxy requests when a pattern is matched" do
299+
stub_request(:get, 'http://users-example.com/users?user=omer').to_return({:body => "User App"})
300+
get '/test', user: "mark"
301+
last_response.body.should == "Dummy App"
302+
get '/users', user: 'omer'
303+
last_response.body.should == "User App"
304+
end
305+
end
306+
307+
265308
describe "with a matching class that accepts headers" do
266309
class MatcherHeaders
267310
def self.match(path, headers)

0 commit comments

Comments
 (0)