Permalink
Browse files

Fix redirects when using non-standard ports.

Commit 507972e introduced a change to the redirect method in order to
be compliant with RFC 2616's requirement that the Location header use an
"absoluteURI". However, the change relied on an undefined "port"
variable. This commit fixes that omission by using the port from the
request.

The formatting of the redirect method has also been adjusted to wrap at
approx. 78-80 characters and use "&&" and "||", like the rest of Sinatra.

Specs included.
  • Loading branch information...
1 parent 4cab214 commit 1e755d5d9b241b9c9aaf1704f619cd4ca8286c7e @antw antw committed with Sep 1, 2010
Showing with 35 additions and 6 deletions.
  1. +11 −6 lib/sinatra/base.rb
  2. +24 −0 test/helpers_test.rb
View
@@ -97,13 +97,18 @@ def block.each ; yield call ; end
# 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
+ # According to RFC 2616 section 14.30, "the field value consists of a
+ # single absolute URI"
+ abs_uri = "#{request.scheme}://#{request.host}"
+
+ if request.scheme == 'https' && request.port != 443 ||
+ request.scheme == 'http' && request.port != 80
+ abs_uri << ":#{request.port}"
+ end
+
+ uri = (abs_uri << uri)
end
+
status 302
response['Location'] = uri
halt(*args)
View
@@ -87,6 +87,30 @@ def test_default
assert_equal 302, response.status
assert_equal 'http://example.org/foo', response['Location']
end
+
+ it 'redirects using a non-standard HTTP port' do
+ mock_app {
+ get '/' do
+ redirect '/foo'
+ end
+ }
+
+ request = Rack::MockRequest.new(@app)
+ response = request.get('/', 'SERVER_PORT' => '81')
+ assert_equal 'http://example.org:81/foo', response['Location']
+ end
+
+ it 'redirects using a non-standard HTTPS port' do
+ mock_app {
+ get '/' do
+ redirect '/foo'
+ end
+ }
+
+ request = Rack::MockRequest.new(@app)
+ response = request.get('/', 'SERVER_PORT' => '444')
+ assert_equal 'http://example.org:444/foo', response['Location']
+ end
end
describe 'error' do

0 comments on commit 1e755d5

Please sign in to comment.