Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add URL with fragment to ClientResponse #2925

Merged
merged 5 commits into from
Apr 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/2925.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ClientResponse and RequestInfo now have real_url property, which is request url without fragment part being stripped
1 change: 0 additions & 1 deletion aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ async def _request(self, method, url, *,
"with AUTH argument or credentials "
"encoded in URL")

url = url.with_fragment(None)
cookies = self._cookie_jar.filter_cookies(url)

if proxy is not None:
Expand Down
17 changes: 14 additions & 3 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class RequestInfo:
url = attr.ib(type=URL)
method = attr.ib(type=str)
headers = attr.ib(type=CIMultiDictProxy)
real_url = attr.ib(type=URL)

@real_url.default
def real_url_default(self):
return self.url


class Fingerprint:
Expand Down Expand Up @@ -191,8 +196,8 @@ def __init__(self, method, url, *,
url2 = url.with_query(params)
q.extend(url2.query)
url = url.with_query(q)
self.url = url.with_fragment(None)
self.original_url = url
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this code before my commit looks strange to me:

        self.url = url.with_fragment(None)
        self.original_url = url

Both url and original_url are not modified after (at least by the object itself), so they are always the same.

And then original_url is passed as url for ClientResponse.

So, wasn't it actually intended to keep URL fragment in response object?

self.url = url.with_fragment(None)
self.method = method.upper()
self.chunked = chunked
self.compress = compress
Expand Down Expand Up @@ -244,7 +249,8 @@ def port(self):

@property
def request_info(self):
return RequestInfo(self.url, self.method, self.headers)
return RequestInfo(self.url, self.method,
self.headers, self.original_url)

def update_host(self, url):
"""Update destination host, port and connection type (ssl)."""
Expand Down Expand Up @@ -582,7 +588,8 @@ def __init__(self, method, url, *,
self.headers = None
self.cookies = SimpleCookie()

self._url = url
self._real_url = url
self._url = url.with_fragment(None)
self._body = None
self._writer = writer
self._continue = continue100 # None by default
Expand All @@ -608,6 +615,10 @@ def url_obj(self):
"Deprecated, use .url #1654", DeprecationWarning, stacklevel=2)
return self._url

@property
def real_url(self):
return self._real_url

@property
def host(self):
return self._url.host
Expand Down
12 changes: 12 additions & 0 deletions docs/client_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,12 @@ Response object

URL of request (:class:`~yarl.URL`).

.. attribute:: real_url

Unmodified URL of request (:class:`~yarl.URL`).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add .. versionadded:: 3.2 tag

.. versionadded:: 3.2

.. attribute:: connection

:class:`Connection` used for handling response.
Expand Down Expand Up @@ -1453,6 +1459,12 @@ RequestInfo

HTTP headers for request, :class:`multidict.CIMultiDict` instance.

.. attribute:: real_url

Requested *url* with URL fragment unstripped, :class:`yarl.URL` instance.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. versionadded:: 3.2

.. versionadded:: 3.2


BasicAuth
^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ unittest
Unittest
unix
unsets
unstripped
upstr
url
urldispatcher
Expand Down
8 changes: 8 additions & 0 deletions tests/test_client_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ def test_request_info(make_request):
req.headers)


def test_request_info_with_fragment(make_request):
req = make_request('get', 'http://python.org/#urlfragment')
assert req.request_info == aiohttp.RequestInfo(
URL('http://python.org/'),
'GET', req.headers,
URL('http://python.org/#urlfragment'))


def test_version_err(make_request):
with pytest.raises(ValueError):
make_request('get', 'http://python.org/', version='1.c')
Expand Down
15 changes: 15 additions & 0 deletions tests/test_client_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -1018,3 +1018,18 @@ def side_effect(*args, **kwargs):
trace.send_response_chunk_received.call_args ==
mock.call(response_body)
)


def test_response_real_url(loop, session):
url = URL('http://def-cl-resp.org/#urlfragment')
response = ClientResponse('get', url,
request_info=mock.Mock(),
writer=mock.Mock(),
continue100=None,
timer=TimerNoop(),
auto_decompress=True,
traces=[],
loop=loop,
session=session)
assert response.url == url.with_fragment(None)
assert response.real_url == url