Skip to content
Browse files

simpler 405

  • Loading branch information...
1 parent 609573f commit f4a34f4fa66729570369df4a244ff135bf074c54 @joshbuddy committed Oct 1, 2011
View
21 lib/http_router.rb
@@ -25,7 +25,7 @@ class HttpRouter
# Raised when there are left over options
LeftOverOptions = Class.new(RuntimeError)
- attr_reader :root, :routes, :known_methods, :named_routes, :nodes
+ attr_reader :root, :routes, :named_routes, :nodes
attr_accessor :default_app, :url_mount, :route_class, :default_host, :default_port, :default_scheme
# Creates a new HttpRouter.
@@ -35,14 +35,12 @@ class HttpRouter
# * :default_app -- Default application used if there is a non-match on #call. Defaults to 404 generator.
# * :ignore_trailing_slash -- Ignore a trailing / when attempting to match. Defaults to +true+.
# * :redirect_trailing_slash -- On trailing /, redirect to the same path without the /. Defaults to +false+.
- # * :known_methods -- Array of http methods tested for 405s.
def initialize(*args, &blk)
default_app, options = args.first.is_a?(Hash) ? [nil, args.first] : [args.first, args[1]]
@options = options
@default_app = default_app || options && options[:default_app] || proc{|env| ::Rack::Response.new("Not Found", 404, {'X-Cascade' => 'pass'}).finish }
@ignore_trailing_slash = options && options.key?(:ignore_trailing_slash) ? options[:ignore_trailing_slash] : true
@redirect_trailing_slash = options && options.key?(:redirect_trailing_slash) ? options[:redirect_trailing_slash] : false
- @known_methods = Set.new(options && options[:known_methods] || [])
@route_class = Route
reset!
instance_eval(&blk) if blk
@@ -221,21 +219,14 @@ def rewrite_path_info(env, request)
env['PATH_INFO'] = ''
end
- def no_response(env)
- supported_methods = @known_methods.select do |m|
- next if m == env['REQUEST_METHOD']
- test_env = ::Rack::Request.new(env.clone)
- test_env.env['REQUEST_METHOD'] = m
- test_env.env['_HTTP_ROUTER_405_TESTING_ACCEPTANCE'] = true
- test_request = Request.new(test_env.path_info, test_env)
- !@root.call(test_request).nil?
- end
- supported_methods.empty? ? @default_app.call(env) : [405, {'Allow' => supported_methods.sort.join(", ")}, []]
+ def no_response(request, env)
+ request.acceptable_methods.empty? ?
+ @default_app.call(env) : [405, {'Allow' => request.acceptable_methods.sort.join(", ")}, []]
end
def to_s
compile
- "#<HttpRouter:0x#{object_id.to_s(16)} number of routes (#{routes.size}) ignore_trailing_slash? (#{ignore_trailing_slash?}) redirect_trailing_slash? (#{redirect_trailing_slash?}) known_methods (#{known_methods.to_a.join(', ')})>"
+ "#<HttpRouter:0x#{object_id.to_s(16)} number of routes (#{routes.size}) ignore_trailing_slash? (#{ignore_trailing_slash?}) redirect_trailing_slash? (#{redirect_trailing_slash?})>"
end
def inspect
@@ -283,7 +274,7 @@ def raw_call(env, &blk)
if blk
@root.call(request, &blk)
else
- @root.call(request) or no_response(env)
+ @root.call(request) or no_response(request, env)
end
end
View
7 lib/http_router/node/request_method.rb
@@ -4,6 +4,13 @@ class RequestMethod < AbstractRequestNode
def initialize(router, parent, request_methods)
super(router, parent, request_methods, :request_method)
end
+
+ def to_code
+ "if #{@tests.map { |test| "#{test.inspect} === request.rack_request.#{request_method}" } * ' or '}
+ #{super}
+ end
+ request.acceptable_methods.merge(#{@tests.inspect})"
+ end
end
end
end
View
2 lib/http_router/node/root.rb
@@ -130,8 +130,8 @@ def add_complex_part(route, node, parts, path_generator)
def add_non_path_to_tree(route, node, path, param_names)
node = node.add_host([route.host, route.other_hosts].flatten.compact) if route.host or route.other_hosts
node = node.add_user_agent(route.user_agent) if route.user_agent
- node = node.add_request_method(route.request_methods) if route.request_methods
node = node.add_scheme(route.scheme) if route.scheme
+ node = node.add_request_method(route.request_methods) if route.request_methods
path_obj = node.add_destination(route, path, param_names)
path_obj
end
View
2 lib/http_router/request.rb
@@ -2,13 +2,15 @@ class HttpRouter
class Request
attr_accessor :path, :params, :rack_request, :extra_env, :continue, :passed_with
alias_method :rack, :rack_request
+ attr_reader :acceptable_methods
def initialize(path, rack_request)
@rack_request = rack_request
@path = URI.unescape(path).split(/\//)
@path.shift if @path.first == ''
@path.push('') if path[-1] == ?/
@extra_env = {}
@params = []
+ @acceptable_methods = Set.new
end
def joined_path
View
1 lib/http_router/route.rb
@@ -40,7 +40,6 @@ def add_request_method(methods)
methods.each do |method|
method = method.to_s.upcase
raise unless VALID_HTTP_VERBS.include?(method)
- @router.known_methods << method
@request_methods << method
end
end
View
4 test/test_misc.rb
@@ -105,8 +105,8 @@ def test_to_s_and_inspect
router.add('/').to(:test)
router.add('/test').to(:test2)
router.post('/test').to(:test3)
- assert router.to_s.match(/^#<HttpRouter:0x[0-9a-f-]+ number of routes \(3\) ignore_trailing_slash\? \(true\) redirect_trailing_slash\? \(false\) known_methods \(POST\)>$/)
- assert router.inspect.match(/^#<HttpRouter:0x[0-9a-f-]+ number of routes \(3\) ignore_trailing_slash\? \(true\) redirect_trailing_slash\? \(false\) known_methods \(POST\)>/)
+ assert router.to_s.match(/^#<HttpRouter:0x[0-9a-f-]+ number of routes \(3\) ignore_trailing_slash\? \(true\) redirect_trailing_slash\? \(false\)>$/)
+ assert router.inspect.match(/^#<HttpRouter:0x[0-9a-f-]+ number of routes \(3\) ignore_trailing_slash\? \(true\) redirect_trailing_slash\? \(false\)>/)
assert router.inspect.match(/Path: "\/test" for route unnamed route to :test3/)
end
end

0 comments on commit f4a34f4

Please sign in to comment.
Something went wrong with that request. Please try again.