http_router 0.8.2 → 0.8.3

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/benchmarks/rec2.rb CHANGED
@@ -36,6 +36,7 @@ TIMES = 50_000
36
36
  #simple_and_dynamic_env1 = Rack::MockRequest.env_for('/rails/controller/action/id')
37
37
  #simple_and_dynamic_env2 = Rack::MockRequest.env_for('/greedy/controller/action/id')
38
38
  #simple_and_dynamic_env3 = Rack::MockRequest.env_for('/greedy/hey.hello.html')
39
+ u.call(Rack::MockRequest.env_for('/simple')).first == 200 or raise
39
40
  5.times {
40
41
  RBench.run(TIMES) do
41
42
 
data/lib/http_router.rb CHANGED
@@ -70,14 +70,6 @@ class HttpRouter
70
70
  route
71
71
  end
72
72
 
73
- def pass_on_response(response)
74
- response[1]['X-Cascade'] == 'pass'
75
- end
76
-
77
- def set_pass_on_response(&blk)
78
- extend(Module.new { define_method(:pass_on_response, &blk) })
79
- end
80
-
81
73
  # Adds a path that only responds to the request method +GET+.
82
74
  #
83
75
  # Returns the route object.
@@ -108,21 +100,21 @@ class HttpRouter
108
100
  # Returns the route object.
109
101
  def options(path, opts = {}, &app); add_with_request_method(path, :options, opts, &app); end
110
102
 
111
- def recognize(env, &blk)
112
- call(env, false, &blk)
103
+ def recognize(env)
104
+ call(env, false)
113
105
  end
114
106
 
115
107
  # Rack compatible #call. If matching route is found, and +dest+ value responds to #call, processing will pass to the matched route. Otherwise,
116
108
  # the default application will be called. The router will be available in the env under the key <tt>router</tt>. And parameters matched will
117
109
  # be available under the key <tt>router.params</tt>.
118
- def call(env, perform_call = true, &blk)
110
+ def call(env, perform_call = true)
119
111
  rack_request = ::Rack::Request.new(env)
120
112
  if redirect_trailing_slash? && (rack_request.head? || rack_request.get?) && rack_request.path_info[-1] == ?/
121
113
  response = ::Rack::Response.new
122
114
  response.redirect(request.path_info[0, request.path_info.size - 1], 302)
123
115
  response.finish
124
116
  else
125
- request = Request.new(rack_request.path_info, rack_request, perform_call, &blk)
117
+ request = Request.new(rack_request.path_info, rack_request, perform_call)
126
118
  response = catch(:success) { @root[request] }
127
119
  if response
128
120
  response
@@ -169,6 +161,14 @@ class HttpRouter
169
161
  end
170
162
  end
171
163
 
164
+ def process_destination(destination, env)
165
+ destination.call(env)
166
+ end
167
+
168
+ def pass_on_response(response)
169
+ response[1]['X-Cascade'] == 'pass'
170
+ end
171
+
172
172
  # Ignore trailing slash feature enabled? See #initialize for details.
173
173
  def ignore_trailing_slash?
174
174
  @ignore_trailing_slash
@@ -72,6 +72,11 @@ class HttpRouter
72
72
  end
73
73
  end
74
74
 
75
+ def inject_root_ivar(name, val)
76
+ root.instance_variable_set(name, val)
77
+ end
78
+
79
+
75
80
  def add(matcher)
76
81
  @matchers << matcher unless matcher.usable?(@matchers.last)
77
82
  @matchers.last
@@ -13,11 +13,28 @@ class HttpRouter
13
13
  end
14
14
 
15
15
  def to_code
16
- b, method_name = @blk, :"blk_#{router.next_counter}"
17
- inject_root_methods { define_method(method_name) { b } }
16
+ path = blk
17
+ path_ivar = :"@path_#{router.next_counter}"
18
+ inject_root_ivar(path_ivar, blk)
18
19
  "#{"if request.path_finished?" unless @allow_partial}
19
- request.passed_with = catch(:pass) do
20
- #{method_name}[request, #{@param_names.nil? || @param_names.empty? ? 'nil' : "Hash[#{@param_names.inspect}.zip(request.params)]"}]
20
+ catch(:pass) do
21
+ #{"if request.path.empty?#{" or (request.path.size == 1 and request.path.first == '')" if @router.ignore_trailing_slash?}" unless @allow_partial}
22
+ if request.perform_call
23
+ env = request.rack_request.dup.env
24
+ env['router.params'] ||= {}
25
+ #{"env['router.params'].merge!(Hash[#{path.param_names.inspect}.zip(request.params)])" if path.dynamic?}
26
+ #{@allow_partial ? "
27
+ env['PATH_INFO'] = \"/\#{request.path.join('/')}\"
28
+ env['SCRIPT_NAME'] += request.rack_request.path_info[0, request.rack_request.path_info.size - env['PATH_INFO'].size]" :
29
+ "env['PATH_INFO'] = ''
30
+ env['SCRIPT_NAME'] += request.rack_request.path_info"
31
+ }
32
+ response = @router.process_destination(#{path_ivar}.route.dest, env)
33
+ router.pass_on_response(response) ? throw(:pass) : throw(:success, response)
34
+ else
35
+ throw :success, Response.new(request, #{path_ivar})
36
+ end
37
+ #{"end" unless @allow_partial}
21
38
  end
22
39
  #{"end" unless @allow_partial}"
23
40
  end
@@ -15,6 +15,8 @@ class HttpRouter
15
15
  end
16
16
 
17
17
  def to_code
18
+ lookup_ivar = :"@lookup_#{router.next_counter}"
19
+ inject_root_ivar(lookup_ivar, @map)
18
20
  inject_root_methods @map.keys.map {|k|
19
21
  method = :"lookup_#{object_id}_#{k.hash}"
20
22
  "define_method(#{method.inspect}) do |request|
@@ -23,10 +25,7 @@ class HttpRouter
23
25
  request.path.unshift part
24
26
  end"}.join("\n")
25
27
  code = "
26
- unless request.path_finished?
27
- m = \"lookup_#{object_id}_\#{request.path.first.hash}\"
28
- send(m, request) if respond_to?(m)
29
- end
28
+ send(\"lookup_#{object_id}_\#{request.path.first.hash}\", request) if !request.path_finished? && #{lookup_ivar}.key?(request.path.first)
30
29
  "
31
30
  end
32
31
  end
@@ -1,7 +1,8 @@
1
1
  require 'uri'
2
2
  class HttpRouter
3
3
  class Path
4
- attr_reader :route, :param_names
4
+ attr_reader :route, :param_names, :dynamic
5
+ alias_method :dynamic?, :dynamic
5
6
  def initialize(route, path, param_names = [])
6
7
  @route, @path, @param_names, @dynamic = route, path, param_names, !param_names.empty?
7
8
  duplicate_param_names = param_names.dup.uniq!
@@ -1,10 +1,9 @@
1
1
  class HttpRouter
2
2
  class Request
3
- attr_reader :acceptance_test
4
3
  attr_accessor :path, :params, :rack_request, :extra_env, :continue, :passed_with
5
4
  alias_method :rack, :rack_request
6
- def initialize(path, rack_request, perform_call, &acceptance_test)
7
- @rack_request, @perform_call, @acceptance_test = rack_request, perform_call, acceptance_test
5
+ def initialize(path, rack_request, perform_call)
6
+ @rack_request, @perform_call = rack_request, perform_call
8
7
  @path = URI.unescape(path).split(/\//)
9
8
  @path.shift if @path.first == ''
10
9
  @path.push('') if path[-1] == ?/
@@ -1,7 +1,6 @@
1
1
  class HttpRouter
2
2
  class Response < Struct.new(:request, :path)
3
3
  attr_reader :params
4
- attr_accessor :acceptance_response
5
4
  def initialize(request, path)
6
5
  super(request, path)
7
6
  @params = path.hashify_params(request.params)
@@ -256,33 +256,9 @@ class HttpRouter
256
256
  private
257
257
  def add_non_path_to_tree(node, path, names)
258
258
  path_obj = Path.new(self, path, names)
259
- destination = Proc.new do |req, params|
260
- if req.path.empty? or match_partially? or (@router.ignore_trailing_slash? and req.path.size == 1 and req.path.last == '')
261
- if req.perform_call
262
- env = req.rack_request.dup.env
263
- env['router.params'] ||= {}
264
- env['router.params'].merge!(path_obj.hashify_params(req.params))
265
- matched = if match_partially?
266
- env['PATH_INFO'] = "/#{req.path.join('/')}"
267
- env['SCRIPT_NAME'] += req.rack_request.path_info[0, req.rack_request.path_info.size - env['PATH_INFO'].size]
268
- else
269
- env["PATH_INFO"] = ''
270
- env["SCRIPT_NAME"] += req.rack_request.path_info
271
- end
272
- response = path_obj.route.dest.call(env)
273
- router.pass_on_response(response) ? throw(:pass) : throw(:success, response)
274
- elsif req.acceptance_test
275
- response = Response.new(req, path_obj)
276
- req.passed_with = catch(:pass) { req.acceptance_test[response] }
277
- throw :success, response if response.acceptance_response
278
- else
279
- throw :success, Response.new(req, path_obj)
280
- end
281
- end
282
- end
283
259
  node = node.add_request(@conditions) unless @conditions.empty?
284
260
  @arbitrary.each{|a| node = node.add_arbitrary(a, match_partially?, names)} if @arbitrary
285
- node.add_destination(destination, @match_partially)
261
+ node.add_destination(path_obj, @match_partially)
286
262
  if dest.respond_to?(:url_mount=)
287
263
  urlmount = UrlMount.new(@original_path, @default_values)
288
264
  urlmount.url_mount = router.url_mount if router.url_mount
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  class HttpRouter #:nodoc
3
- VERSION = '0.8.2'
3
+ VERSION = '0.8.3'
4
4
  end
@@ -44,15 +44,6 @@ class TestRecognition < MiniTest::Unit::TestCase
44
44
  assert_body 'working', router.call(Rack::MockRequest.env_for('/'))
45
45
  end
46
46
 
47
- def test_passing_with_custom_pass_wrapper
48
- passed, working = router {
49
- add('/').to { |env| [404, {}, ['pass']] }
50
- add('/').to { |env| [200, {}, ['working']] }
51
- }
52
- router.set_pass_on_response {|response| response.first == 404}
53
- assert_body 'working', router.call(Rack::MockRequest.env_for('/'))
54
- end
55
-
56
47
  def test_optional
57
48
  route = router {
58
49
  add 'one(/two(/three(/four)(/five)))'
metadata CHANGED
@@ -2,116 +2,116 @@
2
2
  name: http_router
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.8.2
5
+ version: 0.8.3
6
6
  platform: ruby
7
7
  authors:
8
- - Joshua Hull
8
+ - Joshua Hull
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-01 00:00:00 -07:00
13
+ date: 2011-06-02 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
- - !ruby/object:Gem::Dependency
17
- name: rack
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
20
- none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: 1.0.0
25
- type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: url_mount
29
- prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
31
- none: false
32
- requirements:
33
- - - ~>
34
- - !ruby/object:Gem::Version
35
- version: 0.2.1
36
- type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: minitest
40
- prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
42
- none: false
43
- requirements:
44
- - - ~>
45
- - !ruby/object:Gem::Version
46
- version: 2.0.0
47
- type: :development
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: code_stats
51
- prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
53
- none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: "0"
58
- type: :development
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
61
- name: rake
62
- prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
64
- none: false
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 0.8.7
69
- type: :development
70
- version_requirements: *id005
71
- - !ruby/object:Gem::Dependency
72
- name: rbench
73
- prerelease: false
74
- requirement: &id006 !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
79
- version: "0"
80
- type: :development
81
- version_requirements: *id006
82
- - !ruby/object:Gem::Dependency
83
- name: phocus
84
- prerelease: false
85
- requirement: &id007 !ruby/object:Gem::Requirement
86
- none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: "0"
91
- type: :development
92
- version_requirements: *id007
93
- - !ruby/object:Gem::Dependency
94
- name: bundler
95
- prerelease: false
96
- requirement: &id008 !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ~>
100
- - !ruby/object:Gem::Version
101
- version: 1.0.0
102
- type: :development
103
- version_requirements: *id008
104
- - !ruby/object:Gem::Dependency
105
- name: thin
106
- prerelease: false
107
- requirement: &id009 !ruby/object:Gem::Requirement
108
- none: false
109
- requirements:
110
- - - "="
111
- - !ruby/object:Gem::Version
112
- version: 1.2.8
113
- type: :development
114
- version_requirements: *id009
16
+ - !ruby/object:Gem::Dependency
17
+ name: rack
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.0.0
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: url_mount
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 0.2.1
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: minitest
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 2.0.0
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: code_stats
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: rake
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.7
69
+ type: :development
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: rbench
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ type: :development
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: phocus
84
+ prerelease: false
85
+ requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
94
+ name: bundler
95
+ prerelease: false
96
+ requirement: &id008 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.0.0
102
+ type: :development
103
+ version_requirements: *id008
104
+ - !ruby/object:Gem::Dependency
105
+ name: thin
106
+ prerelease: false
107
+ requirement: &id009 !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - "="
111
+ - !ruby/object:Gem::Version
112
+ version: 1.2.8
113
+ type: :development
114
+ version_requirements: *id009
115
115
  description: This library allows you to recognize and build URLs in a Rack application.
116
116
  email: joshbuddy@gmail.com
117
117
  executables: []
@@ -119,94 +119,94 @@ executables: []
119
119
  extensions: []
120
120
 
121
121
  extra_rdoc_files:
122
- - README.md
123
- - LICENSE
122
+ - README.md
123
+ - LICENSE
124
124
  files:
125
- - .gitignore
126
- - .rspec
127
- - Gemfile
128
- - LICENSE
129
- - README.md
130
- - Rakefile
131
- - benchmarks/gen2.rb
132
- - benchmarks/generation_bm.rb
133
- - benchmarks/rack_mount.rb
134
- - benchmarks/rack_recognition_bm.rb
135
- - benchmarks/rec2.rb
136
- - benchmarks/recognition_bm.rb
137
- - examples/glob.ru
138
- - examples/rack_mapper.ru
139
- - examples/simple.ru
140
- - examples/static/config.ru
141
- - examples/static/favicon.ico
142
- - examples/static/images/cat1.jpg
143
- - examples/static/images/cat2.jpg
144
- - examples/static/images/cat3.jpg
145
- - examples/variable.ru
146
- - examples/variable_with_regex.ru
147
- - http_router.gemspec
148
- - lib/http_router.rb
149
- - lib/http_router/node.rb
150
- - lib/http_router/node/arbitrary.rb
151
- - lib/http_router/node/destination.rb
152
- - lib/http_router/node/free_regex.rb
153
- - lib/http_router/node/glob.rb
154
- - lib/http_router/node/glob_regex.rb
155
- - lib/http_router/node/lookup.rb
156
- - lib/http_router/node/regex.rb
157
- - lib/http_router/node/request.rb
158
- - lib/http_router/node/root.rb
159
- - lib/http_router/node/spanning_regex.rb
160
- - lib/http_router/node/variable.rb
161
- - lib/http_router/optional_compiler.rb
162
- - lib/http_router/path.rb
163
- - lib/http_router/rack.rb
164
- - lib/http_router/rack/builder.rb
165
- - lib/http_router/rack/url_map.rb
166
- - lib/http_router/regex_route.rb
167
- - lib/http_router/request.rb
168
- - lib/http_router/response.rb
169
- - lib/http_router/route.rb
170
- - lib/http_router/version.rb
171
- - test/helper.rb
172
- - test/rack/test_dispatch.rb
173
- - test/rack/test_route.rb
174
- - test/rack/test_urlmap.rb
175
- - test/test_arbitrary.rb
176
- - test/test_generate.rb
177
- - test/test_greedy.rb
178
- - test/test_interstitial.rb
179
- - test/test_misc.rb
180
- - test/test_mounting.rb
181
- - test/test_recognize.rb
182
- - test/test_request.rb
183
- - test/test_trailing_slash.rb
184
- - test/test_variable.rb
125
+ - .gitignore
126
+ - .rspec
127
+ - Gemfile
128
+ - LICENSE
129
+ - README.md
130
+ - Rakefile
131
+ - benchmarks/gen2.rb
132
+ - benchmarks/generation_bm.rb
133
+ - benchmarks/rack_mount.rb
134
+ - benchmarks/rack_recognition_bm.rb
135
+ - benchmarks/rec2.rb
136
+ - benchmarks/recognition_bm.rb
137
+ - examples/glob.ru
138
+ - examples/rack_mapper.ru
139
+ - examples/simple.ru
140
+ - examples/static/config.ru
141
+ - examples/static/favicon.ico
142
+ - examples/static/images/cat1.jpg
143
+ - examples/static/images/cat2.jpg
144
+ - examples/static/images/cat3.jpg
145
+ - examples/variable.ru
146
+ - examples/variable_with_regex.ru
147
+ - http_router.gemspec
148
+ - lib/http_router.rb
149
+ - lib/http_router/node.rb
150
+ - lib/http_router/node/arbitrary.rb
151
+ - lib/http_router/node/destination.rb
152
+ - lib/http_router/node/free_regex.rb
153
+ - lib/http_router/node/glob.rb
154
+ - lib/http_router/node/glob_regex.rb
155
+ - lib/http_router/node/lookup.rb
156
+ - lib/http_router/node/regex.rb
157
+ - lib/http_router/node/request.rb
158
+ - lib/http_router/node/root.rb
159
+ - lib/http_router/node/spanning_regex.rb
160
+ - lib/http_router/node/variable.rb
161
+ - lib/http_router/optional_compiler.rb
162
+ - lib/http_router/path.rb
163
+ - lib/http_router/rack.rb
164
+ - lib/http_router/rack/builder.rb
165
+ - lib/http_router/rack/url_map.rb
166
+ - lib/http_router/regex_route.rb
167
+ - lib/http_router/request.rb
168
+ - lib/http_router/response.rb
169
+ - lib/http_router/route.rb
170
+ - lib/http_router/version.rb
171
+ - test/helper.rb
172
+ - test/rack/test_dispatch.rb
173
+ - test/rack/test_route.rb
174
+ - test/rack/test_urlmap.rb
175
+ - test/test_arbitrary.rb
176
+ - test/test_generate.rb
177
+ - test/test_greedy.rb
178
+ - test/test_interstitial.rb
179
+ - test/test_misc.rb
180
+ - test/test_mounting.rb
181
+ - test/test_recognize.rb
182
+ - test/test_request.rb
183
+ - test/test_trailing_slash.rb
184
+ - test/test_variable.rb
185
185
  has_rdoc: true
186
186
  homepage: http://github.com/joshbuddy/http_router
187
187
  licenses: []
188
188
 
189
189
  post_install_message:
190
190
  rdoc_options:
191
- - --charset=UTF-8
191
+ - --charset=UTF-8
192
192
  require_paths:
193
- - lib
193
+ - lib
194
194
  required_ruby_version: !ruby/object:Gem::Requirement
195
195
  none: false
196
196
  requirements:
197
- - - ">="
198
- - !ruby/object:Gem::Version
199
- version: "0"
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: "0"
200
200
  required_rubygems_version: !ruby/object:Gem::Requirement
201
201
  none: false
202
202
  requirements:
203
- - - ">="
204
- - !ruby/object:Gem::Version
205
- version: "0"
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: "0"
206
206
  requirements: []
207
207
 
208
208
  rubyforge_project: http_router
209
- rubygems_version: 1.6.2
209
+ rubygems_version: 1.5.1
210
210
  signing_key:
211
211
  specification_version: 3
212
212
  summary: A kick-ass HTTP router for use in Rack