diff -r 8205e72b5cfc Lib/httplib.py --- a/Lib/httplib.py Fri Aug 02 10:01:46 2013 +0200 +++ b/Lib/httplib.py Thu Aug 08 13:09:14 2013 +0200 @@ -1087,6 +1087,7 @@ self.putheader = conn.putheader self.endheaders = conn.endheaders self.set_debuglevel = conn.set_debuglevel + self.set_tunnel = conn.set_tunnel conn._http_vsn = self._http_vsn conn._http_vsn_str = self._http_vsn_str diff -r 8205e72b5cfc Lib/urllib.py --- a/Lib/urllib.py Fri Aug 02 10:01:46 2013 +0200 +++ b/Lib/urllib.py Thu Aug 08 13:09:14 2013 +0200 @@ -188,7 +188,9 @@ urltype, url = splittype(fullurl) if not urltype: urltype = 'file' - if urltype in self.proxies: + realhost, rest = splithost(url) + if ((realhost is None or not proxy_bypass(realhost)) + and urltype in self.proxies): proxy = self.proxies[urltype] urltype, proxyhost = splittype(proxy) host, selector = splithost(proxyhost) @@ -290,9 +292,12 @@ def open_http(self, url, data=None): """Use HTTP protocol.""" import httplib + h = None + tunnelhost = None user_passwd = None proxy_passwd= None if isinstance(url, str): + urltype = 'http' host, selector = splithost(url) if host: user_passwd, host = splituser(host) @@ -305,17 +310,28 @@ # now we proceed with the url we want to obtain urltype, rest = splittype(selector) url = rest - user_passwd = None - if urltype.lower() != 'http': + if urltype not in ['http', 'https']: realhost = None - else: + elif urltype == 'http': realhost, rest = splithost(rest) if realhost: user_passwd, realhost = splituser(realhost) if user_passwd: selector = "%s://%s%s" % (urltype, realhost, rest) - if proxy_bypass(realhost): - host = realhost + elif urltype == 'https': + if _have_ssl: + realhost, selector = splithost(url) + if realhost: + user_passwd, realhost = splituser(realhost) + tunnelhost, tunnelport = splitnport(realhost, + httplib.HTTPS_PORT) + tunnelheaders = dict(self.addheaders) + else: + raise IOError, ('https error', 'no host given') + h = httplib.HTTPS(host) + else: + raise IOError, ('url error', 'invalid proxy for https', + host) #print "proxy via http:", host, selector if not host: raise IOError, ('http error', 'no host given') @@ -331,14 +347,20 @@ auth = base64.b64encode(user_passwd).strip() else: auth = None - h = httplib.HTTP(host) + if h is None: + h = httplib.HTTP(host) if data is not None: h.putrequest('POST', selector) h.putheader('Content-Type', 'application/x-www-form-urlencoded') h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) - if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) + if proxy_auth: + if tunnelhost: + tunnelheaders['Proxy-Authorization'] = 'Basic %s' % proxy_auth + else: + h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) + if tunnelhost: h.set_tunnel(tunnelhost, tunnelport, tunnelheaders) if auth: h.putheader('Authorization', 'Basic %s' % auth) if realhost: h.putheader('Host', realhost) for args in self.addheaders: h.putheader(*args) @@ -353,7 +375,7 @@ # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. if (200 <= errcode < 300): - return addinfourl(fp, headers, "http:" + url, errcode) + return addinfourl(fp, headers, urltype + ":" + url, errcode) else: if data is None: return self.http_error(url, fp, errcode, errmsg, headers) @@ -388,6 +410,7 @@ user_passwd = None proxy_passwd = None if isinstance(url, str): + urltype = 'https' host, selector = splithost(url) if host: user_passwd, host = splituser(host) @@ -399,15 +422,17 @@ proxy_passwd, host = splituser(host) urltype, rest = splittype(selector) url = rest - user_passwd = None - if urltype.lower() != 'https': + if urltype not in ['http', 'https']: realhost = None - else: + elif urltype == 'http': realhost, rest = splithost(rest) if realhost: user_passwd, realhost = splituser(realhost) if user_passwd: selector = "%s://%s%s" % (urltype, realhost, rest) + elif urltype == 'https': + raise IOError, ('url error', + 'httplib does not support SSL inside SSL') #print "proxy via https:", host, selector if not host: raise IOError, ('https error', 'no host given') if proxy_passwd: @@ -445,7 +470,7 @@ # According to RFC 2616, "2xx" code indicates that the client's # request was successfully received, understood, and accepted. if (200 <= errcode < 300): - return addinfourl(fp, headers, "https:" + url, errcode) + return addinfourl(fp, headers, urltype + ":" + url, errcode) else: if data is None: return self.http_error(url, fp, errcode, errmsg, headers)