sinatra-router 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/lib/sinatra/router.rb +91 -0
- metadata +47 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
module Sinatra
|
2
|
+
class Router
|
3
|
+
def initialize(app=nil, *args, &block)
|
4
|
+
@app = app
|
5
|
+
@apps = []
|
6
|
+
@conditions = []
|
7
|
+
|
8
|
+
instance_eval(&block) if block
|
9
|
+
@routes = build_routing_table
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
if ret = try_route(env["REQUEST_METHOD"], env["PATH_INFO"], env)
|
14
|
+
ret
|
15
|
+
else
|
16
|
+
raise "neither @app nor @run is set" if !@app && !@run
|
17
|
+
|
18
|
+
# if set as middlware, prefer that, otherwise try default run module
|
19
|
+
(@app || @run).call(env)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# specify the default app to run if no other app routes matched
|
24
|
+
def run(app)
|
25
|
+
raise "@run already set" if @run
|
26
|
+
@run = app
|
27
|
+
end
|
28
|
+
|
29
|
+
def route(app, *conditions)
|
30
|
+
# mix in context based conditions with conditions given by parameter
|
31
|
+
@apps << [app, @conditions + conditions]
|
32
|
+
end
|
33
|
+
|
34
|
+
# yield to a builder block in which all defined apps will only respond for
|
35
|
+
# the given version
|
36
|
+
def version(version, &block)
|
37
|
+
@conditions = { version: version }
|
38
|
+
instance_eval(&block) if block
|
39
|
+
@conditions = {}
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def with_conditions(*args, &block)
|
45
|
+
old = @conditions
|
46
|
+
@conditions = @conditions + args
|
47
|
+
instance_eval(&block) if block
|
48
|
+
@conditions = old
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def build_routing_table
|
54
|
+
all_routes = {}
|
55
|
+
@apps.each do |app, conditions|
|
56
|
+
next unless app.respond_to?(:routes)
|
57
|
+
app.routes.each do |verb, routes|
|
58
|
+
all_routes[verb] ||= []
|
59
|
+
all_routes[verb] += routes.map do |pattern, _, _, _|
|
60
|
+
[pattern, conditions, app]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
all_routes
|
65
|
+
end
|
66
|
+
|
67
|
+
def conditions_match?(conditions, env)
|
68
|
+
conditions.each do |condition|
|
69
|
+
return false unless condition.call(env)
|
70
|
+
end
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
def try_route(verb, path, env)
|
75
|
+
# see Sinatra's `route!`
|
76
|
+
if verb_routes = @routes[verb]
|
77
|
+
verb_routes.each do |pattern, conditions, app|
|
78
|
+
if match = pattern.match(path) && conditions_match?(conditions, env)
|
79
|
+
status, headers, response = app.call(env)
|
80
|
+
|
81
|
+
# if we got a pass, keep trying routes
|
82
|
+
return nil if headers["X-Cascade"] == "pass"
|
83
|
+
|
84
|
+
return status, headers, response
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-router
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brandur
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-24 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description:
|
15
|
+
email: brandur@mutelight.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/sinatra/router.rb
|
21
|
+
homepage: https://github.com/brandur/sinatra-router
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 1.8.24
|
43
|
+
signing_key:
|
44
|
+
specification_version: 3
|
45
|
+
summary: A tiny vendorable router that makes it easy to try routes from a number of
|
46
|
+
different modular Sinatra applications.
|
47
|
+
test_files: []
|