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

Proxy fix #1421

Merged
merged 4 commits into from
Nov 24, 2016
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
4 changes: 2 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ CHANGES

-

-
- Has functional tests for client proxy #1218

-
- Fix bugs with client proxy target path and proxy host with port #1413

-

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Sebastian Hüther
SeongSoo Cho
Sergey Ninua
Sergey Skripnick
Serhii Kostel
Simon Kennedy
Sin-Woo Bang
Stanislas Plum
Expand Down
16 changes: 13 additions & 3 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,19 @@ def write_bytes(self, request, reader):
self._writer = None

def send(self, writer, reader):
path = self.url.raw_path
if self.url.raw_query_string:
path += '?' + self.url.raw_query_string
# Specify request target:
# - CONNECT request must send authority form URI
# - not CONNECT proxy must send absolute form URI
# - most common is origin form URI
if self.method == hdrs.METH_CONNECT:
path = '{}:{}'.format(self.url.host, self.url.port)
elif self.proxy and not self.ssl:
path = str(self.url)
else:
path = self.url.raw_path
if self.url.raw_query_string:
path += '?' + self.url.raw_query_string

request = aiohttp.Request(writer, self.method, path,
self.version)

Expand Down
6 changes: 2 additions & 4 deletions aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ def _create_direct_connection(self, req):
def _create_proxy_connection(self, req):
proxy_req = ClientRequest(
hdrs.METH_GET, req.proxy,
headers={hdrs.HOST: req.host},
headers={hdrs.HOST: req.headers[hdrs.HOST]},
auth=req.proxy_auth,
loop=self._loop)
try:
Expand All @@ -644,8 +644,6 @@ def _create_proxy_connection(self, req):
except OSError as exc:
raise ProxyConnectionError(*exc.args) from exc

if not req.ssl:
req.path = str(req.url)
if hdrs.AUTHORIZATION in proxy_req.headers:
auth = proxy_req.headers[hdrs.AUTHORIZATION]
del proxy_req.headers[hdrs.AUTHORIZATION]
Expand All @@ -665,7 +663,7 @@ def _create_proxy_connection(self, req):
# to do this we must wrap raw socket into secure one
# asyncio handles this perfectly
proxy_req.method = hdrs.METH_CONNECT
proxy_req.path = '{}:{}'.format(req.host, req.port)
proxy_req.url = req.url
key = (req.host, req.port, req.ssl)
conn = Connection(self, key, proxy_req,
transport, proto, self._loop)
Expand Down
14 changes: 7 additions & 7 deletions tests/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_connect(self, ClientRequestMock):
tr, proto = mock.Mock(), mock.Mock()
self.loop.create_connection = make_mocked_coro((tr, proto))
conn = self.loop.run_until_complete(connector.connect(req))
self.assertEqual(req.path, 'http://www.python.org')
self.assertEqual(req.url, URL('http://www.python.org'))
self.assertIs(conn._transport, tr)
self.assertIs(conn._protocol, proto)

Expand Down Expand Up @@ -105,7 +105,7 @@ def test_auth(self, ClientRequestMock):
self.assertNotIn('PROXY-AUTHORIZATION', req.headers)
conn = self.loop.run_until_complete(connector.connect(req))

self.assertEqual(req.path, 'http://www.python.org')
self.assertEqual(req.url, URL('http://www.python.org'))
self.assertNotIn('AUTHORIZATION', req.headers)
self.assertIn('PROXY-AUTHORIZATION', req.headers)
self.assertNotIn('AUTHORIZATION', proxy_req.headers)
Expand Down Expand Up @@ -148,7 +148,7 @@ def test_auth_from_url(self, ClientRequestMock):
self.assertNotIn('PROXY-AUTHORIZATION', req.headers)
conn = self.loop.run_until_complete(connector.connect(req))

self.assertEqual(req.path, 'http://www.python.org')
self.assertEqual(req.url, URL('http://www.python.org'))
self.assertNotIn('AUTHORIZATION', req.headers)
self.assertIn('PROXY-AUTHORIZATION', req.headers)
self.assertNotIn('AUTHORIZATION', proxy_req.headers)
Expand Down Expand Up @@ -212,7 +212,7 @@ def test_https_connect(self, ClientRequestMock):

self.assertEqual(req.url.path, '/')
self.assertEqual(proxy_req.method, 'CONNECT')
self.assertEqual(proxy_req.path, 'www.python.org:443')
self.assertEqual(proxy_req.url, URL('https://www.python.org'))
tr.pause_reading.assert_called_once_with()
tr.get_extra_info.assert_called_with('socket', default=None)

Expand Down Expand Up @@ -341,7 +341,7 @@ def test_request_port(self, ClientRequestMock):
loop=self.loop,
)
self.loop.run_until_complete(connector._create_connection(req))
self.assertEqual(req.path, 'http://localhost:1234/path')
self.assertEqual(req.url, URL('http://localhost:1234/path'))

def test_proxy_auth_property(self):
req = aiohttp.ClientRequest(
Expand Down Expand Up @@ -393,7 +393,7 @@ def test_https_connect_pass_ssl_context(self, ClientRequestMock):

self.assertEqual(req.url.path, '/')
self.assertEqual(proxy_req.method, 'CONNECT')
self.assertEqual(proxy_req.path, 'www.python.org:443')
self.assertEqual(proxy_req.url, URL('https://www.python.org'))
tr.pause_reading.assert_called_once_with()
tr.get_extra_info.assert_called_with('socket', default=None)

Expand Down Expand Up @@ -494,7 +494,7 @@ def test_connect(self, ClientRequestMock):
tr, proto = mock.Mock(), mock.Mock()
self.loop.create_connection = make_mocked_coro((tr, proto))
conn = self.loop.run_until_complete(connector.connect(req))
self.assertEqual(req.path, 'http://www.python.org')
self.assertEqual(req.url, URL('http://www.python.org'))
self.assertIs(conn._transport, tr)
self.assertIs(conn._protocol, proto)

Expand Down
Loading