diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 7172a174..6562af00 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -96,6 +96,14 @@ module Sinatra # Halt processing and redirect to the URI provided. def redirect(uri, *args) + if not uri =~ /^https?:\/\// + # According to RFC 2616 section 14.30, “the field value consists of a single absolute URI” + abs_uri = request.scheme + "://" + abs_uri << request.host + abs_uri << ":#{port}" if request.scheme == "https" and request.port != 443 or request.scheme == "http" and request.port != 80 + abs_uri << uri + uri = abs_uri + end status 302 response['Location'] = uri halt(*args) diff --git a/test/filter_test.rb b/test/filter_test.rb index 4689913c..11a3d8e4 100644 --- a/test/filter_test.rb +++ b/test/filter_test.rb @@ -55,7 +55,7 @@ class BeforeFilterTest < Test::Unit::TestCase get '/foo' assert redirect? - assert_equal '/bar', response['Location'] + assert_equal 'http://example.org/bar', response['Location'] assert_equal '', body end @@ -189,7 +189,7 @@ class AfterFilterTest < Test::Unit::TestCase get '/foo' assert redirect? - assert_equal '/bar', response['Location'] + assert_equal 'http://example.org/bar', response['Location'] assert_equal '', body end diff --git a/test/helpers_test.rb b/test/helpers_test.rb index 647a1dce..3be2a839 100644 --- a/test/helpers_test.rb +++ b/test/helpers_test.rb @@ -58,7 +58,7 @@ class HelpersTest < Test::Unit::TestCase get '/' assert_equal 302, status assert_equal '', body - assert_equal '/foo', response['Location'] + assert_equal 'http://example.org/foo', response['Location'] end it 'uses the code given when specified' do @@ -72,7 +72,7 @@ class HelpersTest < Test::Unit::TestCase get '/' assert_equal 301, status assert_equal '', body - assert_equal '/foo', response['Location'] + assert_equal 'http://example.org/foo', response['Location'] end it 'redirects back to request.referer when passed back' do @@ -85,7 +85,7 @@ class HelpersTest < Test::Unit::TestCase request = Rack::MockRequest.new(@app) response = request.get('/try_redirect', 'HTTP_REFERER' => '/foo') assert_equal 302, response.status - assert_equal '/foo', response['Location'] + assert_equal 'http://example.org/foo', response['Location'] end end