diff --git a/lib/mechanize/http/agent.rb b/lib/mechanize/http/agent.rb index 5b1b2266..9e433a3f 100644 --- a/lib/mechanize/http/agent.rb +++ b/lib/mechanize/http/agent.rb @@ -9,7 +9,8 @@ class Mechanize::HTTP::Agent - CREDENTIAL_HEADERS = ['Authorization', 'Cookie'] + CREDENTIAL_HEADERS = ['Authorization'] + COOKIE_HEADERS = ['Cookie'] POST_HEADERS = ['Content-Length', 'Content-MD5', 'Content-Type'] # :section: Headers @@ -998,10 +999,14 @@ def response_redirect(response, method, page, redirects, headers, end # Make sure we clear credential headers if being redirected to another site - if new_uri.host != page.uri.host - CREDENTIAL_HEADERS.each do |ch| - headers.delete_if { |h| h.casecmp?(ch) } + if new_uri.host == page.uri.host + if new_uri.port != page.uri.port + # https://datatracker.ietf.org/doc/html/rfc6265#section-8.5 + # cookies are OK to be shared across ports on the same host + CREDENTIAL_HEADERS.each { |ch| headers.delete_if { |h| h.casecmp?(ch) } } end + else + (COOKIE_HEADERS + CREDENTIAL_HEADERS).each { |ch| headers.delete_if { |h| h.casecmp?(ch) } } end fetch new_uri, redirect_method, headers, [], referer, redirects + 1 diff --git a/test/test_mechanize_http_agent.rb b/test/test_mechanize_http_agent.rb index bc8c0580..8a2681f5 100644 --- a/test/test_mechanize_http_agent.rb +++ b/test/test_mechanize_http_agent.rb @@ -1569,7 +1569,7 @@ def test_response_redirect_to_cross_site_with_credential refute_includes(headers.keys, "AUTHORIZATION") refute_includes(headers.keys, "cookie") - assert_match 'range|bytes=0-9999', page.body + assert_match("range|bytes=0-9999", page.body) refute_match("authorization|Basic xxx", page.body) refute_match("cookie|name=value", page.body) end @@ -1590,11 +1590,32 @@ def test_response_redirect_to_same_site_with_credential assert_includes(headers.keys, "AUTHORIZATION") assert_includes(headers.keys, "cookie") - assert_match 'range|bytes=0-9999', page.body + assert_match("range|bytes=0-9999", page.body) assert_match("authorization|Basic xxx", page.body) assert_match("cookie|name=value", page.body) end + def test_response_redirect_to_same_site_diff_port_with_credential + @agent.redirect_ok = true + + headers = { + 'Range' => 'bytes=0-9999', + 'AUTHORIZATION' => 'Basic xxx', + 'cookie' => 'name=value', + } + + page = html_page '' + page = @agent.response_redirect({ 'Location' => 'http://example:81/http_headers' }, :get, + page, 0, headers) + + refute_includes(headers.keys, "AUTHORIZATION") + assert_includes(headers.keys, "cookie") + + assert_match("range|bytes=0-9999", page.body) + refute_match("authorization|Basic xxx", page.body) + assert_match("cookie|name=value", page.body) + end + def test_response_redirect_not_ok @agent.redirect_ok = false