Skip to content

Commit

Permalink
Don't add the standard https port when using redirect in routes.rb an…
Browse files Browse the repository at this point in the history
…d ensure that request.scheme returns https when using a reverse proxy.

[#5408 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information
pixeltrix authored and josevalim committed Aug 20, 2010
1 parent 771d2f9 commit 0d0fbf1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
10 changes: 10 additions & 0 deletions actionpack/lib/action_dispatch/http/url.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ def url
protocol + host_with_port + fullpath protocol + host_with_port + fullpath
end end


# Returns 'https' if this is an SSL request and 'http' otherwise.
def scheme
ssl? ? 'https' : 'http'
end

# Returns 'https://' if this is an SSL request and 'http://' otherwise. # Returns 'https://' if this is an SSL request and 'http://' otherwise.
def protocol def protocol
ssl? ? 'https://' : 'http://' ssl? ? 'https://' : 'http://'
Expand Down Expand Up @@ -53,6 +58,11 @@ def standard_port
end end
end end


# Returns whether this request is using the standard port
def standard_port?
port == standard_port
end

# Returns a \port suffix like ":8080" if the \port number of this request # Returns a \port suffix like ":8080" if the \port number of this request
# is not the default HTTP \port 80 or HTTPS \port 443. # is not the default HTTP \port 80 or HTTPS \port 443.
def port_string def port_string
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/routing/mapper.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def redirect(*args, &block)
uri = URI.parse(path_proc.call(*params)) uri = URI.parse(path_proc.call(*params))
uri.scheme ||= req.scheme uri.scheme ||= req.scheme
uri.host ||= req.host uri.host ||= req.host
uri.port ||= req.port unless req.port == 80 uri.port ||= req.port unless req.standard_port?


body = %(<html><body>You are being <a href="#{ERB::Util.h(uri.to_s)}">redirected</a>.</body></html>) body = %(<html><body>You are being <a href="#{ERB::Util.h(uri.to_s)}">redirected</a>.</body></html>)


Expand Down
36 changes: 36 additions & 0 deletions actionpack/test/dispatch/request_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -132,6 +132,32 @@ class RequestTest < ActiveSupport::TestCase
assert_equal [], request.subdomains assert_equal [], request.subdomains
end end


test "standard_port" do
request = stub_request
assert_equal 80, request.standard_port

request = stub_request 'HTTPS' => 'on'
assert_equal 443, request.standard_port
end

test "standard_port?" do
request = stub_request
assert !request.ssl?
assert request.standard_port?

request = stub_request 'HTTPS' => 'on'
assert request.ssl?
assert request.standard_port?

request = stub_request 'HTTP_HOST' => 'www.example.org:8080'
assert !request.ssl?
assert !request.standard_port?

request = stub_request 'HTTP_HOST' => 'www.example.org:8443', 'HTTPS' => 'on'
assert request.ssl?
assert !request.standard_port?
end

test "port string" do test "port string" do
request = stub_request 'HTTP_HOST' => 'www.example.org:80' request = stub_request 'HTTP_HOST' => 'www.example.org:80'
assert_equal "", request.port_string assert_equal "", request.port_string
Expand Down Expand Up @@ -223,6 +249,16 @@ class RequestTest < ActiveSupport::TestCase
assert request.ssl? assert request.ssl?
end end


test "scheme returns https when proxied" do
request = stub_request 'rack.url_scheme' => 'http'
assert !request.ssl?
assert_equal 'http', request.scheme

request = stub_request 'rack.url_scheme' => 'http', 'HTTP_X_FORWARDED_PROTO' => 'https'
assert request.ssl?
assert_equal 'https', request.scheme
end

test "String request methods" do test "String request methods" do
[:get, :post, :put, :delete].each do |method| [:get, :post, :put, :delete].each do |method|
request = stub_request 'REQUEST_METHOD' => method.to_s.upcase request = stub_request 'REQUEST_METHOD' => method.to_s.upcase
Expand Down
18 changes: 18 additions & 0 deletions actionpack/test/dispatch/routing_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def self.matches?(request)


match 'account/logout' => redirect("/logout"), :as => :logout_redirect match 'account/logout' => redirect("/logout"), :as => :logout_redirect
match 'account/login', :to => redirect("/login") match 'account/login', :to => redirect("/login")
match 'secure', :to => redirect("/secure/login")


constraints(lambda { |req| true }) do constraints(lambda { |req| true }) do
match 'account/overview' match 'account/overview'
Expand Down Expand Up @@ -2003,11 +2004,28 @@ def test_resources_path_can_be_a_symbol
end end
end end


def test_redirect_https
with_test_routes do
with_https do
get '/secure'
verify_redirect 'https://www.example.com/secure/login'
end
end
end

private private
def with_test_routes def with_test_routes
yield yield
end end


def with_https
old_https = https?
https!
yield
ensure
https!(old_https)
end

def verify_redirect(url, status=301) def verify_redirect(url, status=301)
assert_equal status, @response.status assert_equal status, @response.status
assert_equal url, @response.headers['Location'] assert_equal url, @response.headers['Location']
Expand Down

0 comments on commit 0d0fbf1

Please sign in to comment.