[Python-checkins] r74198 - in python/branches/py3k: Doc/library/http.client.rst Lib/http/client.py Lib/test/test_urllib2.py Lib/urllib/request.py Misc/NEWS
senthil.kumaran
python-checkins at python.org
Sat Jul 25 06:24:38 CEST 2009
Author: senthil.kumaran
Date: Sat Jul 25 06:24:38 2009
New Revision: 74198
Log:
Fixed Issue1424152 in Py3k: urllib2 fails with HTTPS over Proxy.
Modified:
python/branches/py3k/Doc/library/http.client.rst
python/branches/py3k/Lib/http/client.py
python/branches/py3k/Lib/test/test_urllib2.py
python/branches/py3k/Lib/urllib/request.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/http.client.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.client.rst (original)
+++ python/branches/py3k/Doc/library/http.client.rst Sat Jul 25 06:24:38 2009
@@ -386,6 +386,12 @@
.. versionadded:: 2.7
+.. method:: HTTPConnection.set_tunnel(host, port=None)
+
+ Set the host and the port for HTTP Connect Tunnelling. Normally used when it
+ is required to a HTTPS Connection through a proxy server.
+
+ .. versionadded:: 3.1
.. method:: HTTPConnection.connect()
Modified: python/branches/py3k/Lib/http/client.py
==============================================================================
--- python/branches/py3k/Lib/http/client.py (original)
+++ python/branches/py3k/Lib/http/client.py Sat Jul 25 06:24:38 2009
@@ -644,11 +644,17 @@
self.__response = None
self.__state = _CS_IDLE
self._method = None
+ self._tunnel_host = None
+ self._tunnel_port = None
self._set_hostport(host, port)
if strict is not None:
self.strict = strict
+ def set_tunnel(self, host, port=None):
+ self._tunnel_host = host
+ self._tunnel_port = port
+
def _set_hostport(self, host, port):
if port is None:
i = host.rfind(':')
@@ -669,10 +675,29 @@
def set_debuglevel(self, level):
self.debuglevel = level
+ def _tunnel(self):
+ self._set_hostport(self._tunnel_host, self._tunnel_port)
+ connect_str = "CONNECT %s:%d HTTP/1.0\r\n\r\n" %(self.host, self.port)
+ connect_bytes = connect_str.encode("ascii")
+ self.send(connect_bytes)
+ response = self.response_class(self.sock, strict = self.strict,
+ method= self._method)
+ (version, code, message) = response._read_status()
+ if code != 200:
+ self.close()
+ raise socket.error("Tunnel connection failed: %d %s" % (code,
+ message.strip()))
+ while True:
+ line = response.fp.readline()
+ if line == b'\r\n':
+ break
+
def connect(self):
"""Connect to the host and port specified in __init__."""
self.sock = socket.create_connection((self.host,self.port),
self.timeout)
+ if self._tunnel_host:
+ self._tunnel()
def close(self):
"""Close the connection to the HTTP server."""
@@ -1008,6 +1033,11 @@
sock = socket.create_connection((self.host, self.port),
self.timeout)
+
+ if self._tunnel_host:
+ self.sock = sock
+ self._tunnel()
+
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
Modified: python/branches/py3k/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2.py (original)
+++ python/branches/py3k/Lib/test/test_urllib2.py Sat Jul 25 06:24:38 2009
@@ -947,6 +947,23 @@
self.assertEqual([(handlers[0], "http_open")],
[tup[0:2] for tup in o.calls])
+ def test_proxy_https(self):
+ o = OpenerDirector()
+ ph = urllib.request.ProxyHandler(dict(https="proxy.example.com:3128"))
+ o.add_handler(ph)
+ meth_spec = [
+ [("https_open", "return response")]
+ ]
+ handlers = add_ordered_mock_handlers(o, meth_spec)
+
+ req = Request("https://www.example.com/")
+ self.assertEqual(req.get_host(), "www.example.com")
+ r = o.open(req)
+ self.assertEqual(req.get_host(), "proxy.example.com:3128")
+ self.assertEqual([(handlers[0], "https_open")],
+ [tup[0:2] for tup in o.calls])
+
+
def test_basic_auth(self, quote_char='"'):
opener = OpenerDirector()
password_manager = MockPasswordManager()
Modified: python/branches/py3k/Lib/urllib/request.py
==============================================================================
--- python/branches/py3k/Lib/urllib/request.py (original)
+++ python/branches/py3k/Lib/urllib/request.py Sat Jul 25 06:24:38 2009
@@ -163,6 +163,7 @@
self.full_url = unwrap(url)
self.data = data
self.headers = {}
+ self._tunnel_host = None
for key, value in headers.items():
self.add_header(key, value)
self.unredirected_hdrs = {}
@@ -218,8 +219,12 @@
# End deprecated methods
def set_proxy(self, host, type):
- self.host, self.type = host, type
- self.selector = self.full_url
+ if self.type == 'https' and not self._tunnel_host:
+ self._tunnel_host = self.host
+ else:
+ self.type= type
+ self.selector = self.full_url
+ self.host = host
def has_proxy(self):
return self.selector == self.full_url
@@ -659,7 +664,7 @@
req.add_header('Proxy-authorization', 'Basic ' + creds)
hostport = unquote(hostport)
req.set_proxy(hostport, proxy_type)
- if orig_type == proxy_type:
+ if orig_type == proxy_type or orig_type == 'https':
# let other handlers take care of it
return None
else:
@@ -1041,6 +1046,10 @@
# request.
headers["Connection"] = "close"
headers = dict((name.title(), val) for name, val in headers.items())
+
+ if req._tunnel_host:
+ h.set_tunnel(req._tunnel_host)
+
try:
h.request(req.get_method(), req.selector, req.data, headers)
r = h.getresponse() # an HTTPResponse instance
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Jul 25 06:24:38 2009
@@ -60,6 +60,9 @@
Library
-------
+- Issue #1424152: Fix for httplib, urllib2 to support SSL while working through
+ proxy. Original patch by Christopher Li, changes made by Senthil Kumaran
+
- Add importlib.abc.ExecutionLoader to represent the PEP 302 protocol for
loaders that allow for modules to be executed. Both importlib.abc.PyLoader
and PyPycLoader inherit from this class and provide implementations in
More information about the Python-checkins
mailing list