http_router 0.7.2 → 0.7.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/Rakefile CHANGED
@@ -114,4 +114,4 @@ Rake::RDocTask.new do |rd|
114
114
  end
115
115
 
116
116
  require 'code_stats'
117
- CodeStats::Tasks.new(:reporting_depth => 3)
117
+ CodeStats::Tasks.new
data/benchmarks/gen2.rb CHANGED
@@ -1,14 +1,16 @@
1
1
  require 'rubygems'
2
2
  require 'rbench'
3
3
  #require 'lib/usher'
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
+
4
6
  require 'lib/http_router'
5
7
 
6
8
  u = HttpRouter.new
7
- u.add('/simple') .name(:simple).compile
8
- u.add('/simple/:variable') .name(:one_variable).compile
9
- u.add('/simple/:var1/:var2/:var3') .name(:three_variables).compile
10
- u.add('/simple/:v1/:v2/:v3/:v4/:v5/:v6/:v7/:v8') .name(:eight_variables).compile
11
- u.add('/with_condition/:cond1/:cond2').matching(:cond1 => /^\d+$/, :cond2 => /^[a-z]+$/) .name(:two_conditions).compile
9
+ u.add('/simple') .name(:simple).send(:compile)
10
+ u.add('/simple/:variable') .name(:one_variable).send(:compile)
11
+ u.add('/simple/:var1/:var2/:var3') .name(:three_variables).send(:compile)
12
+ u.add('/simple/:v1/:v2/:v3/:v4/:v5/:v6/:v7/:v8') .name(:eight_variables).send(:compile)
13
+ u.add('/with_condition/:cond1/:cond2').matching(:cond1 => /^\d+$/, :cond2 => /^[a-z]+$/) .name(:two_conditions).send(:compile)
12
14
 
13
15
  TIMES = 50_000
14
16
 
data/benchmarks/rec2.rb CHANGED
@@ -25,7 +25,7 @@ puts Benchmark.measure {
25
25
  puts "u.routes.size: #{u.routes.size}"
26
26
  }
27
27
  #
28
- TIMES = 50_000
28
+ TIMES = 10_000
29
29
 
30
30
  #simple_env =
31
31
  #simple2_env =
@@ -34,7 +34,7 @@ TIMES = 50_000
34
34
  #simple_and_dynamic_env1 = Rack::MockRequest.env_for('/rails/controller/action/id')
35
35
  #simple_and_dynamic_env2 = Rack::MockRequest.env_for('/greedy/controller/action/id')
36
36
  #simple_and_dynamic_env3 = Rack::MockRequest.env_for('/greedy/hey.hello.html')
37
- 5.times {
37
+ #5.times {
38
38
  RBench.run(TIMES) do
39
39
 
40
40
  report "2 levels, static" do
@@ -62,5 +62,5 @@ TIMES = 50_000
62
62
  #end
63
63
 
64
64
  end
65
- }
65
+ #}
66
66
  puts `ps -o rss= -p #{Process.pid}`.to_i
data/lib/http_router.rb CHANGED
@@ -11,7 +11,7 @@ require 'http_router/optional_compiler'
11
11
 
12
12
  class HttpRouter
13
13
 
14
- attr_reader :root, :routes, :known_methods, :named_routes, :request_methods
14
+ attr_reader :root, :routes, :known_methods, :named_routes
15
15
  attr_accessor :default_app, :url_mount
16
16
 
17
17
  # Raised when a Route is not able to be generated.
@@ -29,7 +29,6 @@ class HttpRouter
29
29
  # * :ignore_trailing_slash -- Ignore a trailing / when attempting to match. Defaults to +true+.
30
30
  # * :redirect_trailing_slash -- On trailing /, redirect to the same path without the /. Defaults to +false+.
31
31
  # * :known_methods -- Array of http methods tested for 405s.
32
- # * :request_methods -- Array of methods to use on request
33
32
  def initialize(*args, &blk)
34
33
  default_app, options = args.first.is_a?(Hash) ? [nil, args.first] : [args.first, args[1]]
35
34
  @options = options
@@ -37,7 +36,6 @@ class HttpRouter
37
36
  @ignore_trailing_slash = options && options.key?(:ignore_trailing_slash) ? options[:ignore_trailing_slash] : true
38
37
  @redirect_trailing_slash = options && options.key?(:redirect_trailing_slash) ? options[:redirect_trailing_slash] : false
39
38
  @known_methods = Set.new(options && options[:known_methods] || [])
40
- @request_methods = options && options[:request_methods] || [:host, :scheme, :request_method, :user_agent]
41
39
  reset!
42
40
  instance_eval(&blk) if blk
43
41
  end
@@ -123,14 +121,7 @@ class HttpRouter
123
121
  request = Request.new(rack_request.path_info, rack_request, perform_call)
124
122
  response = catch(:success) { @root[request] }
125
123
  if response.nil?
126
- supported_methods = (@known_methods - [env['REQUEST_METHOD']]).select do |m|
127
- test_env = ::Rack::Request.new(rack_request.env.clone)
128
- test_env.env['REQUEST_METHOD'] = m
129
- test_env.env['_HTTP_ROUTER_405_TESTING_ACCEPTANCE'] = true
130
- test_request = Request.new(test_env.path_info, test_env, 405)
131
- catch(:success) { @root[test_request] }
132
- end
133
- supported_methods.empty? ? (perform_call ? @default_app.call(env) : nil) : [405, {'Allow' => supported_methods.sort.join(", ")}, []]
124
+ no_response(env, perform_call)
134
125
  elsif response
135
126
  response
136
127
  elsif perform_call
@@ -203,6 +194,17 @@ class HttpRouter
203
194
  end
204
195
 
205
196
  private
197
+ def no_response(env, perform_call = true)
198
+ supported_methods = (@known_methods - [env['REQUEST_METHOD']]).select do |m|
199
+ test_env = ::Rack::Request.new(env.clone)
200
+ test_env.env['REQUEST_METHOD'] = m
201
+ test_env.env['_HTTP_ROUTER_405_TESTING_ACCEPTANCE'] = true
202
+ test_request = Request.new(test_env.path_info, test_env, 405)
203
+ catch(:success) { @root[test_request] }
204
+ end
205
+ supported_methods.empty? ? (perform_call ? @default_app.call(env) : nil) : [405, {'Allow' => supported_methods.sort.join(", ")}, []]
206
+ end
207
+
206
208
  def add_with_request_method(path, method, opts = {}, &app)
207
209
  route = add(path, opts).send(method.to_sym)
208
210
  route.to(app) if app
@@ -18,8 +18,7 @@ class HttpRouter
18
18
  end
19
19
 
20
20
  def [](request)
21
- @matchers.each {|m| m[request] }
22
- nil
21
+ @matchers.each {|m| m[request] }; nil
23
22
  end
24
23
 
25
24
  def add_variable
@@ -66,11 +65,8 @@ class HttpRouter
66
65
  end
67
66
 
68
67
  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 * '/'
68
+ val.to_s.gsub!(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') }
69
+ val
74
70
  end
75
71
  end
76
72
  end
@@ -8,10 +8,12 @@ class HttpRouter
8
8
 
9
9
  def [](request)
10
10
  if request.path.empty? or (request.path.size == 1 and request.path[0] == '') or @allow_partial
11
- request = request.clone
12
- request.continue = proc { |state| super(request) if state }
13
- params = @param_names.nil? ? {} : Hash[@param_names.zip(request.params)]
14
- @blk.call(request, params)
11
+ catch(:pass) do
12
+ request = request.clone
13
+ request.continue = proc { |state| super(request) if state }
14
+ params = @param_names.nil? ? {} : Hash[@param_names.zip(request.params)]
15
+ @blk.call(request, params)
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -8,7 +8,7 @@ class HttpRouter
8
8
  end
9
9
 
10
10
  def [](request)
11
- whole_path = "/#{join_whole_path(request)}"
11
+ whole_path = "/#{request.joined_path}"
12
12
  if match = @matcher.match(whole_path) and match[0].size == whole_path.size
13
13
  request = request.clone
14
14
  request.extra_env['router.regex_match'] = match
@@ -2,7 +2,7 @@ class HttpRouter
2
2
  class Node
3
3
  class SpanningRegex < Regex
4
4
  def [](request)
5
- whole_path = join_whole_path(request)
5
+ whole_path = request.joined_path
6
6
  if match = @matcher.match(whole_path) and match.begin(0).zero?
7
7
  request = request.clone
8
8
  add_params(request, match)
@@ -2,6 +2,7 @@ class HttpRouter
2
2
  class RegexRoute < Route
3
3
  def initialize(router, path, opts = {})
4
4
  @router, @original_path, @opts = router, path, opts
5
+ process_opts
5
6
  end
6
7
 
7
8
  def compile
@@ -10,6 +10,10 @@ class HttpRouter
10
10
  @params = []
11
11
  end
12
12
 
13
+ def joined_path
14
+ @path * '/'
15
+ end
16
+
13
17
  def perform_call
14
18
  @perform_call == true
15
19
  end
@@ -10,19 +10,22 @@ class HttpRouter
10
10
  @original_path = path
11
11
  @path = path
12
12
  @opts = opts
13
- @arbitrary = opts[:arbitrary] || opts[:__arbitrary__]
14
- @conditions = opts[:conditions] || opts[:__conditions__] || {}
15
- name(opts[:name]) if opts.key?(:name)
16
- @opts.merge!(opts[:matching]) if opts[:matching]
17
13
  @matches_with = {}
18
14
  @default_values = opts[:default_values] || {}
19
15
  if @original_path[-1] == ?*
20
16
  @match_partially = true
21
17
  path.slice!(-1)
22
- elsif opts.key?(:partial)
23
- @match_partially = opts[:partial]
24
18
  end
25
19
  @paths = OptionalCompiler.new(path).paths
20
+ process_opts
21
+ end
22
+
23
+ def process_opts
24
+ @arbitrary = @opts[:arbitrary] || @opts[:__arbitrary__]
25
+ @conditions = @opts[:conditions] || @opts[:__conditions__] || {}
26
+ @opts.merge!(@opts[:matching]) if @opts[:matching]
27
+ @match_partially = @opts[:partial] if @match_partially.nil? && @opts.key?(:partial)
28
+ name(@opts[:name]) if @opts.key?(:name)
26
29
  end
27
30
 
28
31
  def as_options
@@ -252,29 +255,27 @@ class HttpRouter
252
255
  private
253
256
  def add_non_path_to_tree(node, path, names)
254
257
  path_obj = Path.new(self, path, names)
255
- destination = Proc.new { |req, use_partial_matching|
256
- if (use_partial_matching or req.path.empty?)
257
- if req.path.empty? or match_partially? or (@router.ignore_trailing_slash? and req.path.size == 1 and req.path.last == '')
258
- if req.perform_call
259
- env = req.rack_request.dup.env
260
- env['router.params'] ||= {}
261
- env['router.params'].merge!(path_obj.hashify_params(req.params))
262
- matched = if match_partially?
263
- env['PATH_INFO'] = "/#{req.path.join('/')}"
264
- env['SCRIPT_NAME'] += req.rack_request.path_info[0, req.rack_request.path_info.size - env['PATH_INFO'].size]
265
- else
266
- env["PATH_INFO"] = ''
267
- env["SCRIPT_NAME"] += req.rack_request.path_info
268
- end
269
- response = path_obj.route.dest.call(env)
270
- router.pass_on_response(response) ? throw(:pass) : throw(:success, response)
258
+ destination = Proc.new do |req, params|
259
+ if req.path.empty? or match_partially? or (@router.ignore_trailing_slash? and req.path.size == 1 and req.path.last == '')
260
+ if req.perform_call
261
+ env = req.rack_request.dup.env
262
+ env['router.params'] ||= {}
263
+ env['router.params'].merge!(path_obj.hashify_params(req.params))
264
+ matched = if match_partially?
265
+ env['PATH_INFO'] = "/#{req.path.join('/')}"
266
+ env['SCRIPT_NAME'] += req.rack_request.path_info[0, req.rack_request.path_info.size - env['PATH_INFO'].size]
271
267
  else
272
- throw :success, Response.new(req, path_obj)
268
+ env["PATH_INFO"] = ''
269
+ env["SCRIPT_NAME"] += req.rack_request.path_info
273
270
  end
271
+ response = path_obj.route.dest.call(env)
272
+ router.pass_on_response(response) ? throw(:pass) : throw(:success, response)
273
+ else
274
+ throw :success, Response.new(req, path_obj)
274
275
  end
275
276
  end
276
- }
277
- node = node.add_request(@conditions) if @conditions && !@conditions.empty?
277
+ end
278
+ node = node.add_request(@conditions) unless @conditions.empty?
278
279
  @arbitrary.each{|a| node = node.add_arbitrary(a, match_partially?, names)} if @arbitrary
279
280
  node.add_destination(destination, @match_partially)
280
281
  if dest.respond_to?(:url_mount=)
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  class HttpRouter #:nodoc
3
- VERSION = '0.7.2'
3
+ VERSION = '0.7.3'
4
4
  end
@@ -48,6 +48,14 @@ class TestArbitrary < MiniTest::Unit::TestCase
48
48
  assert_route r, '/test', {:test => 'test'}
49
49
  end
50
50
 
51
+ def test_passing
52
+ never, route = router {
53
+ add('test').arbitrary(Proc.new{|req, params| throw :pass })
54
+ add("test")
55
+ }
56
+ assert_route route, 'http://lovelove:8080/test'
57
+ end
58
+
51
59
  def test_continue
52
60
  no, yes = router {
53
61
  add('test').arbitrary_with_continue{|req, p| req.continue[false]}
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: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 2
10
- version: 0.7.2
9
+ - 3
10
+ version: 0.7.3
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-25 00:00:00 -07:00
18
+ date: 2011-04-26 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency