mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
Issue #7776: Fix ``Host:'' header and reconnection when using http.client.HTTPConnection.set_tunnel().
Patch by Nikolaus Rath.
This commit is contained in:
parent
b814057cda
commit
9da047b3a5
3 changed files with 100 additions and 26 deletions
|
@ -21,13 +21,15 @@ CACERT_svn_python_org = os.path.join(here, 'https_svn_python_org_root.pem')
|
|||
HOST = support.HOST
|
||||
|
||||
class FakeSocket:
|
||||
def __init__(self, text, fileclass=io.BytesIO):
|
||||
def __init__(self, text, fileclass=io.BytesIO, host=None, port=None):
|
||||
if isinstance(text, str):
|
||||
text = text.encode("ascii")
|
||||
self.text = text
|
||||
self.fileclass = fileclass
|
||||
self.data = b''
|
||||
self.sendall_calls = 0
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
||||
def sendall(self, data):
|
||||
self.sendall_calls += 1
|
||||
|
@ -38,6 +40,9 @@ class FakeSocket:
|
|||
raise client.UnimplementedFileMode()
|
||||
return self.fileclass(self.text)
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
class EPipeSocket(FakeSocket):
|
||||
|
||||
def __init__(self, text, pipe_trigger):
|
||||
|
@ -970,10 +975,51 @@ class HTTPResponseTest(TestCase):
|
|||
header = self.resp.getheader('No-Such-Header',default=42)
|
||||
self.assertEqual(header, 42)
|
||||
|
||||
class TunnelTests(TestCase):
|
||||
|
||||
def test_connect(self):
|
||||
response_text = (
|
||||
'HTTP/1.0 200 OK\r\n\r\n' # Reply to CONNECT
|
||||
'HTTP/1.1 200 OK\r\n' # Reply to HEAD
|
||||
'Content-Length: 42\r\n\r\n'
|
||||
)
|
||||
|
||||
def create_connection(address, timeout=None, source_address=None):
|
||||
return FakeSocket(response_text, host=address[0],
|
||||
port=address[1])
|
||||
|
||||
conn = client.HTTPConnection('proxy.com')
|
||||
conn._create_connection = create_connection
|
||||
|
||||
# Once connected, we shouldn't be able to tunnel anymore
|
||||
conn.connect()
|
||||
self.assertRaises(RuntimeError, conn.set_tunnel,
|
||||
'destination.com')
|
||||
|
||||
# But if we close the connection, we're good
|
||||
conn.close()
|
||||
conn.set_tunnel('destination.com')
|
||||
conn.request('HEAD', '/', '')
|
||||
|
||||
self.assertEqual(conn.sock.host, 'proxy.com')
|
||||
self.assertEqual(conn.sock.port, 80)
|
||||
self.assertTrue(b'CONNECT destination.com' in conn.sock.data)
|
||||
self.assertTrue(b'Host: destination.com' in conn.sock.data)
|
||||
|
||||
# This test should be removed when CONNECT gets the HTTP/1.1 blessing
|
||||
self.assertTrue(b'Host: proxy.com' not in conn.sock.data)
|
||||
|
||||
conn.close()
|
||||
conn.request('PUT', '/', '')
|
||||
self.assertEqual(conn.sock.host, 'proxy.com')
|
||||
self.assertEqual(conn.sock.port, 80)
|
||||
self.assertTrue(b'CONNECT destination.com' in conn.sock.data)
|
||||
self.assertTrue(b'Host: destination.com' in conn.sock.data)
|
||||
|
||||
def test_main(verbose=None):
|
||||
support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
|
||||
HTTPSTest, RequestBodyTest, SourceAddressTest,
|
||||
HTTPResponseTest)
|
||||
HTTPResponseTest, TunnelTests)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_main()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue