Skip to content

Commit 159d109

Browse files
author
Peter Schrammel
committed
some refactoring, and giving each matcher it's options
1 parent 0c1d08f commit 159d109

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

lib/rack/reverse_proxy.rb

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,25 @@ module Rack
55
class ReverseProxy
66
def initialize(app = nil, &b)
77
@app = app || lambda { [404, [], []] }
8-
@paths = {}
9-
@opts = {:preserve_host => false}
8+
@matchers = []
9+
@global_options = {}
1010
instance_eval &b if block_given?
1111
end
1212

1313
def call(env)
1414
rackreq = Rack::Request.new(env)
15-
matcher, url = get_matcher_and_url rackreq.fullpath
15+
matcher = get_matcher rackreq.fullpath
1616
return @app.call(env) if matcher.nil?
1717

18-
uri = get_uri(url, matcher, rackreq.fullpath)
18+
uri = matcher.get_uri(rackreq.fullpath)
19+
all_opts = matcher.options #TODO: merge with global opts
1920
headers = Rack::Utils::HeaderHash.new
2021
env.each { |key, value|
2122
if key =~ /HTTP_(.*)/
2223
headers[$1] = value
2324
end
2425
}
25-
headers['HOST'] = uri.host if @opts[:preserve_host]
26+
headers['HOST'] = uri.host if all_opts[:preserve_host]
2627

2728
session = Net::HTTP.new(uri.host, uri.port)
2829
session.use_ssl = (uri.scheme == 'https')
@@ -32,10 +33,10 @@ def call(env)
3233
case m
3334
when "GET", "HEAD", "DELETE", "OPTIONS", "TRACE"
3435
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]
36+
req.basic_auth all_opts[:username], all_opts[:password] if all_opts[:username] and all_opts[:password]
3637
when "PUT", "POST"
3738
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]
39+
req.basic_auth all_opts[:username], all_opts[:password] if all_opts[:username] and all_opts[:password]
3940
req.content_length = rackreq.body.length
4041
req.body_stream = rackreq.body
4142
else
@@ -55,17 +56,17 @@ def call(env)
5556

5657
private
5758

58-
def get_matcher_and_url path
59-
matches = @paths.select do |matcher, url|
60-
match_path(path, matcher)
59+
def get_matcher path
60+
matches = @matchers.select do |matcher|
61+
matcher.match?(path)
6162
end
6263

6364
if matches.length < 1
6465
nil
6566
elsif matches.length > 1
6667
raise AmbiguousProxyMatch.new(path, matches)
6768
else
68-
matches.first.map{|a| a.dup}
69+
matches.first
6970
end
7071
end
7172

@@ -79,27 +80,10 @@ def create_response_headers http_response
7980
response_headers
8081
end
8182

82-
def match_path(path, matcher)
83-
if matcher.is_a?(Regexp)
84-
path.match(matcher)
85-
else
86-
path.match(/^#{matcher.to_s}/)
87-
end
88-
end
89-
90-
def get_uri(url, matcher, path)
91-
if url =~/\$\d/
92-
match_path(path, matcher).to_a.each_with_index { |m, i| url.gsub!("$#{i.to_s}", m) }
93-
URI(url)
94-
else
95-
URI.join(url, path)
96-
end
97-
end
9883

9984
def reverse_proxy matcher, url, opts={}
10085
raise GenericProxyURI.new(url) if matcher.is_a?(String) && URI(url).class == URI::Generic
101-
@paths.merge!(matcher => url)
102-
@opts.merge!(opts)
86+
@matchers << ReverseProxyMatcher.new(matcher,url,opts)
10387
end
10488
end
10589

@@ -129,8 +113,40 @@ def to_s
129113
private
130114

131115
def formatted_matches
132-
matches.map {|m| %Q("#{m[0].to_s}" => "#{m[1]}")}.join(', ')
116+
matches.map {|matcher| matcher.to_s}.join(', ')
133117
end
134118
end
135119

120+
class ReverseProxyMatcher
121+
def initialize(matching,url,options)
122+
@matching=matching
123+
@url=url
124+
@options={:preserve_host => false}.merge(options)
125+
@matching_regexp= matching.kind_of?(Regexp) ? matching : /^#{matching.to_s}/
126+
end
127+
128+
attr_reader :matching,:matching_regexp,:url,:options
129+
130+
def match?(path)
131+
match_path(path) ? true : false
132+
end
133+
134+
def get_uri(path)
135+
if url =~/\$\d/
136+
match_path(path).to_a.each_with_index { |m, i| url.gsub!("$#{i.to_s}", m) }
137+
URI(url)
138+
else
139+
URI.join(url, path)
140+
end
141+
end
142+
def to_s
143+
%Q("#{matching.to_s}" => "#{url}")
144+
end
145+
private
146+
def match_path(path)
147+
path.match(matching_regexp)
148+
end
149+
150+
151+
end
136152
end

0 commit comments

Comments
 (0)