remove passing support

This commit is contained in:
Josh Hull 2011-09-24 09:55:46 -07:00
parent 83b4875fa2
commit c10ffc6fa1
5 changed files with 36 additions and 56 deletions

View File

@ -3,12 +3,13 @@ require 'rbench'
require 'rack'
require 'rack/mount'
#require '../usher/lib/usher'
require 'lib/http_router'
$: << 'lib'
require 'http_router'
set = Rack::Mount::RouteSet.new do |set|
set.add_route(proc{|env| [200, {'Content-type'=>'text/html'}, []]}, {:path => '/simple'}, {}, :simple)
set.add_route(proc{|env| [200, {'Content-type'=>'text/html'}, []]}, {:path => '/simple/again'}, {}, :again)
set.add_route(proc{|env| [200, {'Content-type'=>'text/html'}, []]}, {:path => '/dynamic/:variable'}, {}, :variable)
set.add_route(proc{|env| [200, {'Content-type'=>'text/html'}, []]}, {:path => %r{/simple/(.*?)}}, {}, :more)
end
#u = Usher::Interface.for(:rack)
@ -16,32 +17,25 @@ end
#u.add('/simple/again').to(proc{|env| [200, {'Content-type'=>'text/html'}, []]})
#u.add('/dynamic/anything').to(proc{|env| [200, {'Content-type'=>'text/html'}, []]})
hr = HttpRouter.new
hr.add('/simple').to(proc{|env| [200, {'Content-type'=>'text/html'}, []]})
hr.add('/simple/again').to(proc{|env| [200, {'Content-type'=>'text/html'}, []]})
hr.add('/dynamic/anything').to(proc{|env| [200, {'Content-type'=>'text/html'}, []]})
TIMES = 50_000
simple_env = Rack::MockRequest.env_for('/simple')
simple2_env = Rack::MockRequest.env_for('/simple/again')
simple_and_dynamic_env = Rack::MockRequest.env_for('/dynamic/anything')
dynamic_env = Rack::MockRequest.env_for('/simple/something')
3.times do
RBench.run(TIMES) do
report "2 levels, static" do
set.url(simple_env, :simple)
set.call(simple_env).first == 200 or raise
end
report "4 levels, static" do
set.url(simple_env, :again)
set.call(simple2_env).first == 200 or raise
end
report "4 levels, 1 dynamic" do
set.url(simple_env, :variable, {:variable => 'onemore'})
report "4 levels, static" do
set.call(dynamic_env).first == 200 or raise
end
end
end

View File

@ -290,11 +290,11 @@ class HttpRouter
def raw_call(env, as_iterator = false)
rack_request = ::Rack::Request.new(env)
request = Request.new(rack_request.path_info, rack_request, as_iterator)
response = catch(:success) { @root[request] }
if as_iterator
request.matches.empty? ? nil : request.matches
else
response = @root[request]
unless as_iterator
response or no_response(env)
else
request.matches.empty? ? nil : request.matches
end
end

View File

@ -25,16 +25,14 @@ class HttpRouter
end
def to_code
lookup_ivar = inject_root_ivar(@map)
method_prefix = "lookup_#{root.next_counter} "
inject_root_methods @map.keys.map {|k|
method = :"#{method_prefix}#{k}"
"define_method(#{method.inspect}) do |request|
part = request.path.shift
#{@map[k].map{|n| n.to_code} * "\n"}
request.path.unshift part
end"}.join("\n")
"send(\"#{method_prefix}\#{request.path.first}\", request) if !request.path_finished? && #{lookup_ivar}.key?(request.path.first)"
part_name = "part#{root.next_counter}"
"unless request.path_finished?
#{part_name} = request.path.shift
case #{part_name}
#{@map.map{|k, v| "when #{k.inspect}; #{v.map(&:to_code) * "\n"};"}}
end
request.path.unshift #{part_name}
end"
end
end
end

View File

@ -17,27 +17,23 @@ class HttpRouter
def to_code
path_ivar = inject_root_ivar(self)
"#{"if request.path_finished?" unless route.match_partially}
catch(:pass) do
#{"if request.path.size == 1 && request.path.first == '' && (request.rack_request.head? || request.rack_request.get?) && request.rack_request.path_info[-1] == ?/
response = ::Rack::Response.new
response.redirect(request.rack_request.path_info[0, request.rack_request.path_info.size - 1], 302)
throw :success, response.finish
end" if router.redirect_trailing_slash?}
"#{"if request.path.size == 1 && request.path.first == '' && (request.rack_request.head? || request.rack_request.get?) && request.rack_request.path_info[-1] == ?/
response = ::Rack::Response.new
response.redirect(request.rack_request.path_info[0, request.rack_request.path_info.size - 1], 302)
return response.finish
end" if router.redirect_trailing_slash?}
#{"if request.path.empty?#{" or (request.path.size == 1 and request.path.first == '')" if router.ignore_trailing_slash?}" unless route.match_partially}
if request.as_iterator
request.matched_route(Response.new(request, #{path_ivar}))
else
env = request.rack_request.dup.env
env['router.request'] = request
env['router.params'] ||= {}
#{"env['router.params'].merge!(Hash[#{param_names.inspect}.zip(request.params)])" if dynamic?}
@router.rewrite#{"_partial" if route.match_partially}_path_info(env, request)
response = @router.process_destination_path(#{path_ivar}, env)
router.pass_on_response(response) ? throw(:pass) : throw(:success, response)
end
#{"end" unless route.match_partially}
#{"if request.#{router.ignore_trailing_slash? ? 'path_finished?' : 'path.empty?'}" unless route.match_partially}
if request.as_iterator
request.matched_route(Response.new(request, #{path_ivar}))
else
env = request.rack_request.dup.env
env['router.request'] = request
env['router.params'] ||= {}
#{"env['router.params'].merge!(Hash[#{param_names.inspect}.zip(request.params)])" if dynamic?}
@router.rewrite#{"_partial" if route.match_partially}_path_info(env, request)
response = @router.process_destination_path(#{path_ivar}, env)
return response unless router.pass_on_response(response)
end
#{"end" unless route.match_partially}"
end

View File

@ -8,14 +8,6 @@ class TestRecognition < MiniTest::Unit::TestCase
EOT
end
def test_passing
passed, working = router {
add('/').to { |env| throw :pass; [200, {}, ['pass']] }
add('/').to { |env| [200, {}, ['working']] }
}
assert_body 'working', router.call(Rack::MockRequest.env_for('/'))
end
def test_non_path_matching
passed, working = router {
add(:conditions => {:user_agent => /MSIE/}).to { |env| [200, {}, ['IE']] }