Catch InvalidURIError on bad paths on redirect.

Handle URI::InvalidURIError errors on the redirect route method, so it
wont raise a 500 if a bad path is given.
This commit is contained in:
Arthur Neves 2015-06-16 21:03:39 +02:00
parent e60c18931c
commit e23b314945
No known key found for this signature in database
GPG Key ID: 04A390FB1E433E17
3 changed files with 19 additions and 4 deletions

@ -1,3 +1,7 @@
* Handle InvalidURIError on bad paths on redirect route.
*arthurnn*
* Deprecate passing first parameter as `Hash` and default status code for `head` method. * Deprecate passing first parameter as `Hash` and default status code for `head` method.
*Mehmet Emin İNAÇ* *Mehmet Emin İNAÇ*

@ -23,8 +23,12 @@ def call(env)
def serve(req) def serve(req)
req.check_path_parameters! req.check_path_parameters!
uri = URI.parse(path(req.path_parameters, req)) begin
uri = URI.parse(path(req.path_parameters, req))
rescue URI::InvalidURIError
return [ 400, {}, ['Invalid path.'] ]
end
unless uri.host unless uri.host
if relative_path?(uri.path) if relative_path?(uri.path)
uri.path = "#{req.script_name}/#{uri.path}" uri.path = "#{req.script_name}/#{uri.path}"
@ -32,7 +36,7 @@ def serve(req)
uri.path = req.script_name.empty? ? "/" : req.script_name uri.path = req.script_name.empty? ? "/" : req.script_name
end end
end end
uri.scheme ||= req.scheme uri.scheme ||= req.scheme
uri.host ||= req.host uri.host ||= req.host
uri.port ||= req.port unless req.standard_port? uri.port ||= req.port unless req.standard_port?
@ -124,7 +128,7 @@ def path(params, request)
url_options[:script_name] = request.script_name url_options[:script_name] = request.script_name
end end
end end
ActionDispatch::Http::URL.url_for url_options ActionDispatch::Http::URL.url_for url_options
end end

@ -219,6 +219,13 @@ def test_X_Cascade
assert_equal 404, resp.first assert_equal 404, resp.first
end end
def test_invalid_url_path
routes = Class.new { include ActionDispatch::Routing::Redirection }.new
route = routes.redirect("/foo/bar/%{id}")
resp = route.serve(rails_env({ 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/foo/(function(){})' }))
assert_equal 400, resp.first
end
def test_clear_trailing_slash_from_script_name_on_root_unanchored_routes def test_clear_trailing_slash_from_script_name_on_root_unanchored_routes
route_set = Routing::RouteSet.new route_set = Routing::RouteSet.new
mapper = Routing::Mapper.new route_set mapper = Routing::Mapper.new route_set