mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 06:46:15 +00:00
append previous url fragment on redirect
This commit is contained in:
@@ -123,6 +123,7 @@ class SessionRedirectMixin(object):
|
||||
hist = [] # keep track of history
|
||||
|
||||
url = self.get_redirect_target(resp)
|
||||
previous_fragment = urlparse(req.url).fragment
|
||||
while url:
|
||||
prepared_request = req.copy()
|
||||
|
||||
@@ -147,8 +148,12 @@ class SessionRedirectMixin(object):
|
||||
parsed_rurl = urlparse(resp.url)
|
||||
url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url)
|
||||
|
||||
# The scheme should be lower case...
|
||||
# Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
|
||||
parsed = urlparse(url)
|
||||
if parsed.fragment == '' and previous_fragment:
|
||||
parsed = parsed._replace(fragment=previous_fragment)
|
||||
elif parsed.fragment:
|
||||
previous_fragment = parsed.fragment
|
||||
url = parsed.geturl()
|
||||
|
||||
# Facilitate relative 'location' headers, as allowed by RFC 7231.
|
||||
|
||||
@@ -235,3 +235,75 @@ def test_redirect_rfc1808_to_non_ascii_location():
|
||||
assert r.url == u'{0}/{1}'.format(url, expected_path.decode('ascii'))
|
||||
|
||||
close_server.set()
|
||||
|
||||
def test_fragment_not_sent_with_request():
|
||||
"""Verify that the fragment portion of a URI isn't sent to the server."""
|
||||
def response_handler(sock):
|
||||
req = consume_socket_content(sock, timeout=0.5)
|
||||
sock.send(
|
||||
b'HTTP/1.1 200 OK\r\n'
|
||||
b'Content-Length: '+bytes(len(req))+b'\r\n'
|
||||
b'\r\n'+req
|
||||
)
|
||||
|
||||
close_server = threading.Event()
|
||||
server = Server(response_handler, wait_to_close_event=close_server)
|
||||
|
||||
with server as (host, port):
|
||||
url = 'http://{0}:{1}/path/to/thing/#view=edit&token=hunter2'.format(host, port)
|
||||
r = requests.get(url)
|
||||
raw_request = r.content
|
||||
|
||||
assert r.status_code == 200
|
||||
headers, body = raw_request.split(b'\r\n\r\n', 1)
|
||||
status_line, headers = headers.split(b'\r\n', 1)
|
||||
|
||||
assert status_line == b'GET /path/to/thing/ HTTP/1.1'
|
||||
for frag in (b'view', b'edit', b'token', b'hunter2'):
|
||||
assert frag not in headers
|
||||
assert frag not in body
|
||||
|
||||
close_server.set()
|
||||
|
||||
def test_fragment_update_on_redirect():
|
||||
"""Verify we only append previous fragment if one doesn't exist on new
|
||||
location. If a new fragment is encounterd in a Location header, it should
|
||||
be added to all subsequent requests.
|
||||
"""
|
||||
|
||||
def response_handler(sock):
|
||||
consume_socket_content(sock, timeout=0.5)
|
||||
sock.send(
|
||||
b'HTTP/1.1 302 FOUND\r\n'
|
||||
b'Content-Length: 0\r\n'
|
||||
b'Location: /get#relevant-section\r\n\r\n'
|
||||
)
|
||||
consume_socket_content(sock, timeout=0.5)
|
||||
sock.send(
|
||||
b'HTTP/1.1 302 FOUND\r\n'
|
||||
b'Content-Length: 0\r\n'
|
||||
b'Location: /final-url/\r\n\r\n'
|
||||
)
|
||||
consume_socket_content(sock, timeout=0.5)
|
||||
sock.send(
|
||||
b'HTTP/1.1 200 OK\r\n\r\n'
|
||||
)
|
||||
|
||||
close_server = threading.Event()
|
||||
server = Server(response_handler, wait_to_close_event=close_server)
|
||||
|
||||
with server as (host, port):
|
||||
url = 'http://{0}:{1}/path/to/thing/#view=edit&token=hunter2'.format(host, port)
|
||||
r = requests.get(url)
|
||||
raw_request = r.content
|
||||
|
||||
assert r.status_code == 200
|
||||
assert len(r.history) == 2
|
||||
assert r.history[0].request.url == url
|
||||
|
||||
# Verify we haven't overwritten the location with our previous fragment.
|
||||
assert r.history[1].request.url == 'http://{0}:{1}/get#relevant-section'.format(host, port)
|
||||
# Verify previous fragment is used and not the original.
|
||||
assert r.url == 'http://{0}:{1}/final-url/#relevant-section'.format(host, port)
|
||||
|
||||
close_server.set()
|
||||
|
||||
@@ -294,6 +294,14 @@ class TestRequests:
|
||||
for header in purged_headers:
|
||||
assert header not in next_resp.request.headers
|
||||
|
||||
def test_fragment_maintained_on_redirect(self, httpbin):
|
||||
fragment = "#view=edit&token=hunter2"
|
||||
r = requests.get(httpbin('redirect-to?url=get')+fragment)
|
||||
|
||||
assert len(r.history) > 0
|
||||
assert r.history[0].request.url == httpbin('redirect-to?url=get')+fragment
|
||||
assert r.url == httpbin('get')+fragment
|
||||
|
||||
def test_HTTP_200_OK_GET_WITH_PARAMS(self, httpbin):
|
||||
heads = {'User-agent': 'Mozilla/5.0'}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user