Skip to content

Commit 9b47bae

Browse files
committed
Extract Rule::Candidate
1 parent c0fab4f commit 9b47bae

File tree

1 file changed

+72
-46
lines changed

1 file changed

+72
-46
lines changed

lib/rack_reverse_proxy/rule.rb

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,65 +5,26 @@ class Rule
55
attr_reader :options
66

77
def initialize(spec, url = nil, options = {})
8-
@default_url = url
8+
@custom_url = url.nil?
99
@url = url
1010
@options = options
1111
@spec = build_matcher(spec)
1212
end
1313

1414
def proxy?(path, *args)
15-
match_path(path, *args).count > 0
15+
_matches(path, *args).count > 0
1616
end
1717

18-
# Lots of calls with passing path and env around
19-
# Sounds like a class to me, Candidate?
2018
def get_uri(path, env)
21-
return nil unless url
22-
evaluated_url = evaluate_url(env)
23-
if with_substitutions?(evaluated_url)
24-
substitute_matches(evaluated_url, path)
25-
else
26-
build_simple_url(evaluated_url, path)
27-
end
19+
Candidate.new(self, url, custom_url, path, env).build_uri
2820
end
2921

3022
def to_s
3123
%("#{spec}" => "#{url}")
3224
end
3325

34-
private
35-
36-
attr_reader :spec, :url, :default_url
37-
38-
def build_simple_url(url, path)
39-
return URI.parse(url) unless default_url
40-
URI.join(url, path)
41-
end
42-
43-
def evaluate_url(env)
44-
return url.clone unless url.respond_to?(:call)
45-
url.call(env)
46-
end
47-
48-
def with_substitutions?(url)
49-
url =~ /\$\d/
50-
end
51-
52-
# FIXME: This function currently is stressful for GC
53-
def substitute_matches(url, path)
54-
match_path(path).each_with_index do |match, i|
55-
url = url.gsub("$#{i}", match)
56-
end
57-
URI(url)
58-
end
59-
60-
def build_matcher(spec)
61-
return /^#{spec}/ if spec.is_a?(String)
62-
return spec if spec.respond_to?(:match)
63-
fail ArgumentError, "Invalid Rule for reverse_proxy"
64-
end
65-
66-
def match_path(path, *args)
26+
# @private
27+
def _matches(path, *args)
6728
headers = args[0]
6829
rackreq = args[1]
6930
arity = spec.method(:match).arity
@@ -74,12 +35,77 @@ def match_path(path, *args)
7435
match = spec.match(*params[0..(arity - 1)])
7536
end
7637
# FIXME: This state mutation is very confusing
77-
@url = match.url(path) if match && default_url.nil?
38+
@url = match.url(path) if match && custom_url
7839
Array(match)
7940
end
8041

81-
# Candidate represents a path being verified
42+
private
43+
44+
attr_reader :spec, :url, :custom_url
45+
46+
def build_matcher(spec)
47+
return /^#{spec}/ if spec.is_a?(String)
48+
return spec if spec.respond_to?(:match)
49+
fail ArgumentError, "Invalid Rule for reverse_proxy"
50+
end
51+
52+
# Candidate represents a request being matched
8253
class Candidate
54+
def initialize(rule, url, custom_url, path, env)
55+
@rule = rule
56+
@env = env
57+
@path = path
58+
@custom_url = custom_url
59+
60+
@url = evaluate(url)
61+
end
62+
63+
def build_uri
64+
return nil unless url
65+
URI(raw_uri)
66+
end
67+
68+
private
69+
70+
attr_reader :rule, :url, :custom_url, :path, :env
71+
72+
def raw_uri
73+
return substitute_matches if with_substitutions?
74+
return just_uri if custom_url
75+
uri_with_path
76+
end
77+
78+
def just_uri
79+
URI.parse(url)
80+
end
81+
82+
def uri_with_path
83+
URI.join(url, path)
84+
end
85+
86+
def evaluate(url)
87+
return unless url
88+
return url.call(env) if lazy?(url)
89+
url.clone
90+
end
91+
92+
def lazy?(url)
93+
url.respond_to?(:call)
94+
end
95+
96+
def with_substitutions?
97+
url =~ /\$\d/
98+
end
99+
100+
def substitute_matches
101+
matches.each_with_index.inject(url) do |url, (match, i)|
102+
url.gsub("$#{i}", match)
103+
end
104+
end
105+
106+
def matches
107+
rule._matches(path)
108+
end
83109
end
84110
end
85111
end

0 commit comments

Comments
 (0)