Skip to content
Closed
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8055b96
Copy of #2582, Added proxy parameters for ClientSession
RatanShreshtha Nov 22, 2018
d3416a3
Removed extra line from aiohttp/client.py and sorted CONTRIBUTORS.txt
RatanShreshtha Nov 23, 2018
f23b9ee
Fixed tests for session proxy.
RatanShreshtha Nov 23, 2018
19ccf12
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha Nov 24, 2018
5821bc0
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha Nov 24, 2018
5c37878
Fixed mypy errors
RatanShreshtha Nov 24, 2018
66c4ce7
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha Nov 25, 2018
8e79f99
Added proxy params in client session attrs
RatanShreshtha Nov 25, 2018
8c249e1
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha Dec 30, 2018
3defdef
Merge branch 'master' of https://github.com/aio-libs/aiohttp
Feb 24, 2019
dc2115c
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha Mar 22, 2019
1f11214
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
RatanShreshtha Mar 22, 2019
7370f8a
Resolved conflict and making tests pass.
RatanShreshtha Mar 22, 2019
0233316
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
RatanShreshtha Apr 4, 2019
e592dd6
Merge branch 'master' of https://github.com/aio-libs/aiohttp
Apr 15, 2019
578de43
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
Apr 15, 2019
9c75827
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha May 6, 2019
bcd94cf
Merge branch 'master' of https://github.com/aio-libs/aiohttp
May 9, 2019
36c2b1b
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
May 9, 2019
f1fba4d
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha May 13, 2019
1936e55
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
RatanShreshtha May 13, 2019
18d9dde
Merge branch 'master' of https://github.com/aio-libs/aiohttp
May 22, 2019
90333ca
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
May 22, 2019
4ee84d7
Merge branch 'master' of https://github.com/aio-libs/aiohttp
RatanShreshtha Jul 6, 2019
508541e
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
RatanShreshtha Jul 6, 2019
f266e15
Merge branch 'master' of https://github.com/aio-libs/aiohttp
Jul 29, 2019
d767587
Merge branch 'master' of github.com:RatanShreshtha/aiohttp
Jul 29, 2019
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/2580.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added proxy parameters for ClientSession.
4 changes: 3 additions & 1 deletion CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Eugene Chernyshov
Eugene Naydenov
Eugene Tolmachev
Evert Lammerts
Fan Yu
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Plz clean-up all unrelated changes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Should I squash all the changes ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Up to you. We'll use "Merge and squash" strategy on this PR anyway :)

FichteFoll
Frederik Gladhorn
Frederik Peter Aalund
Expand Down Expand Up @@ -192,6 +193,7 @@ Pepe Osca
Philipp A.
Pieter van Beek
Rafael Viotti
Ratan Kulshreshtha
Raúl Cumplido
Required Field
Robert Lu
Expand Down Expand Up @@ -262,4 +264,4 @@ Yuriy Shatrov
Yury Selivanov
Yusuke Tsutsumi
Марк Коренберг
Семён Марьясин
Семён Марьясин
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This change is unrelated. Fix your editor to preserve original EOF.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

24 changes: 21 additions & 3 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ class ClientSession:
'_timeout', '_raise_for_status', '_auto_decompress',
'_trust_env', '_default_headers', '_skip_auto_headers',
'_request_class', '_response_class',
'_ws_response_class', '_trace_configs')
'_ws_response_class', '_trace_configs', '_session_proxy',
'_session_proxy_auth', '_session_proxy_headers')

def __init__(self, *, connector: Optional[BaseConnector]=None,
loop: Optional[asyncio.AbstractEventLoop]=None,
Expand All @@ -194,7 +195,10 @@ def __init__(self, *, connector: Optional[BaseConnector]=None,
auto_decompress: bool=True,
trust_env: bool=False,
requote_redirect_url: bool=True,
trace_configs: Optional[List[TraceConfig]]=None) -> None:
trace_configs: Optional[List[TraceConfig]]=None,
proxy: Optional[StrOrURL]=None,
proxy_auth: Optional[BasicAuth]=None,
proxy_headers: Optional[LooseHeaders]=None) -> None:

if loop is None:
if connector is not None:
Expand Down Expand Up @@ -259,6 +263,10 @@ def __init__(self, *, connector: Optional[BaseConnector]=None,
self._trust_env = trust_env
self._requote_redirect_url = requote_redirect_url

self._session_proxy = proxy
self._session_proxy_auth = proxy_auth
self._session_proxy_headers = proxy_headers

# Convert to list of tuples
if headers:
headers = CIMultiDict(headers)
Expand Down Expand Up @@ -372,12 +380,22 @@ async def _request(
for i in skip_auto_headers:
skip_headers.add(istr(i))

if proxy is not None:
if proxy is not None and self._session_proxy is None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is the behavior if proxy is not None and self._session_proxy is not None?
I think passed proxy parameter should take precedence.

try:
proxy = URL(proxy)
except ValueError:
raise InvalidURL(proxy)

if proxy is None and self._session_proxy is not None:
try:
proxy = self._session_proxy
proxy_auth = self._session_proxy_auth
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

By this line you are overriding explicitly passed proxy_auth and proxy_headers arguments with session default ones.

I have no idea how to resolve the conflict properly but proposed behavior looks confusing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I am trying to use session proxy if proxy is not mentioned explicitly for a particular request.

proxy_headers = self._prepare_headers(
self._session_proxy_headers
)
except ValueError:
raise InvalidURL(proxy)

if timeout is sentinel:
real_timeout = self._timeout # type: ClientTimeout
else:
Expand Down
11 changes: 10 additions & 1 deletion docs/client_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ The client session supports the context manager protocol for self closing.
auto_decompress=True, \
requote_redirect_url=False, \
trust_env=False, \
trace_configs=None)
trace_configs=None, \
proxy=None, \
proxy_auth=None, \
proxy_headers=None)

The class for creating client sessions and making requests.

Expand Down Expand Up @@ -188,6 +191,12 @@ The client session supports the context manager protocol for self closing.
disabling. See :ref:`aiohttp-client-tracing-reference` for
more information.

:param proxy: Proxy url that you want to use with the session.

:param proxy_auth: Authentication credentials for proxy url that you want to use with the session.

:param proxy_headers: Proxy headers that you want to use with the session.

.. attribute:: closed

``True`` if the session has been closed, ``False`` otherwise.
Expand Down
120 changes: 120 additions & 0 deletions tests/test_proxy_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from unittest import mock

import pytest

import aiohttp
from aiohttp import web


@pytest.fixture
def proxy_test_server(aiohttp_raw_server, loop, monkeypatch):
"""Handle all proxy requests and imitate remote server response."""

_patch_ssl_transport(monkeypatch)

default_response = {'status': 200, 'headers': None, 'body': None}

proxy_mock = mock.Mock()

async def proxy_handler(request):
proxy_mock.request = request
proxy_mock.requests_list.append(request)

response = default_response.copy()
if isinstance(proxy_mock.return_value, dict):
response.update(proxy_mock.return_value)

headers = response['headers']
if not headers:
headers = {}

if request.method == 'CONNECT':
response['body'] = None

response['headers'] = headers

resp = web.Response(**response)
await resp.prepare(request)
await resp.write_eof()
return resp

async def proxy_server():
proxy_mock.request = None
proxy_mock.auth = None
proxy_mock.requests_list = []

server = await aiohttp_raw_server(proxy_handler)

proxy_mock.server = server
proxy_mock.url = server.make_url('/')

return proxy_mock

return proxy_server


@pytest.fixture()
def get_request(loop):
async def _request(method='GET', *, url, trust_env=False, **kwargs):
connector = aiohttp.TCPConnector(verify_ssl=False, loop=loop)
client = aiohttp.ClientSession(connector=connector,
trust_env=trust_env)
try:
resp = await client.request(method, url, **kwargs)
await resp.release()
return resp
finally:
await client.close()
return _request


def _patch_ssl_transport(monkeypatch) -> None:
"""Make ssl transport substitution to prevent ssl handshake."""
def _make_ssl_transport_dummy(self, rawsock, protocol, sslcontext,
waiter=None, **kwargs):
return self._make_socket_transport(rawsock, protocol, waiter,
extra=kwargs.get('extra'),
server=kwargs.get('server'))

monkeypatch.setattr(
"asyncio.selector_events.BaseSelectorEventLoop._make_ssl_transport",
_make_ssl_transport_dummy)


async def test_session_proxy_http(proxy_test_server, loop) -> None:
url = 'http://aiohttp.io/path'
proxy = await proxy_test_server()
proxy.return_value = dict(body=b'test')

conn = aiohttp.TCPConnector(loop=loop)
sess = aiohttp.ClientSession(connector=conn, loop=loop, proxy=proxy.url)

resp = await sess.get(url)
assert (await resp.read()) == b'test'


async def test_session_proxy_http_auth(proxy_test_server, loop) -> None:
url = 'http://aiohttp.io/path'
proxy = await proxy_test_server()

conn = aiohttp.TCPConnector(loop=loop)
sess = aiohttp.ClientSession(connector=conn, loop=loop, proxy=proxy.url)
await sess.get(url)
assert 'Authorization' not in proxy.request.headers
assert 'Proxy-Authorization' not in proxy.request.headers

conn = aiohttp.TCPConnector(loop=loop)
auth = aiohttp.BasicAuth('user', 'pass')
sess = aiohttp.ClientSession(connector=conn, loop=loop,
proxy_auth=auth, proxy=proxy.url)
await sess.get(url)
assert 'Authorization' not in proxy.request.headers
assert 'Proxy-Authorization' in proxy.request.headers

conn = aiohttp.TCPConnector(loop=loop)
auth = aiohttp.BasicAuth('user', 'pass')
sess = aiohttp.ClientSession(connector=conn, loop=loop,
auth=auth, proxy_auth=auth, proxy=proxy.url)
await sess.get(url)
assert 'Authorization' in proxy.request.headers
assert 'Proxy-Authorization' in proxy.request.headers