http_router 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -8,4 +8,5 @@ group :development do
8
8
  gem 'rake'
9
9
  gem 'sinatra'
10
10
  gem 'rbench'
11
+ gem 'tumbler', ">= 0.0.11"
11
12
  end
@@ -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
- url_mount:
11
+ tumbler:
8
12
  group:
9
- - :default
10
- version: ">= 0.2.1"
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.0
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: 31358295b6fc19c69280f917c4fa3db0d1a7d48d
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,4 @@
1
+ gem_name "http_router"
2
+
3
+ version_file 'lib/http_router/version.rb'
4
+ changelog_file "CHANGELOG"
@@ -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
@@ -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 = %q{http_router}
5
- s.version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
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 = %q{2010-05-30}
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
- "README.rdoc"
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 = `git ls-files spec`.split("\n")
21
+ s.test_files = Tumbler::Gemspec.files(/^spec/)
22
22
 
23
23
  # dependencies
24
- s.add_dependency "rack", ">= 1.0.0"
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
@@ -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 Route.new(self, path.dup).with_options(options)
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 = HttpRouter.new(@default_app, @options)
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
@@ -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
- current_node = request_method == :request_method ? Response.unmatched(405, {"Allow" => @lookup.keys.join(", ")}) : nil
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
 
@@ -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
@@ -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
- nil
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
@@ -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
- name(options[:name]) if options && options[:name]
45
- matching(options[:matching]) if options && options[:matching]
46
- condition(options[:conditions]) if options && options[:conditions]
47
- default(options[:default_values]) if options && options[:default_values]
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
 
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ class HttpRouter #:nodoc
3
+ VERSION = '0.2.5'
4
+ end
@@ -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
@@ -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: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 4
10
- version: 0.2.4
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-05-30 00:00:00 -04:00
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
- requirement: &id001 !ruby/object:Gem::Requirement
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: 23
28
+ hash: 15
30
29
  segments:
31
30
  - 1
32
31
  - 0
33
- - 0
34
- version: 1.0.0
32
+ version: "1.0"
33
+ requirement: *id001
35
34
  type: :runtime
36
- version_requirements: *id001
35
+ name: rack
37
36
  - !ruby/object:Gem::Dependency
38
- name: url_mount
39
37
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
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: 15
43
+ hash: 21
46
44
  segments:
47
45
  - 0
48
46
  - 2
49
- version: "0.2"
47
+ - 1
48
+ version: 0.2.1
49
+ requirement: *id002
50
50
  type: :runtime
51
- version_requirements: *id002
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
- - VERSION
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