http_router 0.2.4 → 0.2.5
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/CHANGELOG +13 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +21 -5
- data/Rakefile +10 -0
- data/Tumbler +4 -0
- data/examples/static/config.ru +26 -0
- data/examples/static/favicon.ico +0 -0
- data/examples/static/images/cat1.jpg +0 -0
- data/examples/static/images/cat2.jpg +0 -0
- data/examples/static/images/cat3.jpg +0 -0
- data/http_router.gemspec +9 -10
- data/lib/ext/rack/rack_urlmap.rb +10 -0
- data/lib/http_router.rb +16 -3
- data/lib/http_router/node.rb +15 -12
- data/lib/http_router/response.rb +3 -3
- data/lib/http_router/root.rb +10 -4
- data/lib/http_router/route.rb +8 -5
- data/lib/http_router/version.rb +4 -0
- data/spec/rack/dispatch_spec.rb +8 -0
- data/spec/rack/urlmap_spec.rb +13 -0
- data/spec/recognize_spec.rb +35 -1
- metadata +98 -16
- data/VERSION +0 -1
data/CHANGELOG
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
== 0.2.5
|
2
|
+
|
3
|
+
* Walk entire tree looking for possible request_methods to return on 405 if a match isn't achieved. (Joshua Hull, 3e8631f)
|
4
|
+
* Upgraded deps + spec running (Joshua Hull, fcefce9)
|
5
|
+
* Simplified route cloning (Joshua Hull, 4b0ff59)
|
6
|
+
* Added partial matching to route cloning (Joshua Hull, d1a57d8)
|
7
|
+
* Merge branch 'master' of github.com:joshbuddy/http_router (Joshua Hull, 7f42a27)
|
8
|
+
* Convert to Tumbler (Joshua Hull, 295e6a2)
|
9
|
+
* Updates cloning (Daniel Neighman, 37178bf)
|
10
|
+
* Add Rack::urlmap replacement (Joshua Hull, 2868044)
|
11
|
+
* Added scheme example (Joshua Hull, f23da20)
|
12
|
+
* Added static example (Joshua Hull, df54ee0)
|
13
|
+
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
---
|
2
2
|
dependencies:
|
3
|
+
url_mount:
|
4
|
+
group:
|
5
|
+
- :default
|
6
|
+
version: ">= 0.2.1"
|
3
7
|
rake:
|
4
8
|
group:
|
5
9
|
- :development
|
6
10
|
version: ">= 0"
|
7
|
-
|
11
|
+
tumbler:
|
8
12
|
group:
|
9
|
-
- :
|
10
|
-
version: ">= 0.
|
13
|
+
- :development
|
14
|
+
version: ">= 0.0.11"
|
11
15
|
rspec:
|
12
16
|
group:
|
13
17
|
- :development
|
@@ -27,17 +31,29 @@ dependencies:
|
|
27
31
|
specs:
|
28
32
|
- rake:
|
29
33
|
version: 0.8.7
|
34
|
+
- blockenspiel:
|
35
|
+
version: 0.3.3
|
36
|
+
- bundler:
|
37
|
+
version: 0.9.26
|
38
|
+
- callsite:
|
39
|
+
version: 0.0.2
|
40
|
+
- json:
|
41
|
+
version: 1.4.3
|
30
42
|
- rack:
|
31
|
-
version: 1.1
|
43
|
+
version: 1.2.1
|
32
44
|
- rbench:
|
33
45
|
version: 0.2.3
|
34
46
|
- rspec:
|
35
47
|
version: 1.3.0
|
36
48
|
- sinatra:
|
37
49
|
version: "1.0"
|
50
|
+
- versionomy:
|
51
|
+
version: 0.4.0
|
52
|
+
- tumbler:
|
53
|
+
version: 0.0.11
|
38
54
|
- url_mount:
|
39
55
|
version: 0.2.1
|
40
|
-
hash:
|
56
|
+
hash: df813dada9b96e269c9f2dc81627e29f1dcec5f4
|
41
57
|
sources:
|
42
58
|
- Rubygems:
|
43
59
|
uri: http://gemcutter.org
|
data/Rakefile
CHANGED
@@ -7,6 +7,10 @@ Spec::Rake::SpecTask.new(:spec) do |t|
|
|
7
7
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
8
8
|
end
|
9
9
|
|
10
|
+
task 'tumbler:preflight' do
|
11
|
+
Rake::Task["spec"].invoke
|
12
|
+
end
|
13
|
+
|
10
14
|
begin
|
11
15
|
require 'code_stats'
|
12
16
|
CodeStats::Tasks.new
|
@@ -20,3 +24,9 @@ Rake::RDocTask.new do |rd|
|
|
20
24
|
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
21
25
|
rd.rdoc_dir = 'rdoc'
|
22
26
|
end
|
27
|
+
|
28
|
+
|
29
|
+
# automatically added Tumbler tasks
|
30
|
+
|
31
|
+
require 'tumbler'
|
32
|
+
Tumbler.use_rake_tasks
|
data/Tumbler
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# static serving example
|
2
|
+
|
3
|
+
require 'http_router'
|
4
|
+
|
5
|
+
base = File.expand_path(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
run HttpRouter.new {
|
8
|
+
get('/favicon.ico').static("#{base}/favicon.ico") # from a single file
|
9
|
+
get('/images').static("#{base}/images") # or from a directory
|
10
|
+
}
|
11
|
+
|
12
|
+
# crapbook-pro:~ joshua$ curl -I http://localhost:3000/favicon.ico
|
13
|
+
# HTTP/1.1 200 OK
|
14
|
+
# Last-Modified: Fri, 11 Jun 2010 21:02:22 GMT
|
15
|
+
# Content-Type: image/vnd.microsoft.icon
|
16
|
+
# Content-Length: 1150
|
17
|
+
# Connection: keep-alive
|
18
|
+
# Server: thin 1.2.7 codename No Hup
|
19
|
+
#
|
20
|
+
# crapbook-pro:~ joshua$ curl -I http://localhost:3000/images/cat1.jpg
|
21
|
+
# HTTP/1.1 200 OK
|
22
|
+
# Last-Modified: Fri, 11 Jun 2010 21:54:16 GMT
|
23
|
+
# Content-Type: image/jpeg
|
24
|
+
# Content-Length: 29817
|
25
|
+
# Connection: keep-alive
|
26
|
+
# Server: thin 1.2.7 codename No Hup
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/http_router.gemspec
CHANGED
@@ -1,28 +1,27 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'tumbler/gemspec'
|
4
|
+
|
3
5
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.version =
|
6
|
+
s.name = Tumbler::Gemspec.name
|
7
|
+
s.version = Tumbler::Gemspec.version
|
6
8
|
|
7
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
10
|
s.authors = ["Joshua Hull"]
|
9
|
-
s.date =
|
11
|
+
s.date = Tumbler::Gemspec.date
|
10
12
|
s.description = %q{A kick-ass HTTP router for use in Rack & Sinatra}
|
11
13
|
s.email = %q{joshbuddy@gmail.com}
|
12
|
-
s.extra_rdoc_files =
|
13
|
-
|
14
|
-
]
|
15
|
-
s.files = `git ls-files`.split("\n")
|
14
|
+
s.extra_rdoc_files = Tumbler::Gemspec.files('README.rdoc')
|
15
|
+
s.files = Tumbler::Gemspec.files
|
16
16
|
s.homepage = %q{http://github.com/joshbuddy/http_router}
|
17
17
|
s.rdoc_options = ["--charset=UTF-8"]
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
s.rubygems_version = %q{1.3.7}
|
20
20
|
s.summary = %q{A kick-ass HTTP router for use in Rack & Sinatra}
|
21
|
-
s.test_files =
|
21
|
+
s.test_files = Tumbler::Gemspec.files(/^spec/)
|
22
22
|
|
23
23
|
# dependencies
|
24
|
-
s
|
25
|
-
s.add_dependency "url_mount", ">=0.2"
|
24
|
+
Tumbler::Gemspec.inject_dependencies(s)
|
26
25
|
|
27
26
|
if s.respond_to? :specification_version then
|
28
27
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Rack::URLMap
|
2
|
+
def initialize(map = {})
|
3
|
+
@router = HttpRouter.new
|
4
|
+
map.each { |path, app| (path =~ /^(https?):\/\/(.*?)(\/.*)/ ? @router.add($3).host($2).scheme($1) : @router.add(path)).partial.to(app) }
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
@router.call(env)
|
9
|
+
end
|
10
|
+
end
|
data/lib/http_router.rb
CHANGED
@@ -12,6 +12,7 @@ require 'http_router/response'
|
|
12
12
|
require 'http_router/path'
|
13
13
|
require 'http_router/optional_compiler'
|
14
14
|
require 'http_router/parts'
|
15
|
+
require 'http_router/version'
|
15
16
|
|
16
17
|
class HttpRouter
|
17
18
|
# Raised when a Route is not able to be generated.
|
@@ -40,6 +41,12 @@ class HttpRouter
|
|
40
41
|
require File.join('ext', 'rack', 'rack_mapper')
|
41
42
|
end
|
42
43
|
|
44
|
+
# Monkey-patches Rack::Builder to use HttpRouter.
|
45
|
+
# See examples/rack_mapper.rb
|
46
|
+
def self.override_rack_urlmap!
|
47
|
+
require File.join('ext', 'rack', 'rack_urlmap')
|
48
|
+
end
|
49
|
+
|
43
50
|
# Creates a new HttpRouter.
|
44
51
|
# Can be called with either <tt>HttpRouter.new(proc{|env| ... }, { .. options .. })</tt> or with the first argument omitted.
|
45
52
|
# If there is a proc first, then it's used as the default app in the case of a non-match.
|
@@ -104,7 +111,7 @@ class HttpRouter
|
|
104
111
|
#
|
105
112
|
# Returns the route object.
|
106
113
|
def add(path, options = nil)
|
107
|
-
add_route
|
114
|
+
add_route route(path.dup).with_options(options)
|
108
115
|
end
|
109
116
|
|
110
117
|
# Adds a route to be recognized. This must be a HttpRouter::Route object. Returns the route just added.
|
@@ -191,6 +198,7 @@ class HttpRouter
|
|
191
198
|
elsif !response.matched?
|
192
199
|
return [response.status, response.headers, []]
|
193
200
|
end
|
201
|
+
process_params(env, response)
|
194
202
|
end
|
195
203
|
env['router.response'] = response
|
196
204
|
@default_app.call(env)
|
@@ -221,9 +229,14 @@ class HttpRouter
|
|
221
229
|
Glob.new(self, *args)
|
222
230
|
end
|
223
231
|
|
232
|
+
# Returns a new glob
|
233
|
+
def route(*args)
|
234
|
+
Route.new(self, *args)
|
235
|
+
end
|
236
|
+
|
224
237
|
# Creates a deep-copy of the router.
|
225
|
-
def clone
|
226
|
-
cloned_router =
|
238
|
+
def clone(klass = self.class)
|
239
|
+
cloned_router = klass.new(@default_app, @options)
|
227
240
|
@routes.each do |route|
|
228
241
|
new_route = route.clone(cloned_router)
|
229
242
|
cloned_router.add_route(new_route).compile
|
data/lib/http_router/node.rb
CHANGED
@@ -137,10 +137,10 @@ class HttpRouter
|
|
137
137
|
current_nodes
|
138
138
|
end
|
139
139
|
|
140
|
-
def find_on_parts(request, parts, params)
|
140
|
+
def find_on_parts(request, parts, params, alternate_request_methods)
|
141
141
|
if parts and !parts.empty?
|
142
142
|
if parts.size == 1 and parts.first == ''
|
143
|
-
potential_match = find_on_parts(request, [], params)
|
143
|
+
potential_match = find_on_parts(request, [], params, alternate_request_methods)
|
144
144
|
if potential_match and (router.ignore_trailing_slash? or potential_match.value && potential_match.value.route.trailing_slash_ignore?)
|
145
145
|
parts.shift
|
146
146
|
return potential_match
|
@@ -153,10 +153,10 @@ class HttpRouter
|
|
153
153
|
if tester.respond_to?(:matches?) and match = tester.matches?(parts)
|
154
154
|
dupped_parts = parts.dup
|
155
155
|
params << tester.consume(match, dupped_parts)
|
156
|
-
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params)
|
156
|
+
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params, alternate_request_methods)
|
157
157
|
elsif tester.respond_to?(:match) and match = tester.match(parts.whole_path) and match.begin(0) == 0
|
158
158
|
dupped_parts = router.split(parts.whole_path[match[0].size, parts.whole_path.size])
|
159
|
-
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params)
|
159
|
+
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params, alternate_request_methods)
|
160
160
|
else
|
161
161
|
nil
|
162
162
|
end
|
@@ -165,14 +165,14 @@ class HttpRouter
|
|
165
165
|
end
|
166
166
|
if match = @lookup && @lookup[parts.first]
|
167
167
|
parts.shift
|
168
|
-
return match.find_on_parts(request, parts, params)
|
168
|
+
return match.find_on_parts(request, parts, params, alternate_request_methods)
|
169
169
|
elsif @catchall
|
170
170
|
params << @catchall.variable.consume(nil, parts)
|
171
|
-
return @catchall.find_on_parts(request, parts, params)
|
171
|
+
return @catchall.find_on_parts(request, parts, params, alternate_request_methods)
|
172
172
|
end
|
173
173
|
end
|
174
174
|
if request_node
|
175
|
-
request_node.find_on_request_methods(request)
|
175
|
+
request_node.find_on_request_methods(request, alternate_request_methods)
|
176
176
|
elsif arbitrary_node
|
177
177
|
arbitrary_node.find_on_arbitrary(request)
|
178
178
|
elsif @value
|
@@ -207,19 +207,19 @@ class HttpRouter
|
|
207
207
|
RequestMethods = [:request_method, :host, :port, :scheme]
|
208
208
|
attr_accessor :request_method
|
209
209
|
|
210
|
-
def find_on_request_methods(request)
|
210
|
+
def find_on_request_methods(request, alternate_request_methods)
|
211
211
|
if @request_method
|
212
212
|
request_value = request.send(request_method)
|
213
213
|
if @linear && !@linear.empty?
|
214
214
|
next_node = @linear.find do |(regexp, node)|
|
215
215
|
regexp === request_value
|
216
216
|
end
|
217
|
-
next_node &&= next_node.find_on_request_methods(request)
|
217
|
+
next_node &&= next_node.find_on_request_methods(request, alternate_request_methods)
|
218
218
|
return next_node if next_node
|
219
219
|
end
|
220
|
-
if @lookup and next_node = (@lookup[request_value] && @lookup[request_value].find_on_request_methods(request))
|
220
|
+
if @lookup and next_node = (@lookup[request_value] && @lookup[request_value].find_on_request_methods(request, alternate_request_methods))
|
221
221
|
return next_node
|
222
|
-
elsif next_node = (@catchall && @catchall.find_on_request_methods(request))
|
222
|
+
elsif next_node = (@catchall && @catchall.find_on_request_methods(request, alternate_request_methods))
|
223
223
|
return next_node
|
224
224
|
end
|
225
225
|
end
|
@@ -229,7 +229,10 @@ class HttpRouter
|
|
229
229
|
elsif @value
|
230
230
|
self
|
231
231
|
else
|
232
|
-
|
232
|
+
if request_method == :request_method
|
233
|
+
alternate_request_methods.concat(@lookup.keys)
|
234
|
+
end
|
235
|
+
nil
|
233
236
|
end
|
234
237
|
end
|
235
238
|
|
data/lib/http_router/response.rb
CHANGED
@@ -31,14 +31,14 @@ class HttpRouter
|
|
31
31
|
def route
|
32
32
|
path.route
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def dest
|
36
36
|
route.dest
|
37
37
|
end
|
38
38
|
alias_method :destination, :dest
|
39
|
-
|
39
|
+
|
40
40
|
def partial_match?
|
41
|
-
remaining_path
|
41
|
+
remaining_path || route.partially_match?
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/http_router/root.rb
CHANGED
@@ -10,16 +10,18 @@ class HttpRouter
|
|
10
10
|
parts = router.split(path)
|
11
11
|
parts << '' if path[path.size - 1] == ?/
|
12
12
|
params = []
|
13
|
+
alternate_request_methods = []
|
13
14
|
process_response(
|
14
|
-
find_on_parts(request, parts, params),
|
15
|
+
find_on_parts(request, parts, params, alternate_request_methods),
|
15
16
|
parts,
|
16
17
|
params,
|
17
|
-
request
|
18
|
+
request,
|
19
|
+
alternate_request_methods
|
18
20
|
)
|
19
21
|
end
|
20
22
|
|
21
23
|
private
|
22
|
-
def process_response(node, parts, params, request)
|
24
|
+
def process_response(node, parts, params, request, alternate_request_methods)
|
23
25
|
if node.respond_to?(:matched?) && !node.matched?
|
24
26
|
node
|
25
27
|
elsif node && node.value
|
@@ -32,7 +34,11 @@ class HttpRouter
|
|
32
34
|
nil
|
33
35
|
end
|
34
36
|
else
|
35
|
-
|
37
|
+
if alternate_request_methods.empty?
|
38
|
+
nil
|
39
|
+
else
|
40
|
+
Response.unmatched(405, {"Allow" => alternate_request_methods.join(", ")})
|
41
|
+
end
|
36
42
|
end
|
37
43
|
end
|
38
44
|
end
|
data/lib/http_router/route.rb
CHANGED
@@ -26,7 +26,7 @@ class HttpRouter
|
|
26
26
|
|
27
27
|
# Returns the options used to create this route.
|
28
28
|
def as_options
|
29
|
-
{:matching => @matches_with, :conditions => @conditions, :default_values => @default_values, :name => @name}
|
29
|
+
{:matching => @matches_with, :conditions => @conditions, :default_values => @default_values, :name => @name, :partial => @partially_match}
|
30
30
|
end
|
31
31
|
|
32
32
|
# Creates a deep uncompiled copy of this route.
|
@@ -41,10 +41,13 @@ class HttpRouter
|
|
41
41
|
# *conditions -- Maps to #conditions method.
|
42
42
|
# *default_value -- Maps to #default_value method.
|
43
43
|
def with_options(options)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
if options
|
45
|
+
name(options[:name]) if options[:name]
|
46
|
+
matching(options[:matching]) if options[:matching]
|
47
|
+
condition(options[:conditions]) if options[:conditions]
|
48
|
+
default(options[:default_values]) if options[:default_values]
|
49
|
+
partial(options[:partial]) if options[:partial]
|
50
|
+
end
|
48
51
|
self
|
49
52
|
end
|
50
53
|
|
data/spec/rack/dispatch_spec.rb
CHANGED
@@ -35,6 +35,14 @@ describe "HttpRouter route dispatching" do
|
|
35
35
|
response = @route_set.call_with_mock_request
|
36
36
|
@app.env["router.params"].should == {}
|
37
37
|
end
|
38
|
+
|
39
|
+
it "should write router.params for default values" do
|
40
|
+
@route_set.add("/foobar", :default_values => {:hi => :there}).compile
|
41
|
+
response = @route_set.call_with_mock_request("/foobar")
|
42
|
+
env = Rack::MockRequest.env_for("/foobar")
|
43
|
+
@route_set.call(env)
|
44
|
+
env['router.params'].should == {:hi => :there}
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
describe "HTTP POST" do
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Rack::Urlmap replacement" do
|
4
|
+
it "should map urls" do
|
5
|
+
HttpRouter.override_rack_urlmap!
|
6
|
+
map = Rack::URLMap.new(
|
7
|
+
"http://www.example.org/test" => proc {|env| [200, {}, ['test']]},
|
8
|
+
"http://www.example.org/:test" => proc {|env| [200, {}, ['variable']]}
|
9
|
+
)
|
10
|
+
map.call(Rack::MockRequest.env_for('http://www.example.org/test')).last.join.should == 'test'
|
11
|
+
map.call(Rack::MockRequest.env_for('http://www.example.org/whhhaaa')).last.join.should == 'variable'
|
12
|
+
end
|
13
|
+
end
|
data/spec/recognize_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe "HttpRouter#recognize" do
|
|
5
5
|
end
|
6
6
|
|
7
7
|
context("with static paths") do
|
8
|
-
['/', '/test', '/test/time', '/one/more/what', '/test.html'].each do |path|
|
8
|
+
['/', '/test', '/test/time', '/one/more/what', '/test.html', '/.html'].each do |path|
|
9
9
|
it "should recognize #{path.inspect}" do
|
10
10
|
route = @router.add(path).to(path)
|
11
11
|
@router.recognize(Rack::MockRequest.env_for(path)).route.should == route
|
@@ -37,6 +37,7 @@ describe "HttpRouter#recognize" do
|
|
37
37
|
response.route.should == route
|
38
38
|
response.remaining_path.should == '/optional'
|
39
39
|
end
|
40
|
+
|
40
41
|
end
|
41
42
|
|
42
43
|
context("with proc acceptance") do
|
@@ -124,6 +125,21 @@ describe "HttpRouter#recognize" do
|
|
124
125
|
@router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).headers['Allow'].should == "POST"
|
125
126
|
end
|
126
127
|
|
128
|
+
it "should recognize with optional parts and correctly return a 405 when the method isn't found" do
|
129
|
+
@router.get("/test(.:format)").to(:get)
|
130
|
+
@router.post("/test(.:format)").to(:post)
|
131
|
+
@router.delete("/test(.:format)").to(:delete)
|
132
|
+
@router.recognize(Rack::MockRequest.env_for('/test', :method => 'POST')).destination.should == :post
|
133
|
+
@router.recognize(Rack::MockRequest.env_for('/test', :method => 'GET')).destination.should == :get
|
134
|
+
@router.recognize(Rack::MockRequest.env_for('/test', :method => 'DELETE')).destination.should == :delete
|
135
|
+
@router.recognize(Rack::MockRequest.env_for('/test', :method => 'PUT')).status.should == 405
|
136
|
+
@router.recognize(Rack::MockRequest.env_for('/test', :method => 'PUT')).headers['Allow'].should == "DELETE, GET, POST"
|
137
|
+
@router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'POST')).destination.should == :post
|
138
|
+
@router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'GET')).destination.should == :get
|
139
|
+
@router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'DELETE')).destination.should == :delete
|
140
|
+
@router.recognize(Rack::MockRequest.env_for('/test.html', :method => 'PUT')).status.should == 405
|
141
|
+
end
|
142
|
+
|
127
143
|
it "should recognize deeply" do
|
128
144
|
@router.post("/test").to(:test_post)
|
129
145
|
@router.post("/test/post").to(:test_post_post)
|
@@ -152,6 +168,14 @@ describe "HttpRouter#recognize" do
|
|
152
168
|
@router.recognize(Rack::MockRequest.env_for('http://host2/test', :method => 'POST')).dest.should == :any_post2
|
153
169
|
end
|
154
170
|
|
171
|
+
it "should match on scheme" do
|
172
|
+
@router.get("/test").scheme('http').to(:http)
|
173
|
+
@router.get("/test").scheme('https').to(:https)
|
174
|
+
@router.recognize(Rack::MockRequest.env_for('http://example.org/test')).dest.should == :http
|
175
|
+
@router.recognize(Rack::MockRequest.env_for('https://example.org/test')).dest.should == :https
|
176
|
+
@router.recognize(Rack::MockRequest.env_for('https://example.org/test', :method => 'POST')).matched?.should be_false
|
177
|
+
end
|
178
|
+
|
155
179
|
end
|
156
180
|
|
157
181
|
context("with dynamic paths") do
|
@@ -181,6 +205,16 @@ describe "HttpRouter#recognize" do
|
|
181
205
|
response.params_as_hash[:format].should be_nil
|
182
206
|
end
|
183
207
|
|
208
|
+
it "should recognize '/(.:format)'" do
|
209
|
+
route = @router.add('/(.:format)').to(:test)
|
210
|
+
response = @router.recognize(Rack::MockRequest.env_for('/.html'))
|
211
|
+
response.route.should == route
|
212
|
+
response.params_as_hash[:format].should == 'html'
|
213
|
+
response = @router.recognize(Rack::MockRequest.env_for('/'))
|
214
|
+
response.route.should == route
|
215
|
+
response.params_as_hash[:format].should be_nil
|
216
|
+
end
|
217
|
+
|
184
218
|
it "should recognize '/:test.:format'" do
|
185
219
|
route = @router.add('/:test.:format').to(:test)
|
186
220
|
response = @router.recognize(Rack::MockRequest.env_for('/hey.html'))
|
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:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 5
|
10
|
+
version: 0.2.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joshua Hull
|
@@ -15,40 +15,112 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-06-18 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
name: rack
|
23
22
|
prerelease: false
|
24
|
-
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
28
|
+
hash: 15
|
30
29
|
segments:
|
31
30
|
- 1
|
32
31
|
- 0
|
33
|
-
|
34
|
-
|
32
|
+
version: "1.0"
|
33
|
+
requirement: *id001
|
35
34
|
type: :runtime
|
36
|
-
|
35
|
+
name: rack
|
37
36
|
- !ruby/object:Gem::Dependency
|
38
|
-
name: url_mount
|
39
37
|
prerelease: false
|
40
|
-
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
42
40
|
requirements:
|
43
41
|
- - ">="
|
44
42
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
43
|
+
hash: 21
|
46
44
|
segments:
|
47
45
|
- 0
|
48
46
|
- 2
|
49
|
-
|
47
|
+
- 1
|
48
|
+
version: 0.2.1
|
49
|
+
requirement: *id002
|
50
50
|
type: :runtime
|
51
|
-
|
51
|
+
name: url_mount
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
prerelease: false
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
requirement: *id003
|
64
|
+
type: :development
|
65
|
+
name: rspec
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
requirement: *id004
|
78
|
+
type: :development
|
79
|
+
name: rake
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirement: *id005
|
92
|
+
type: :development
|
93
|
+
name: sinatra
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 3
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
requirement: *id006
|
106
|
+
type: :development
|
107
|
+
name: rbench
|
108
|
+
- !ruby/object:Gem::Dependency
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: 9
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
- 0
|
119
|
+
- 11
|
120
|
+
version: 0.0.11
|
121
|
+
requirement: *id007
|
122
|
+
type: :development
|
123
|
+
name: tumbler
|
52
124
|
description: A kick-ass HTTP router for use in Rack & Sinatra
|
53
125
|
email: joshbuddy@gmail.com
|
54
126
|
executables: []
|
@@ -59,11 +131,12 @@ extra_rdoc_files:
|
|
59
131
|
- README.rdoc
|
60
132
|
files:
|
61
133
|
- .gitignore
|
134
|
+
- CHANGELOG
|
62
135
|
- Gemfile
|
63
136
|
- Gemfile.lock
|
64
137
|
- README.rdoc
|
65
138
|
- Rakefile
|
66
|
-
-
|
139
|
+
- Tumbler
|
67
140
|
- benchmarks/gen2.rb
|
68
141
|
- benchmarks/generation_bm.rb
|
69
142
|
- benchmarks/rack_mount.rb
|
@@ -74,10 +147,16 @@ files:
|
|
74
147
|
- examples/middleware.ru
|
75
148
|
- examples/rack_mapper.ru
|
76
149
|
- examples/simple.ru
|
150
|
+
- examples/static/config.ru
|
151
|
+
- examples/static/favicon.ico
|
152
|
+
- examples/static/images/cat1.jpg
|
153
|
+
- examples/static/images/cat2.jpg
|
154
|
+
- examples/static/images/cat3.jpg
|
77
155
|
- examples/variable.ru
|
78
156
|
- examples/variable_with_regex.ru
|
79
157
|
- http_router.gemspec
|
80
158
|
- lib/ext/rack/rack_mapper.rb
|
159
|
+
- lib/ext/rack/rack_urlmap.rb
|
81
160
|
- lib/ext/rack/uri_escape.rb
|
82
161
|
- lib/http_router.rb
|
83
162
|
- lib/http_router/glob.rb
|
@@ -90,6 +169,7 @@ files:
|
|
90
169
|
- lib/http_router/root.rb
|
91
170
|
- lib/http_router/route.rb
|
92
171
|
- lib/http_router/variable.rb
|
172
|
+
- lib/http_router/version.rb
|
93
173
|
- spec/generate_spec.rb
|
94
174
|
- spec/misc_spec.rb
|
95
175
|
- spec/mounting_spec.rb
|
@@ -97,6 +177,7 @@ files:
|
|
97
177
|
- spec/rack/generate_spec.rb
|
98
178
|
- spec/rack/middleware_spec.rb
|
99
179
|
- spec/rack/route_spec.rb
|
180
|
+
- spec/rack/urlmap_spec.rb
|
100
181
|
- spec/recognize_spec.rb
|
101
182
|
- spec/sinatra/recognize_spec.rb
|
102
183
|
- spec/spec.opts
|
@@ -143,6 +224,7 @@ test_files:
|
|
143
224
|
- spec/rack/generate_spec.rb
|
144
225
|
- spec/rack/middleware_spec.rb
|
145
226
|
- spec/rack/route_spec.rb
|
227
|
+
- spec/rack/urlmap_spec.rb
|
146
228
|
- spec/recognize_spec.rb
|
147
229
|
- spec/sinatra/recognize_spec.rb
|
148
230
|
- spec/spec.opts
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.2.4
|