Skip to content

Commit

Permalink
Fix redirects when using non-standard ports.
Browse files Browse the repository at this point in the history
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
antw authored and rkh committed Sep 1, 2010
1 parent 4cab214 commit 1e755d5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
17 changes: 11 additions & 6 deletions lib/sinatra/base.rb
Expand Up @@ -97,13 +97,18 @@ def block.each ; yield call ; end
# Halt processing and redirect to the URI provided. # Halt processing and redirect to the URI provided.
def redirect(uri, *args) def redirect(uri, *args)
if not uri =~ /^https?:\/\// if not uri =~ /^https?:\/\//
# According to RFC 2616 section 14.30, “the field value consists of a single absolute URI” # According to RFC 2616 section 14.30, "the field value consists of a
abs_uri = request.scheme + "://" # single absolute URI"
abs_uri << request.host abs_uri = "#{request.scheme}://#{request.host}"
abs_uri << ":#{port}" if request.scheme == "https" and request.port != 443 or request.scheme == "http" and request.port != 80
abs_uri << uri if request.scheme == 'https' && request.port != 443 ||
uri = abs_uri request.scheme == 'http' && request.port != 80
abs_uri << ":#{request.port}"
end

uri = (abs_uri << uri)
end end

status 302 status 302
response['Location'] = uri response['Location'] = uri
halt(*args) halt(*args)
Expand Down
24 changes: 24 additions & 0 deletions test/helpers_test.rb
Expand Up @@ -87,6 +87,30 @@ def test_default
assert_equal 302, response.status assert_equal 302, response.status
assert_equal 'http://example.org/foo', response['Location'] assert_equal 'http://example.org/foo', response['Location']
end 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 end


describe 'error' do describe 'error' do
Expand Down

0 comments on commit 1e755d5

Please sign in to comment.