http_router 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
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