addressive 0.1.0.alpha → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/addressive.gemspec +4 -4
- data/lib/addressive.rb +86 -27
- data/lib/addressive/{graphviz.rb → backports.rb} +12 -5
- data/lib/addressive/builder.rb +8 -0
- data/lib/addressive/graph.rb +39 -29
- data/lib/addressive/graph/builds_uris.rb +47 -0
- data/lib/addressive/graph/middleware.rb +38 -0
- data/lib/addressive/rack_ext.rb +0 -0
- data/lib/addressive/router.rb +33 -23
- data/lib/addressive/static.rb +1 -1
- metadata +55 -26
data/addressive.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'addressive'
|
3
|
-
s.version = '0.1.0
|
4
|
-
s.date = '
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
5
5
|
s.authors = ["HannesG"]
|
6
6
|
s.email = %q{hannes.georg@googlemail.com}
|
7
7
|
s.summary = 'A system which should help bringing different Rack applications together.'
|
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
|
|
12
12
|
|
13
13
|
s.files = Dir.glob('lib/**/**/*.rb') + ['addressive.gemspec']
|
14
14
|
|
15
|
-
s.add_dependency 'uri_template', '
|
16
|
-
|
15
|
+
s.add_dependency 'uri_template', '>= 0.5.1'
|
16
|
+
|
17
17
|
s.add_development_dependency 'simplecov'
|
18
18
|
s.add_development_dependency 'rspec'
|
19
19
|
s.add_development_dependency 'yard'
|
data/lib/addressive.rb
CHANGED
@@ -15,10 +15,11 @@
|
|
15
15
|
# (c) 2011 by Hannes Georg
|
16
16
|
#
|
17
17
|
|
18
|
-
|
19
|
-
require File.expand_path('../../uri_template7/lib/uri_template',File.dirname(__FILE__))
|
18
|
+
require 'uri_template'
|
20
19
|
require 'ostruct'
|
21
20
|
|
21
|
+
require File.expand_path('addressive/backports', File.dirname(__FILE__))
|
22
|
+
|
22
23
|
# Addressive is library which should make it possible for different rack-applications to live together on the same server.
|
23
24
|
# To accomplish this, addressive supplies you with:
|
24
25
|
# - A model for a graph in which each node is one application.
|
@@ -37,6 +38,8 @@ module Addressive
|
|
37
38
|
|
38
39
|
ADDRESSIVE_ENV_KEY = 'addressive'.freeze
|
39
40
|
|
41
|
+
DEFAULT_ACTION = :default
|
42
|
+
|
40
43
|
class Error < StandardError
|
41
44
|
|
42
45
|
end
|
@@ -48,7 +51,14 @@ module Addressive
|
|
48
51
|
|
49
52
|
def initialize(builder)
|
50
53
|
@builder = builder
|
51
|
-
super(
|
54
|
+
super([
|
55
|
+
"No URISpec found for #{builder.inspect}. Only got:",
|
56
|
+
*builder.node.uri_specs.map{|key,specs|
|
57
|
+
["\t#{key.inspect} :",
|
58
|
+
*specs.select{|spec| spec.valid? and spec.emit != false }.map{|spec| "\t\t#{spec.template.inspect}" }
|
59
|
+
].join("\n")
|
60
|
+
}
|
61
|
+
].join("\n"))
|
52
62
|
end
|
53
63
|
|
54
64
|
end
|
@@ -83,6 +93,12 @@ module Addressive
|
|
83
93
|
#
|
84
94
|
# @example
|
85
95
|
# node = Addressive::Node.new
|
96
|
+
# node.uri_spec << Addressive::URISpec.new( URITemplate.new('/an/uri/with/{var}') )
|
97
|
+
# bldr = Addressive::URIBuilder.new(node)
|
98
|
+
# bldr.uri('var'=>'VAR!').to_s #=> '/an/uri/with/VAR%21'
|
99
|
+
#
|
100
|
+
# @example
|
101
|
+
# node = Addressive::Node.new
|
86
102
|
# node.uri_spec(:show) << Addressive::URISpec.new( URITemplate.new('/an/uri/with/{var}') )
|
87
103
|
# bldr = Addressive::URIBuilder.new(node)
|
88
104
|
# bldr.uri(:show, 'var'=>'VAR!').to_s #=> '/an/uri/with/VAR%21'
|
@@ -90,14 +106,20 @@ module Addressive
|
|
90
106
|
# @return URIBuilder
|
91
107
|
def uri(*args)
|
92
108
|
return uri_builder_delegate.uri(*args) if uri_builder_delegate
|
93
|
-
|
109
|
+
argz = args.collect_concat{|a| a.respond_to?(:to_addressive) ? a.to_addressive : [a] }
|
110
|
+
hashes, path = argz.partition{|x| x.kind_of? Hash}
|
94
111
|
node = self.node
|
95
112
|
action = self.action
|
96
113
|
if path.size >= 1
|
97
114
|
node = node.traverse(*path[0..-2])
|
98
|
-
|
115
|
+
if node.edge? path.last
|
116
|
+
node = node.traverse(path.last)
|
117
|
+
action = DEFAULT_ACTION
|
118
|
+
else
|
119
|
+
action = path.last
|
120
|
+
end
|
99
121
|
end
|
100
|
-
derive_uri_builder(action, hashes.
|
122
|
+
derive_uri_builder(action, hashes.map{|hsh| Hash[hsh.map{|k,v| [k.to_s,v] }] }.inject(&:merge!), node)
|
101
123
|
end
|
102
124
|
|
103
125
|
private
|
@@ -116,7 +138,7 @@ module Addressive
|
|
116
138
|
attr_reader :origin,:node,:variables,:action
|
117
139
|
|
118
140
|
# @private
|
119
|
-
def initialize(origin, action
|
141
|
+
def initialize(origin, action=DEFAULT_ACTION, vars={}, node=origin)
|
120
142
|
@origin = origin
|
121
143
|
@node = node
|
122
144
|
@action = action
|
@@ -153,7 +175,7 @@ module Addressive
|
|
153
175
|
def uri_builder_specs
|
154
176
|
return @specs ||= begin
|
155
177
|
varnames = (self.variables || {} ).keys
|
156
|
-
self.node.uri_spec(self.action).select{|s| s.valid? and (s.variables - varnames).none? }.sort_by{|s| (varnames - s.variables).size }
|
178
|
+
self.node.uri_spec(self.action).select{|s| s.valid? and s.emit != false and (s.variables - varnames).none? }.sort_by{|s| (varnames - s.variables).size }
|
157
179
|
end
|
158
180
|
end
|
159
181
|
end
|
@@ -170,14 +192,32 @@ module Addressive
|
|
170
192
|
def variables
|
171
193
|
@template ? @template.variables : []
|
172
194
|
end
|
173
|
-
|
195
|
+
|
196
|
+
def prefix!(with, op=:/)
|
197
|
+
return self unless valid?
|
198
|
+
@template = URITemplate.apply(with, op, @template )
|
199
|
+
return self
|
200
|
+
end
|
201
|
+
|
202
|
+
def set_unless(key, value)
|
203
|
+
send("#{key}=".to_sym, send(key) || value)
|
204
|
+
end
|
205
|
+
|
174
206
|
def initialize(template, *args)
|
175
207
|
@template = template
|
176
208
|
super(*args)
|
177
209
|
end
|
210
|
+
|
211
|
+
def hash
|
212
|
+
@template.hash ^ super
|
213
|
+
end
|
214
|
+
|
215
|
+
def ==(other)
|
216
|
+
@template == other.template && super
|
217
|
+
end
|
178
218
|
|
179
219
|
def inspect
|
180
|
-
['#<',self.class.name,': ',template.inspect
|
220
|
+
( ['#<',self.class.name,': ',template.inspect ] + @table.map{|k,v| " #{k}=#{v.inspect}"} + ['>'] ).join
|
181
221
|
end
|
182
222
|
|
183
223
|
end
|
@@ -190,11 +230,11 @@ module Addressive
|
|
190
230
|
def converter(defaults = self.all_defaults)
|
191
231
|
lambda{|spec|
|
192
232
|
if spec.kind_of? URISpec
|
193
|
-
|
233
|
+
normalize( spec.dup, defaults )
|
194
234
|
elsif spec.kind_of? URITemplate
|
195
|
-
|
235
|
+
normalize( URISpec.new( spec ) , defaults)
|
196
236
|
elsif spec.kind_of? String
|
197
|
-
|
237
|
+
normalize( URISpec.new( URITemplate.new(spec) ) , defaults)
|
198
238
|
elsif spec.kind_of? Array
|
199
239
|
spec.map(&self.converter(defaults))
|
200
240
|
elsif spec.kind_of? Hash
|
@@ -209,13 +249,11 @@ module Addressive
|
|
209
249
|
protected :converter
|
210
250
|
|
211
251
|
def normalize( spec, defaults = self.all_defaults )
|
212
|
-
|
213
|
-
spec.
|
252
|
+
defaults.each do |key,value|
|
253
|
+
spec.set_unless( key, value)
|
214
254
|
end
|
215
|
-
|
216
|
-
|
217
|
-
spec.template = URITemplate.apply( defaults[:prefix] , :/ , spec.template)
|
218
|
-
end
|
255
|
+
if defaults[:rewrite]
|
256
|
+
spec = Array( defaults[:rewrite].call(spec) )
|
219
257
|
end
|
220
258
|
return spec
|
221
259
|
end
|
@@ -223,8 +261,9 @@ module Addressive
|
|
223
261
|
attr_reader :defaults
|
224
262
|
|
225
263
|
def initialize(defaults, parent = nil)
|
226
|
-
@defaults = defaults
|
264
|
+
@defaults = defaults.dup
|
227
265
|
@parent = parent
|
266
|
+
validate!
|
228
267
|
end
|
229
268
|
|
230
269
|
def convert(*args)
|
@@ -236,10 +275,18 @@ module Addressive
|
|
236
275
|
def all_defaults
|
237
276
|
@parent ? @parent.all_defaults.merge(defaults) : defaults
|
238
277
|
end
|
239
|
-
|
278
|
+
|
240
279
|
def derive(nu_defaults)
|
241
280
|
self.class.new(nu_defaults, self)
|
242
281
|
end
|
282
|
+
|
283
|
+
private
|
284
|
+
|
285
|
+
def validate!(defaults = self.all_defaults)
|
286
|
+
if defaults[:rewrite] && !defaults[:rewrite].respond_to?(:call)
|
287
|
+
raise ArgumentError.new("Expected option :rewrite to respond to :call ( got: #{defaults[:rewrite].inspect} ).")
|
288
|
+
end
|
289
|
+
end
|
243
290
|
|
244
291
|
end
|
245
292
|
|
@@ -314,8 +361,17 @@ module Addressive
|
|
314
361
|
raise NoEdgeFound.new(self, args.first)
|
315
362
|
end
|
316
363
|
end
|
317
|
-
|
318
|
-
def
|
364
|
+
|
365
|
+
def edge?(name)
|
366
|
+
return edges.key?(name)
|
367
|
+
end
|
368
|
+
|
369
|
+
def uri_spec?(name = DEFAULT_ACTION)
|
370
|
+
@uri_specs.key? name
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
def uri_spec(name = DEFAULT_ACTION)
|
319
375
|
@uri_specs[name]
|
320
376
|
end
|
321
377
|
|
@@ -341,14 +397,17 @@ module Addressive
|
|
341
397
|
# @example
|
342
398
|
# node = Addressive.node do
|
343
399
|
# edge( :another ) do
|
344
|
-
# default :
|
345
|
-
#
|
400
|
+
# default :rewrite, lambda{|spec|
|
401
|
+
# spec.template = URITemplate.new('/another') / spec.template
|
402
|
+
# spec
|
403
|
+
# }
|
404
|
+
# uri '/'
|
346
405
|
# end
|
347
|
-
# uri
|
406
|
+
# uri '/'
|
348
407
|
# end
|
349
408
|
#
|
350
409
|
# node.uri.to_s #=> '/'
|
351
|
-
# node.uri(:another
|
410
|
+
# node.uri(:another).to_s #=> '/another/'
|
352
411
|
#
|
353
412
|
# @param name [Symbol] a name for this node
|
354
413
|
# @yield {NodeBuilder}
|
@@ -12,10 +12,17 @@
|
|
12
12
|
# You should have received a copy of the GNU General Public License
|
13
13
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
#
|
15
|
-
# (c)
|
15
|
+
# (c) 2012 by Hannes Georg
|
16
16
|
#
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
unless [].respond_to? :collect_concat
|
19
|
+
Enumerable.class_eval do
|
20
|
+
def collect_concat
|
21
|
+
result = []
|
22
|
+
each do |e|
|
23
|
+
result += yield e
|
24
|
+
end
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/addressive/graph.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
# You should have received a copy of the GNU General Public License
|
13
13
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
14
|
#
|
15
|
-
# (c) 2011 by Hannes Georg
|
15
|
+
# (c) 2011 - 2012 by Hannes Georg
|
16
16
|
#
|
17
17
|
|
18
18
|
module Addressive
|
@@ -21,27 +21,43 @@ module Addressive
|
|
21
21
|
# Graphs are only used to generate nodes and their relations.
|
22
22
|
# They will be GCed when they are done.
|
23
23
|
class Graph
|
24
|
-
|
24
|
+
|
25
|
+
require 'addressive/graph/builds_uris'
|
26
|
+
require 'addressive/graph/middleware'
|
27
|
+
|
25
28
|
# An app builder is used to add uris for a certain app to a node.
|
26
29
|
class AppBuilder
|
27
|
-
|
30
|
+
|
31
|
+
include BuildsURIs
|
32
|
+
|
33
|
+
attr :spec_factory, :node, :defaults
|
34
|
+
|
28
35
|
# @private
|
29
36
|
def initialize(node, factory, app)
|
30
37
|
@node = node
|
31
38
|
@app = app
|
32
39
|
@spec_factory = factory
|
40
|
+
@callback = nil
|
41
|
+
@defaults = {}
|
42
|
+
@middleware = Middleware::End
|
33
43
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
44
|
+
|
45
|
+
def spec_factory_with_options(overrides)
|
46
|
+
if overrides.key? :app
|
47
|
+
cb = @middleware.unwind(overrides[:app])
|
48
|
+
else
|
49
|
+
cb = (@callback ||= @middleware.unwind(@app))
|
50
|
+
end
|
51
|
+
super( {:callback => cb}.merge(overrides) )
|
38
52
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
53
|
+
|
54
|
+
def use(middleware, *args, &block)
|
55
|
+
if middleware.respond_to? :call
|
56
|
+
@middleware <<= proc{|app| proc{|env| middleware.call(env, app, *args, &block) } }
|
57
|
+
else
|
58
|
+
@middleware <<= proc{|app| middleware.new(app,*args, &block) }
|
59
|
+
end
|
60
|
+
@callback = nil
|
45
61
|
end
|
46
62
|
|
47
63
|
end
|
@@ -49,14 +65,17 @@ module Addressive
|
|
49
65
|
# A NodeBuilder is used to build a Node inside a Graph.
|
50
66
|
# This class should not be generated directly, it's created for you by {Builder#node}.
|
51
67
|
class NodeBuilder
|
52
|
-
|
53
|
-
|
54
|
-
|
68
|
+
|
69
|
+
include BuildsURIs
|
70
|
+
|
71
|
+
attr :spec_factory, :node, :defaults
|
72
|
+
|
55
73
|
# @private
|
56
74
|
def initialize(network,node)
|
57
75
|
@network = network
|
58
76
|
@node = node
|
59
|
-
@
|
77
|
+
@defaults = {}
|
78
|
+
@spec_factory = network.spec_factory
|
60
79
|
end
|
61
80
|
|
62
81
|
# Adds an edge from the current node to a node with the given name.
|
@@ -90,17 +109,6 @@ module Addressive
|
|
90
109
|
|
91
110
|
alias ref edge
|
92
111
|
|
93
|
-
# Sets a default value for an option.
|
94
|
-
def default(name, value)
|
95
|
-
@spec_factory.defaults[name] = value
|
96
|
-
end
|
97
|
-
|
98
|
-
# Adds one or more uri specs for a given name.
|
99
|
-
def uri(name,*args)
|
100
|
-
@node.uri_spec(name) << @spec_factory.convert(args)
|
101
|
-
return @node.uri_spec(name)
|
102
|
-
end
|
103
|
-
|
104
112
|
# Adds an rack-application to this node.
|
105
113
|
#
|
106
114
|
# @example
|
@@ -142,7 +150,9 @@ module Addressive
|
|
142
150
|
end
|
143
151
|
return builder
|
144
152
|
end
|
145
|
-
|
153
|
+
|
154
|
+
alias run app
|
155
|
+
|
146
156
|
end
|
147
157
|
|
148
158
|
# A Builder is used to construct a network.
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
# This program is free software: you can redistribute it and/or modify
|
3
|
+
# it under the terms of the Affero GNU General Public License as published by
|
4
|
+
# the Free Software Foundation, either version 3 of the License, or
|
5
|
+
# (at your option) any later version.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
|
+
#
|
15
|
+
# (c) 2011 - 2012 by Hannes Georg
|
16
|
+
#
|
17
|
+
|
18
|
+
module Addressive; module Graph::BuildsURIs
|
19
|
+
|
20
|
+
# Adds one or more uri specs for a given name.
|
21
|
+
def uri(name_or_uri,*args)
|
22
|
+
if name_or_uri.kind_of? Symbol
|
23
|
+
name = name_or_uri
|
24
|
+
else
|
25
|
+
name = DEFAULT_ACTION
|
26
|
+
args.unshift( name_or_uri )
|
27
|
+
end
|
28
|
+
specs = node.uri_spec(name)
|
29
|
+
options = {}
|
30
|
+
if args.size > 1 && args.last.kind_of?(Hash)
|
31
|
+
options = args.pop
|
32
|
+
end
|
33
|
+
specs << spec_factory_with_options(options).convert(*args)
|
34
|
+
return specs
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def spec_factory_with_options(overrides={})
|
39
|
+
return spec_factory.derive( defaults.merge(overrides) )
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sets a default value for an option.
|
43
|
+
def default(name, value)
|
44
|
+
defaults[name] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
end; end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
# This program is free software: you can redistribute it and/or modify
|
3
|
+
# it under the terms of the Affero GNU General Public License as published by
|
4
|
+
# the Free Software Foundation, either version 3 of the License, or
|
5
|
+
# (at your option) any later version.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
14
|
+
#
|
15
|
+
# (c) 2011 - 2012 by Hannes Georg
|
16
|
+
#
|
17
|
+
|
18
|
+
module Addressive; class Graph::Middleware
|
19
|
+
|
20
|
+
def initialize(proc, rest = End)
|
21
|
+
@proc, @rest = proc, rest
|
22
|
+
end
|
23
|
+
|
24
|
+
def unwind(app)
|
25
|
+
@proc.call( @rest.unwind(app) )
|
26
|
+
end
|
27
|
+
|
28
|
+
def <<(proc)
|
29
|
+
self.class.new(proc, self)
|
30
|
+
end
|
31
|
+
|
32
|
+
End = self.new(nil,nil)
|
33
|
+
|
34
|
+
def End.unwind(app)
|
35
|
+
return app
|
36
|
+
end
|
37
|
+
|
38
|
+
end ; end
|
File without changes
|
data/lib/addressive/router.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
require 'rack/request'
|
19
19
|
require 'thread'
|
20
|
+
require 'enumerator'
|
20
21
|
|
21
22
|
module Addressive
|
22
23
|
|
@@ -54,7 +55,7 @@ module Addressive
|
|
54
55
|
@routes = []
|
55
56
|
end
|
56
57
|
|
57
|
-
def preroute(
|
58
|
+
def preroute(*_)
|
58
59
|
return self
|
59
60
|
end
|
60
61
|
|
@@ -72,21 +73,25 @@ module Addressive
|
|
72
73
|
|
73
74
|
def done!
|
74
75
|
# compile *gnihihi*
|
75
|
-
code =
|
76
|
-
|
76
|
+
code = (
|
77
|
+
['def each(proto,host,path)',
|
78
|
+
'routes = @routes.to_enum',
|
79
|
+
'host_path = host + path; proto_host_path = proto + host + path'] +
|
80
|
+
@routes.each_with_index.map{|r,i|
|
77
81
|
"route = routes.next
|
78
|
-
vars = route.template.extract(#{r.template.
|
82
|
+
vars = route.template.extract(#{r.template.scheme? ? 'proto_host_path' : (r.template.host? ? 'host_path' : 'path')})
|
79
83
|
if vars
|
80
|
-
yield( route, vars, #{i} )
|
84
|
+
yield( route, vars, #{i+1} )
|
81
85
|
end
|
82
86
|
"
|
83
|
-
}
|
87
|
+
} + [ 'end']).join("\n")
|
84
88
|
instance_eval(code)
|
85
89
|
end
|
86
90
|
|
87
|
-
def each(path
|
91
|
+
def each(proto,host,path)
|
92
|
+
host_path = host + path; proto_host_path = proto + host + path
|
88
93
|
@routes.each_with_index do |route,i|
|
89
|
-
vars = route.template.extract(route.template.
|
94
|
+
vars = route.template.extract(route.template.scheme? ? proto_host_path : (route.template.host? ? host_path : path) )
|
90
95
|
if vars
|
91
96
|
yield( route, vars, i )
|
92
97
|
end
|
@@ -103,8 +108,8 @@ module Addressive
|
|
103
108
|
@partitions = partitions
|
104
109
|
end
|
105
110
|
|
106
|
-
def preroute(path
|
107
|
-
@partitions[
|
111
|
+
def preroute(proto,host,path)
|
112
|
+
@partitions[ (host+path).include?(@substring) ? 0 : 1 ].preroute(proto,host,path)
|
108
113
|
end
|
109
114
|
|
110
115
|
def <<(spec)
|
@@ -137,8 +142,8 @@ module Addressive
|
|
137
142
|
@partitions = partitions
|
138
143
|
end
|
139
144
|
|
140
|
-
def preroute(path
|
141
|
-
@partitions[ path.start_with?(@prefix) ? 0 : 1 ].preroute(
|
145
|
+
def preroute(proto, host, path)
|
146
|
+
@partitions[ path.start_with?(@prefix) ? 0 : 1 ].preroute(proto, host, path)
|
142
147
|
end
|
143
148
|
|
144
149
|
def <<(spec)
|
@@ -225,14 +230,14 @@ module Addressive
|
|
225
230
|
l = env['rack.logger']
|
226
231
|
db = l ? l.method(:debug) : DEBUG_NULL
|
227
232
|
db.call(DEBUG_NAME) do
|
228
|
-
"[ ? ] #{rr.url.inspect}"
|
233
|
+
"[ ? ] url: #{rr.url.inspect}, path: #{rr.fullpath.inspect}"
|
229
234
|
end
|
230
|
-
matches = routes_for(rr.
|
235
|
+
matches = routes_for(rr.fullpath, rr.url)
|
231
236
|
result = nil
|
232
237
|
matches.each do |addressive|
|
233
238
|
env[ADDRESSIVE_ENV_KEY] = addressive
|
234
239
|
begin
|
235
|
-
result = addressive.spec.app.call(env)
|
240
|
+
result = (addressive.spec.callback || addressive.spec.app).call(env)
|
236
241
|
db.call(DEBUG_NAME) do
|
237
242
|
"[#{result[0]}] #{addressive.spec.template.pattern} with #{addressive.variables.inspect} on #{addressive.spec.app} ( route #{addressive.data[:'routes.scanned']} / #{addressive.data[:'routes.total']} ) after #{'%.6f' % addressive.data[:duration]}"
|
238
243
|
end
|
@@ -260,15 +265,15 @@ module Addressive
|
|
260
265
|
include Enumerable
|
261
266
|
|
262
267
|
# @private
|
263
|
-
def initialize(routes,path,
|
264
|
-
@routes,@path,@
|
268
|
+
def initialize(routes,proto,host,path,actions)
|
269
|
+
@routes,@proto,@host,@path,@actions = routes, proto, host,path, actions
|
265
270
|
end
|
266
271
|
|
267
272
|
# @yield {Addressive::Match}
|
268
273
|
def each
|
269
274
|
total = @routes.size
|
270
275
|
scan_time = Time.now
|
271
|
-
@routes.each(@path
|
276
|
+
@routes.each(@proto,@host,@path) do |spec, vars, scanned|
|
272
277
|
node, action = @actions[spec];
|
273
278
|
t = Time.now
|
274
279
|
yield Match.new(node, action, vars, spec, {:'routes.scanned'=>scanned,:'routes.total'=>total,:duration => (t - scan_time)})
|
@@ -279,14 +284,19 @@ module Addressive
|
|
279
284
|
end
|
280
285
|
|
281
286
|
end
|
282
|
-
|
287
|
+
|
288
|
+
URI_SPLITTER = %r{\A([a-z]+:)(//[^/\n]+)(/[^\n]+)\z}
|
289
|
+
|
283
290
|
#
|
284
291
|
# @param path String the path to look for
|
285
292
|
# @param uri String the full uri
|
286
293
|
# @return {RouteEnumerator} an enumerator which yields the requested routes
|
287
|
-
def routes_for(path, uri)
|
294
|
+
def routes_for(path=nil, uri)
|
295
|
+
_, *parts = URI_SPLITTER.match(uri).to_a
|
296
|
+
raise ArgumentError.new("Expected a valid URI but got #{uri.inspect}") if parts.size != 3
|
297
|
+
parts.map!(&:to_s)
|
288
298
|
materialize!
|
289
|
-
return RouteEnumerator.new(@tree.preroute(
|
299
|
+
return RouteEnumerator.new(@tree.preroute(*parts),*parts,@actions)
|
290
300
|
end
|
291
301
|
|
292
302
|
# @private
|
@@ -323,9 +333,9 @@ module Addressive
|
|
323
333
|
return unless @immaterial
|
324
334
|
@mutex.synchronize do
|
325
335
|
return unless @immaterial
|
326
|
-
@routes.sort_by
|
336
|
+
routes = @routes.sort_by{|spec| [ -spec.template.static_characters, spec.variables.size ] }
|
327
337
|
@tree.clear!
|
328
|
-
|
338
|
+
routes.each do |spec|
|
329
339
|
@tree << spec
|
330
340
|
end
|
331
341
|
@tree.done!
|
data/lib/addressive/static.rb
CHANGED
@@ -31,7 +31,7 @@ module Addressive
|
|
31
31
|
# # Create a file, so this won't be a 404:
|
32
32
|
# File.new('/tmp/baz','w').close
|
33
33
|
# router = Addressive::Router.new.add(node)
|
34
|
-
# status,headers,body = router.call('rack.url_scheme'=>'http','PATH_INFO'=>'/baz','HTTP_HOST'=>'example.example')
|
34
|
+
# status,headers,body = router.call('rack.url_scheme'=>'http','PATH_INFO'=>'/baz','HTTP_HOST'=>'example.example','REQUEST_METHOD'=>'GET')
|
35
35
|
# body.class #=> Rack::File
|
36
36
|
# body.path #=> "/tmp/baz"
|
37
37
|
#
|
metadata
CHANGED
@@ -1,82 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: addressive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- HannesG
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: uri_template
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.1
|
21
|
+
version: 0.5.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.5.1
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: simplecov
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
|
-
- -
|
35
|
+
- - '>='
|
31
36
|
- !ruby/object:Gem::Version
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: rspec
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
|
-
- -
|
51
|
+
- - '>='
|
42
52
|
- !ruby/object:Gem::Version
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: yard
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
|
-
- -
|
67
|
+
- - '>='
|
53
68
|
- !ruby/object:Gem::Version
|
54
69
|
version: '0'
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: rack
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
|
-
- -
|
83
|
+
- - '>='
|
64
84
|
- !ruby/object:Gem::Version
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
description: ''
|
70
95
|
email: hannes.georg@googlemail.com
|
71
96
|
executables: []
|
72
97
|
extensions: []
|
73
98
|
extra_rdoc_files: []
|
74
99
|
files:
|
75
|
-
- lib/addressive/
|
76
|
-
- lib/addressive/graphviz.rb
|
77
|
-
- lib/addressive/graph.rb
|
100
|
+
- lib/addressive/rack_ext.rb
|
78
101
|
- lib/addressive/router.rb
|
102
|
+
- lib/addressive/graph.rb
|
103
|
+
- lib/addressive/graph/middleware.rb
|
104
|
+
- lib/addressive/graph/builds_uris.rb
|
105
|
+
- lib/addressive/backports.rb
|
79
106
|
- lib/addressive/static.rb
|
107
|
+
- lib/addressive/request.rb
|
108
|
+
- lib/addressive/builder.rb
|
80
109
|
- lib/addressive.rb
|
81
110
|
- addressive.gemspec
|
82
111
|
homepage: https://github.com/hannesg/addressive
|
@@ -88,18 +117,18 @@ require_paths:
|
|
88
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
89
118
|
none: false
|
90
119
|
requirements:
|
91
|
-
- -
|
120
|
+
- - '>='
|
92
121
|
- !ruby/object:Gem::Version
|
93
122
|
version: '0'
|
94
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
124
|
none: false
|
96
125
|
requirements:
|
97
|
-
- -
|
126
|
+
- - '>='
|
98
127
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
128
|
+
version: '0'
|
100
129
|
requirements: []
|
101
130
|
rubyforge_project:
|
102
|
-
rubygems_version: 1.8.
|
131
|
+
rubygems_version: 1.8.25
|
103
132
|
signing_key:
|
104
133
|
specification_version: 3
|
105
134
|
summary: A system which should help bringing different Rack applications together.
|