@@ -5,65 +5,26 @@ class Rule
5
5
attr_reader :options
6
6
7
7
def initialize ( spec , url = nil , options = { } )
8
- @default_url = url
8
+ @custom_url = url . nil?
9
9
@url = url
10
10
@options = options
11
11
@spec = build_matcher ( spec )
12
12
end
13
13
14
14
def proxy? ( path , *args )
15
- match_path ( path , *args ) . count > 0
15
+ _matches ( path , *args ) . count > 0
16
16
end
17
17
18
- # Lots of calls with passing path and env around
19
- # Sounds like a class to me, Candidate?
20
18
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
28
20
end
29
21
30
22
def to_s
31
23
%("#{ spec } " => "#{ url } ")
32
24
end
33
25
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 )
67
28
headers = args [ 0 ]
68
29
rackreq = args [ 1 ]
69
30
arity = spec . method ( :match ) . arity
@@ -74,12 +35,77 @@ def match_path(path, *args)
74
35
match = spec . match ( *params [ 0 ..( arity - 1 ) ] )
75
36
end
76
37
# 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
78
39
Array ( match )
79
40
end
80
41
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
82
53
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
83
109
end
84
110
end
85
111
end
0 commit comments