Skip to content

Commit 93ec24d

Browse files
committed
Added the ability to pass in the Rack request as an optional third argument to a Matcher class.
1 parent b88ff89 commit 93ec24d

File tree

4 files changed

+60
-16
lines changed

4 files changed

+60
-16
lines changed

Guardfile

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
# A sample Guardfile
22
# More info at https://github.com/guard/guard#readme
33

4-
guard 'bundler' do
5-
watch('Gemfile')
6-
# Uncomment next line if Gemfile contain `gemspec' command
7-
# watch(/^.+\.gemspec/)
8-
end
9-
104
guard 'rspec', :version => 1 do
115
watch(%r{^spec/.+_spec\.rb$})
126
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
137
watch('spec/spec_helper.rb') { "spec" }
148

159
# Rails example
16-
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec" }
1711
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
1812
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"] }
1913
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }

lib/rack/reverse_proxy.rb

Lines changed: 3 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]
@@ -97,9 +97,9 @@ def reconstruct_header_name(name)
9797
name.sub(/^HTTP_/, "").gsub("_", "-")
9898
end
9999

100-
def get_matcher(path, headers)
100+
def get_matcher(path, headers, rackreq)
101101
matches = @matchers.select do |matcher|
102-
matcher.match?(path, headers)
102+
matcher.match?(path, headers, rackreq)
103103
end
104104

105105
if matches.length < 1

lib/rack/reverse_proxy_matcher.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ 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)
@@ -35,11 +35,15 @@ def to_s
3535
end
3636

3737
private
38-
def match_path(path, headers=nil)
39-
if @options[:accept_headers]
40-
match = matcher.match(path, headers)
41-
else
38+
def match_path(path, *args)
39+
headers = args[0]
40+
rackreq = args[1]
41+
arity = matcher.method(:match).arity
42+
if arity == -1
4243
match = matcher.match(path)
44+
else
45+
params = [path, (@options[:accept_headers] ? headers : nil), rackreq]
46+
match = matcher.match(*params[0..(arity - 1)])
4347
end
4448
@url = match.url(path) if match && default_url.nil?
4549
match

spec/rack/reverse_proxy_spec.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,52 @@ 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+
else
283+
'http://example.com' + path
284+
end
285+
end
286+
end
287+
288+
def app
289+
Rack::ReverseProxy.new(dummy_app) do
290+
reverse_proxy RequestMatcher
291+
end
292+
end
293+
294+
it "should forward requests to the calling app when the path is not matched" do
295+
get '/'
296+
last_response.body.should == "Dummy App"
297+
last_response.should be_ok
298+
end
299+
300+
it "should proxy requests when a pattern is matched" do
301+
stub_request(:get, 'http://example.com/test?user=mark').to_return({:body => "Proxied App"})
302+
stub_request(:get, 'http://users-example.com/users?user=omer').to_return({:body => "User App"})
303+
get '/test', user: "mark"
304+
last_response.body.should == "Proxied App"
305+
get '/users', user: 'omer'
306+
last_response.body.should == "User App"
307+
end
308+
end
309+
310+
265311
describe "with a matching class that accepts headers" do
266312
class MatcherHeaders
267313
def self.match(path, headers)

0 commit comments

Comments
 (0)