http_router 0.6.9 → 0.7.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/{README.rdoc → README.md} +22 -18
- data/Rakefile +1 -1
- data/examples/rack_mapper.ru +5 -4
- data/http_router.gemspec +1 -1
- data/lib/http_router/node/arbitrary.rb +3 -2
- data/lib/http_router/node/destination.rb +21 -0
- data/lib/http_router/node/free_regex.rb +3 -1
- data/lib/http_router/node/lookup.rb +21 -0
- data/lib/http_router/node/regex.rb +3 -2
- data/lib/http_router/node/request.rb +12 -48
- data/lib/http_router/node/variable.rb +5 -3
- data/lib/http_router/node.rb +29 -105
- data/lib/http_router/optional_compiler.rb +1 -1
- data/lib/http_router/route.rb +6 -8
- data/lib/http_router/version.rb +1 -1
- data/test/test_arbitrary.rb +2 -2
- data/test/test_interstitial.rb +6 -6
- data/test/test_recognize.rb +8 -0
- data/test/test_request.rb +5 -5
- data/test/test_variable.rb +3 -3
- metadata +11 -9
data/{README.rdoc → README.md}
RENAMED
@@ -1,6 +1,10 @@
|
|
1
|
-
|
1
|
+
# HTTP Router
|
2
2
|
|
3
|
-
|
3
|
+
## What is it?
|
4
|
+
|
5
|
+
This is an HTTP router for use in either a web framework, or on it's own using Rack. It takes a set of routes and attempts to find the best match for it. Take a look at the examples directory for how you'd use it in the Rack context.
|
6
|
+
|
7
|
+
## Features
|
4
8
|
|
5
9
|
* Supports variables, and globbing, both named and unnamed.
|
6
10
|
* Regex support for variables.
|
@@ -10,30 +14,30 @@
|
|
10
14
|
* Very fast and small code base (~1,000 loc).
|
11
15
|
* Sinatra via https://github.com/joshbuddy/http_router_sinatra
|
12
16
|
|
13
|
-
|
17
|
+
## Usage
|
14
18
|
|
15
19
|
Please see the examples directory for a bunch of awesome rackup file examples, with tonnes of commentary. As well, the rdocs should provide a lot of useful specifics and exact usage.
|
16
20
|
|
17
|
-
|
21
|
+
### `HttpRouter.new`
|
18
22
|
|
19
23
|
Takes the following options:
|
20
24
|
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*
|
24
|
-
*
|
25
|
+
* `:default_app` - The default #call made on non-matches. Defaults to a 404 generator.
|
26
|
+
* `:ignore_trailing_slash` - Ignores the trailing slash when matching. Defaults to true.
|
27
|
+
* `:redirect_trailing_slash` - Redirect on trailing slash matches to non-trailing slash paths. Defaults to false.
|
28
|
+
* `:middleware` - Perform matching without deferring to matched route. Defaults to false.
|
25
29
|
|
26
|
-
|
30
|
+
### `#add(name, options)`
|
27
31
|
|
28
32
|
Maps a route. The format for variables in paths is:
|
29
33
|
:variable
|
30
34
|
*glob
|
31
35
|
|
32
|
-
Everything else is treated literally. Optional parts are surrounded by brackets. Partially matching paths have a trailing
|
36
|
+
Everything else is treated literally. Optional parts are surrounded by brackets. Partially matching paths have a trailing `*`. Optional trailing slash matching is done with `/?`.
|
33
37
|
|
34
|
-
As well, you can escape the following characters with a backslash:
|
38
|
+
As well, you can escape the following characters with a backslash: `( ) : *`
|
35
39
|
|
36
|
-
Once you have a route object, use
|
40
|
+
Once you have a route object, use `HttpRouter::Route#to` to add a destination and `HttpRouter::Route#name` to name it.
|
37
41
|
|
38
42
|
e.g.
|
39
43
|
|
@@ -42,22 +46,22 @@ e.g.
|
|
42
46
|
r.add('/test').redirect("http://www.google.com/")
|
43
47
|
r.add('/static').static('/my_file_system')
|
44
48
|
|
45
|
-
As well, you can support regex matching and request conditions. To add a regex match, use
|
46
|
-
To match on a request condition you can use
|
49
|
+
As well, you can support regex matching and request conditions. To add a regex match, use `matching(:id => /\d+/)`.
|
50
|
+
To match on a request condition you can use `condition(:request_method => %w(POST HEAD))` or more succinctly `request_method('POST', 'HEAD')`.
|
47
51
|
|
48
52
|
There are convenience methods HttpRouter#get, HttpRouter#post, etc for each request method.
|
49
53
|
|
50
|
-
Routes will not be recognized unless
|
54
|
+
Routes will not be recognized unless `#to` has been called on it.
|
51
55
|
|
52
|
-
|
56
|
+
### `#url(name or route, *args)`
|
53
57
|
|
54
58
|
Generates a route. The args can either be a hash, a list, or a mix of both.
|
55
59
|
|
56
|
-
|
60
|
+
### `#call(env or Rack::Request)`
|
57
61
|
|
58
62
|
Recognizes and dispatches the request.
|
59
63
|
|
60
|
-
|
64
|
+
### `#recognize(env or Rack::Request)`
|
61
65
|
|
62
66
|
Only performs recognition.
|
63
67
|
|
data/Rakefile
CHANGED
@@ -39,7 +39,7 @@ namespace :test do
|
|
39
39
|
case c
|
40
40
|
when /^\$/
|
41
41
|
out = `#{c[1, c.size]} 2>/dev/null`.split(/\n/)
|
42
|
-
raise "#{c} produced #{
|
42
|
+
raise "#{c} produced #{`#{c[1, c.size]} 2>&1`}" unless $?.success?
|
43
43
|
when /^=> ?(.*)/
|
44
44
|
c = $1
|
45
45
|
raise "out was nil" if out.nil?
|
data/examples/rack_mapper.ru
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'http_router'
|
2
2
|
HttpRouter::Rack.override_rack_builder!
|
3
3
|
|
4
|
-
map('/get/:id') { |env|
|
5
|
-
[200, {'Content-type' => 'text/plain'}, ["My id is #{env['router.params'][:id]}\n"]]
|
4
|
+
map('/get/:id', :matching => {:id => /\d+/}) { |env|
|
5
|
+
[200, {'Content-type' => 'text/plain'}, ["My id is #{env['router.params'][:id]}, which is a number\n"]]
|
6
6
|
}
|
7
7
|
|
8
8
|
# you have post, get, head, put and delete.
|
@@ -10,10 +10,11 @@ post('/get/:id') { |env|
|
|
10
10
|
[200, {'Content-type' => 'text/plain'}, ["My id is #{env['router.params'][:id]} and you posted!\n"]]
|
11
11
|
}
|
12
12
|
|
13
|
-
map('/get/:id'
|
14
|
-
[200, {'Content-type' => 'text/plain'}, ["My id is #{env['router.params'][:id]}
|
13
|
+
map('/get/:id') { |env|
|
14
|
+
[200, {'Content-type' => 'text/plain'}, ["My id is #{env['router.params'][:id]}\n"]]
|
15
15
|
}
|
16
16
|
|
17
|
+
|
17
18
|
# $ curl http://127.0.0.1:3000/get/foo
|
18
19
|
# => My id is foo
|
19
20
|
# $ curl -X POST http://127.0.0.1:3000/get/foo
|
data/http_router.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.summary = "A kick-ass HTTP router for use in Rack"
|
11
11
|
s.description = "This library allows you to recognize and build URLs in a Rack application."
|
12
12
|
s.email = %q{joshbuddy@gmail.com}
|
13
|
-
s.extra_rdoc_files = ['README.
|
13
|
+
s.extra_rdoc_files = ['README.md']
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.homepage = %q{http://github.com/joshbuddy/http_router}
|
16
16
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -2,13 +2,14 @@ class HttpRouter
|
|
2
2
|
class Node
|
3
3
|
class Arbitrary < Node
|
4
4
|
def initialize(router, allow_partial, blk, param_names)
|
5
|
-
@
|
5
|
+
@allow_partial, @blk, @param_names = allow_partial, blk, param_names
|
6
|
+
super(router)
|
6
7
|
end
|
7
8
|
|
8
9
|
def [](request)
|
9
10
|
if request.path.empty? or (request.path.size == 1 and request.path[0] == '') or @allow_partial
|
10
11
|
request = request.clone
|
11
|
-
request.continue = proc { |state|
|
12
|
+
request.continue = proc { |state| super(request) if state }
|
12
13
|
params = @param_names.nil? ? {} : Hash[@param_names.zip(request.params)]
|
13
14
|
@blk.call(request, params)
|
14
15
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class HttpRouter
|
2
|
+
class Node
|
3
|
+
class Destination < Node
|
4
|
+
def initialize(router, blk, allow_partial)
|
5
|
+
@blk, @allow_partial = blk, allow_partial
|
6
|
+
super(router)
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](request)
|
10
|
+
if request.path.empty? or (request.path.size == 1 and request.path[0] == '') or @allow_partial
|
11
|
+
catch(:pass) do
|
12
|
+
request = request.clone
|
13
|
+
request.continue = proc { |state| destination(request) if state }
|
14
|
+
params = @param_names.nil? ? {} : Hash[@param_names.zip(request.params)]
|
15
|
+
@blk.call(request, params)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -3,7 +3,8 @@ class HttpRouter
|
|
3
3
|
class FreeRegex < Node
|
4
4
|
attr_reader :matcher
|
5
5
|
def initialize(router, matcher)
|
6
|
-
@
|
6
|
+
@matcher = matcher
|
7
|
+
super(router)
|
7
8
|
end
|
8
9
|
|
9
10
|
def [](request)
|
@@ -11,6 +12,7 @@ class HttpRouter
|
|
11
12
|
if match = @matcher.match(whole_path) and match[0].size == whole_path.size
|
12
13
|
request = request.clone
|
13
14
|
request.extra_env['router.regex_match'] = match
|
15
|
+
request.path = ['']
|
14
16
|
match.names.size.times{|i| request.params << match[i + 1]} if match.respond_to?(:names) && match.names
|
15
17
|
super
|
16
18
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class HttpRouter
|
2
|
+
class Node
|
3
|
+
class Lookup < Node
|
4
|
+
def initialize(router)
|
5
|
+
@map = {}
|
6
|
+
super(router)
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](request)
|
10
|
+
if @map[request.path.first]
|
11
|
+
request = request.clone
|
12
|
+
@map[request.path.shift].each{|m| m[request]}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(part)
|
17
|
+
Node.new(@router, @map[part] ||= [])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -4,8 +4,9 @@ class HttpRouter
|
|
4
4
|
alias_method :node_lookup, :[]
|
5
5
|
attr_reader :matcher, :splitting_indicies
|
6
6
|
|
7
|
-
def initialize(router, matcher, capturing_indicies,
|
8
|
-
@
|
7
|
+
def initialize(router, matcher, capturing_indicies, splitting_indicies = nil)
|
8
|
+
@matcher, @capturing_indicies, @splitting_indicies = matcher, capturing_indicies, splitting_indicies
|
9
|
+
super(router)
|
9
10
|
end
|
10
11
|
|
11
12
|
def [](request)
|
@@ -3,57 +3,21 @@ class HttpRouter
|
|
3
3
|
class Request < Node
|
4
4
|
attr_reader :request_method
|
5
5
|
|
6
|
-
def initialize(router)
|
7
|
-
@
|
8
|
-
|
9
|
-
|
10
|
-
def transform_to(meth)
|
11
|
-
new_node = Request.new(router)
|
12
|
-
new_node.request_method = @request_method
|
13
|
-
new_node.instance_var_set(:@linear, @linear.dup)
|
14
|
-
new_node.instance_var_set(:@catchall, @catchall)
|
15
|
-
new_node.instance_var_set(:@lookup, @lookup.dup)
|
16
|
-
@linear.clear
|
17
|
-
@lookup.clear
|
18
|
-
@catchall = new_node
|
19
|
-
@request_method = meth
|
20
|
-
new_node
|
21
|
-
end
|
22
|
-
|
23
|
-
def request_method=(meth)
|
24
|
-
@request_method = meth == :method ? :request_method : meth
|
25
|
-
if @destination
|
26
|
-
next_node = add_catchall
|
27
|
-
next_node.instance_variable_set(:@destination, @destination)
|
28
|
-
@destination = nil
|
29
|
-
end
|
30
|
-
@request_method
|
31
|
-
end
|
32
|
-
|
33
|
-
def add_lookup(val)
|
34
|
-
@router.known_methods << val if @request_method == :request_method
|
35
|
-
@lookup[val] ||= Request.new(@router)
|
36
|
-
end
|
37
|
-
|
38
|
-
def add_catchall
|
39
|
-
@catchall ||= Request.new(@router)
|
40
|
-
end
|
41
|
-
|
42
|
-
def add_linear(matcher)
|
43
|
-
next_node = Request.new(@router)
|
44
|
-
@linear << [matcher, next_node]
|
45
|
-
next_node
|
6
|
+
def initialize(router, opts)
|
7
|
+
@opts = opts
|
8
|
+
Array(@opts[:request_method]).each { |m| router.known_methods << m } if @opts.key?(:request_method)
|
9
|
+
super(router)
|
46
10
|
end
|
47
11
|
|
48
12
|
def [](request)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
13
|
+
@opts.each{|k,v|
|
14
|
+
test = request.rack_request.send(k)
|
15
|
+
return unless case v
|
16
|
+
when Array then v.any?{|vv| vv === test}
|
17
|
+
else v === test
|
18
|
+
end
|
19
|
+
}
|
20
|
+
super(request)
|
57
21
|
end
|
58
22
|
end
|
59
23
|
end
|
@@ -2,9 +2,11 @@ class HttpRouter
|
|
2
2
|
class Node
|
3
3
|
class Variable < Node
|
4
4
|
def [](request)
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
unless request.path.empty?
|
6
|
+
request = request.clone
|
7
|
+
request.params << unescape(request.path.shift)
|
8
|
+
super(request)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|
data/lib/http_router/node.rb
CHANGED
@@ -8,145 +8,69 @@ class HttpRouter
|
|
8
8
|
autoload :FreeRegex, 'http_router/node/free_regex'
|
9
9
|
autoload :Arbitrary, 'http_router/node/arbitrary'
|
10
10
|
autoload :Request, 'http_router/node/request'
|
11
|
+
autoload :Lookup, 'http_router/node/lookup'
|
12
|
+
autoload :Destination, 'http_router/node/destination'
|
11
13
|
|
12
14
|
attr_reader :priority, :router
|
13
15
|
|
14
|
-
def initialize(router)
|
15
|
-
@router = router
|
16
|
+
def initialize(router, matchers = [])
|
17
|
+
@router, @matchers = router, matchers
|
16
18
|
end
|
17
19
|
|
18
20
|
def [](request)
|
19
|
-
|
20
|
-
|
21
|
-
linear(request)
|
22
|
-
lookup(request)
|
23
|
-
variable(request)
|
24
|
-
glob(request)
|
25
|
-
end
|
26
|
-
destination(request)
|
27
|
-
end
|
28
|
-
|
29
|
-
def linear(request)
|
30
|
-
@linear && @linear.each{|n| n[request]}
|
31
|
-
end
|
32
|
-
|
33
|
-
def lookup(request)
|
34
|
-
if @lookup && @lookup[request.path.first]
|
35
|
-
request = request.clone
|
36
|
-
@lookup[request.path.shift][request]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def variable(request)
|
41
|
-
@variable && @variable[request]
|
42
|
-
end
|
43
|
-
|
44
|
-
def glob(request)
|
45
|
-
@glob && @glob[request]
|
46
|
-
end
|
47
|
-
|
48
|
-
def request(request)
|
49
|
-
@request && @request[request]
|
50
|
-
end
|
51
|
-
|
52
|
-
def arbitrary(request)
|
53
|
-
@arbitrary && @arbitrary.each{|n| n[request]}
|
54
|
-
end
|
55
|
-
|
56
|
-
def unescape(val)
|
57
|
-
val.to_s.gsub(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') }
|
58
|
-
end
|
59
|
-
|
60
|
-
def destination(request_obj, match_partially = true)
|
61
|
-
request(request_obj)
|
62
|
-
arbitrary(request_obj)
|
63
|
-
@destination.call(request_obj, match_partially) if @destination
|
21
|
+
@matchers.each {|m| m[request] }
|
22
|
+
nil
|
64
23
|
end
|
65
24
|
|
66
25
|
def add_variable
|
67
|
-
|
26
|
+
add(Variable.new(@router))
|
68
27
|
end
|
69
28
|
|
70
29
|
def add_glob
|
71
|
-
|
30
|
+
add(Glob.new(@router))
|
72
31
|
end
|
73
32
|
|
74
33
|
def add_request(opts)
|
75
|
-
|
76
|
-
next_requests = [@request]
|
77
|
-
@router.request_methods.each_with_index do |method, method_index|
|
78
|
-
next_requests.map! do |next_request|
|
79
|
-
if opts[method].nil? && next_request.request_method.nil?
|
80
|
-
next_request
|
81
|
-
else
|
82
|
-
next_request_index = next_request.request_method && @router.request_methods.index(next_request.request_method)
|
83
|
-
rank = next_request_index ? method_index <=> next_request_index : 0
|
84
|
-
case rank
|
85
|
-
when 0
|
86
|
-
next_request.request_method = method
|
87
|
-
(opts[method].nil? ? [nil] : Array(opts[method])).map do |request_matcher|
|
88
|
-
case request_matcher
|
89
|
-
when nil then next_request.add_catchall
|
90
|
-
when String then next_request.add_lookup(request_matcher)
|
91
|
-
when Regexp then next_request.add_linear(request_matcher)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
when -1 then next_request
|
95
|
-
when 1 then next_request.transform_to(method)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
next_requests.flatten!
|
100
|
-
end
|
101
|
-
next_requests
|
34
|
+
add(Request.new(@router, opts))
|
102
35
|
end
|
103
36
|
|
104
37
|
def add_arbitrary(blk, allow_partial, param_names)
|
105
|
-
@
|
106
|
-
@arbitrary << Arbitrary.new(@router, allow_partial, blk, param_names)
|
107
|
-
@arbitrary.last
|
38
|
+
add(Arbitrary.new(@router, allow_partial, blk, param_names))
|
108
39
|
end
|
109
40
|
|
110
|
-
def add_match(regexp, matching_indicies = [0],
|
111
|
-
|
41
|
+
def add_match(regexp, matching_indicies = [0], splitting_indicies = nil)
|
42
|
+
add(Regex.new(@router, regexp, matching_indicies, splitting_indicies))
|
112
43
|
end
|
113
44
|
|
114
|
-
def add_spanning_match(regexp, matching_indicies = [0],
|
115
|
-
|
45
|
+
def add_spanning_match(regexp, matching_indicies = [0], splitting_indicies = nil)
|
46
|
+
add(SpanningRegex.new(@router, regexp, matching_indicies, splitting_indicies))
|
116
47
|
end
|
117
48
|
|
118
49
|
def add_free_match(regexp)
|
119
|
-
@
|
120
|
-
@linear << FreeRegex.new(@router, regexp)
|
121
|
-
@linear.last
|
50
|
+
add(FreeRegex.new(@router, regexp))
|
122
51
|
end
|
123
52
|
|
124
|
-
def add_destination(
|
125
|
-
@
|
53
|
+
def add_destination(blk, partial)
|
54
|
+
add(Destination.new(@router, blk, partial))
|
126
55
|
end
|
127
56
|
|
128
57
|
def add_lookup(part)
|
129
|
-
@
|
130
|
-
@
|
58
|
+
add(Lookup.new(@router)) unless @matchers.last.is_a?(Lookup)
|
59
|
+
@matchers.last.add(part)
|
131
60
|
end
|
132
61
|
|
133
|
-
|
134
|
-
|
62
|
+
private
|
63
|
+
def add(matcher)
|
64
|
+
@matchers << matcher
|
65
|
+
@matchers.last
|
135
66
|
end
|
136
67
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
@linear[i, 0] = match
|
144
|
-
return @linear[i]
|
145
|
-
end
|
146
|
-
}
|
147
|
-
end
|
148
|
-
@linear << match
|
149
|
-
@linear.last
|
68
|
+
def unescape(val)
|
69
|
+
val.to_s.gsub(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') }
|
70
|
+
end
|
71
|
+
|
72
|
+
def join_whole_path(request)
|
73
|
+
request.path * '/'
|
150
74
|
end
|
151
75
|
end
|
152
76
|
end
|
data/lib/http_router/route.rb
CHANGED
@@ -167,7 +167,7 @@ class HttpRouter
|
|
167
167
|
path.param_names.size == var_count
|
168
168
|
}
|
169
169
|
else
|
170
|
-
@paths.
|
170
|
+
@paths.each do |path|
|
171
171
|
if params && !params.empty?
|
172
172
|
return path if (path.param_names & params.keys).size == path.param_names.size
|
173
173
|
elsif path.param_names.empty?
|
@@ -216,7 +216,6 @@ class HttpRouter
|
|
216
216
|
capturing_indicies = []
|
217
217
|
splitting_indicies = []
|
218
218
|
captures = 0
|
219
|
-
priority = 0
|
220
219
|
spans = false
|
221
220
|
regex = parts.inject('') do |reg, part|
|
222
221
|
reg << case part[0]
|
@@ -238,12 +237,11 @@ class HttpRouter
|
|
238
237
|
matches_with[name] = @opts[name]
|
239
238
|
"(#{(@opts[name] || '.*?')})"
|
240
239
|
else
|
241
|
-
priority += part.size
|
242
240
|
Regexp.quote(URI.encode(part))
|
243
241
|
end
|
244
242
|
end
|
245
|
-
node = spans ? node.add_spanning_match(Regexp.new("#{regex}$"), capturing_indicies,
|
246
|
-
node.add_match(Regexp.new("#{regex}$"), capturing_indicies,
|
243
|
+
node = spans ? node.add_spanning_match(Regexp.new("#{regex}$"), capturing_indicies, splitting_indicies) :
|
244
|
+
node.add_match(Regexp.new("#{regex}$"), capturing_indicies, splitting_indicies)
|
247
245
|
end
|
248
246
|
end
|
249
247
|
add_non_path_to_tree(node, path, param_names)
|
@@ -274,9 +272,9 @@ class HttpRouter
|
|
274
272
|
end
|
275
273
|
end
|
276
274
|
}
|
277
|
-
|
278
|
-
@arbitrary.each{|a|
|
279
|
-
|
275
|
+
node = node.add_request(@conditions) if @conditions && !@conditions.empty?
|
276
|
+
@arbitrary.each{|a| node = node.add_arbitrary(a, match_partially?, names)} if @arbitrary
|
277
|
+
node.add_destination(destination, @match_partially)
|
280
278
|
if dest.respond_to?(:url_mount=)
|
281
279
|
urlmount = UrlMount.new(@original_path, @default_values)
|
282
280
|
urlmount.url_mount = router.url_mount if router.url_mount
|
data/lib/http_router/version.rb
CHANGED
data/test/test_arbitrary.rb
CHANGED
@@ -9,11 +9,11 @@ class TestArbitrary < MiniTest::Unit::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_less_specific_node
|
12
|
-
|
13
|
-
add("/test")
|
12
|
+
hello, love80, love8080, general = router {
|
14
13
|
add("/test").arbitrary(Proc.new{|req, params| req.rack.host == 'hellodooly' })
|
15
14
|
add("/test").arbitrary(Proc.new{|req, params| req.rack.host == 'lovelove' }).arbitrary{|req, params| req.rack.port == 80}
|
16
15
|
add("/test").arbitrary(Proc.new{|req, params| req.rack.host == 'lovelove' }).arbitrary{|req, params| req.rack.port == 8080}
|
16
|
+
add("/test")
|
17
17
|
}
|
18
18
|
assert_route general, 'http://lovelove:8081/test'
|
19
19
|
assert_route hello, 'http://hellodooly:8081/test'
|
data/test/test_interstitial.rb
CHANGED
@@ -20,13 +20,13 @@ class TestInterstitial < MiniTest::Unit::TestCase
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_multi
|
23
|
-
|
24
|
-
add('/:var1')
|
25
|
-
add('/:var1-:var2')
|
26
|
-
add('/:var1-:var2-:var3')
|
27
|
-
add('/:var1-:var2-:var3-:var4')
|
28
|
-
add('/:var1-:var2-:var3-:var4-:var5')
|
23
|
+
r6, r5, r4, r3, r2, r1 = router {
|
29
24
|
add('/:var1-:var2-:var3-:var4-:var5-:var6')
|
25
|
+
add('/:var1-:var2-:var3-:var4-:var5')
|
26
|
+
add('/:var1-:var2-:var3-:var4')
|
27
|
+
add('/:var1-:var2-:var3')
|
28
|
+
add('/:var1-:var2')
|
29
|
+
add('/:var1')
|
30
30
|
}
|
31
31
|
assert_route r1, '/one', {:var1 => 'one'}
|
32
32
|
assert_route r2, '/one-value', {:var1 => 'one', :var2 => 'value'}
|
data/test/test_recognize.rb
CHANGED
@@ -12,6 +12,14 @@ class TestRecognition < MiniTest::Unit::TestCase
|
|
12
12
|
assert_route router.add('/.html'), '/.html'
|
13
13
|
end
|
14
14
|
|
15
|
+
def test_passing
|
16
|
+
passed, working = router {
|
17
|
+
add('/').to { |env| throw :pass; [200, {}, ['pass']] }
|
18
|
+
add('/').to { |env| [200, {}, ['working']] }
|
19
|
+
}
|
20
|
+
assert_body 'working', router.call(Rack::MockRequest.env_for('/'))
|
21
|
+
end
|
22
|
+
|
15
23
|
def test_optional
|
16
24
|
route = router {
|
17
25
|
add 'one(/two(/three(/four)(/five)))'
|
data/test/test_request.rb
CHANGED
@@ -47,20 +47,20 @@ class TestRequest < MiniTest::Unit::TestCase
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def test_move_node
|
50
|
-
|
51
|
-
add("/test").default_destination
|
50
|
+
post, general = router {
|
52
51
|
post("/test").default_destination
|
52
|
+
add("/test").default_destination
|
53
53
|
}
|
54
54
|
assert_route post, Rack::MockRequest.env_for('/test', :method => 'POST')
|
55
55
|
assert_route general, Rack::MockRequest.env_for('/test', :method => 'PUT')
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_complex_routing
|
59
|
-
|
59
|
+
host2_post, host2_get, host2, post = router {
|
60
|
+
add("/test").post.host('host2')
|
61
|
+
add("/test").host('host2').get
|
60
62
|
add("/test").host('host2')
|
61
63
|
add("/test").post
|
62
|
-
add("/test").host('host2').get
|
63
|
-
add("/test").post.host('host2')
|
64
64
|
}
|
65
65
|
assert_route host2, Rack::MockRequest.env_for('http://host2/test', :method => 'PUT')
|
66
66
|
assert_route post, Rack::MockRequest.env_for('http://host1/test', :method => 'POST')
|
data/test/test_variable.rb
CHANGED
@@ -5,7 +5,7 @@ class TestVariable < MiniTest::Unit::TestCase
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def test_variable_vs_static
|
8
|
-
|
8
|
+
static, dynamic = router { add 'one'; add ':one' }
|
9
9
|
assert_route dynamic, '/two', {:one => 'two'}
|
10
10
|
assert_route static, '/one'
|
11
11
|
end
|
@@ -107,10 +107,10 @@ class TestVariable < MiniTest::Unit::TestCase
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def test_regex_and_greedy
|
110
|
-
with_regex,
|
110
|
+
with_regex, with_post, without_regex = router {
|
111
111
|
add("/:common_variable/:matched").matching(:matched => /\d+/)
|
112
|
-
add("/:common_variable/:unmatched")
|
113
112
|
post("/:common_variable/:unmatched")
|
113
|
+
add("/:common_variable/:unmatched")
|
114
114
|
}
|
115
115
|
assert_route with_regex, '/common/123', {:common_variable => 'common', :matched => '123'}
|
116
116
|
assert_route without_regex, '/common/other', {:common_variable => 'common', :unmatched => 'other'}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 3
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 7
|
9
|
+
- 0
|
10
|
+
version: 0.7.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joshua Hull
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-18 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -161,13 +161,13 @@ executables: []
|
|
161
161
|
extensions: []
|
162
162
|
|
163
163
|
extra_rdoc_files:
|
164
|
-
- README.
|
164
|
+
- README.md
|
165
165
|
files:
|
166
166
|
- .gitignore
|
167
167
|
- .rspec
|
168
168
|
- CHANGELOG
|
169
169
|
- Gemfile
|
170
|
-
- README.
|
170
|
+
- README.md
|
171
171
|
- Rakefile
|
172
172
|
- benchmarks/gen2.rb
|
173
173
|
- benchmarks/generation_bm.rb
|
@@ -189,9 +189,11 @@ files:
|
|
189
189
|
- lib/http_router.rb
|
190
190
|
- lib/http_router/node.rb
|
191
191
|
- lib/http_router/node/arbitrary.rb
|
192
|
+
- lib/http_router/node/destination.rb
|
192
193
|
- lib/http_router/node/free_regex.rb
|
193
194
|
- lib/http_router/node/glob.rb
|
194
195
|
- lib/http_router/node/glob_regex.rb
|
196
|
+
- lib/http_router/node/lookup.rb
|
195
197
|
- lib/http_router/node/regex.rb
|
196
198
|
- lib/http_router/node/request.rb
|
197
199
|
- lib/http_router/node/spanning_regex.rb
|
@@ -250,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
252
|
requirements: []
|
251
253
|
|
252
254
|
rubyforge_project: http_router
|
253
|
-
rubygems_version: 1.
|
255
|
+
rubygems_version: 1.6.2
|
254
256
|
signing_key:
|
255
257
|
specification_version: 3
|
256
258
|
summary: A kick-ass HTTP router for use in Rack
|