http_router 0.7.2 → 0.7.3

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