summaryrefslogtreecommitdiffstats
path: root/Lib/urllib.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/urllib.py')
-rw-r--r--Lib/urllib.py101
1 files changed, 27 insertions, 74 deletions
diff --git a/Lib/urllib.py b/Lib/urllib.py
index d486bcc..c55dee8 100644
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -22,10 +22,11 @@ used to query various info about the object, if available.
(mimetools.Message objects are queried with the getheader() method.)
"""
-import socket
+import httplib
import os
-import time
+import socket
import sys
+import time
from urlparse import urljoin as basejoin
__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
@@ -268,9 +269,19 @@ class URLopener:
# Each method named open_<type> knows how to open that type of URL
- def open_http(self, url, data=None):
- """Use HTTP protocol."""
- import httplib
+ def _open_generic_http(self, connection_factory, url, data):
+ """Make an HTTP connection using connection_class.
+
+ This is an internal method that should be called from
+ open_http() or open_https().
+
+ Arguments:
+ - connection_factory should take a host name and return an
+ HTTPConnection instance.
+ - url is the url to retrieval or a host, relative-path pair.
+ - data is payload for a POST request or None.
+ """
+
user_passwd = None
proxy_passwd= None
if isinstance(url, str):
@@ -312,7 +323,7 @@ class URLopener:
auth = base64.b64encode(user_passwd).strip()
else:
auth = None
- http_conn = httplib.HTTPConnection(host)
+ http_conn = connection_factory(host)
# XXX We should fix urllib so that it works with HTTP/1.1.
http_conn._http_vsn = 10
http_conn._http_vsn_str = "HTTP/1.0"
@@ -347,6 +358,10 @@ class URLopener:
url, response.fp,
response.status, response.reason, response.msg, data)
+ def open_http(self, url, data=None):
+ """Use HTTP protocol."""
+ return self._open_generic_http(httplib.HTTPConnection, url, data)
+
def http_error(self, url, fp, errcode, errmsg, headers, data=None):
"""Handle http errors.
@@ -370,76 +385,14 @@ class URLopener:
raise IOError, ('http error', errcode, errmsg, headers)
if hasattr(socket, "ssl"):
+ def _https_connection(self, host):
+ return httplib.HTTPSConnection(host,
+ key_file=self.key_file,
+ cert_file=self.cert_file)
+
def open_https(self, url, data=None):
"""Use HTTPS protocol."""
- import httplib
- user_passwd = None
- proxy_passwd = None
- if isinstance(url, str):
- host, selector = splithost(url)
- if host:
- user_passwd, host = splituser(host)
- host = unquote(host)
- realhost = host
- else:
- host, selector = url
- # here, we determine, whether the proxy contains authorization information
- proxy_passwd, host = splituser(host)
- urltype, rest = splittype(selector)
- url = rest
- user_passwd = None
- if urltype.lower() != 'https':
- realhost = None
- else:
- realhost, rest = splithost(rest)
- if realhost:
- user_passwd, realhost = splituser(realhost)
- if user_passwd:
- selector = "%s://%s%s" % (urltype, realhost, rest)
- #print "proxy via https:", host, selector
- if not host: raise IOError, ('https error', 'no host given')
- if proxy_passwd:
- import base64
- proxy_auth = base64.b64encode(proxy_passwd).strip()
- else:
- proxy_auth = None
- if user_passwd:
- import base64
- auth = base64.b64encode(user_passwd).strip()
- else:
- auth = None
- h = httplib.HTTPS(host, 0,
- key_file=self.key_file,
- cert_file=self.cert_file)
- 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 auth: h.putheader('Authorization', 'Basic %s' % auth)
- if realhost: h.putheader('Host', realhost)
- for args in self.addheaders: h.putheader(*args)
- h.endheaders()
- if data is not None:
- h.send(data)
- errcode, errmsg, headers = h.getreply()
- fp = h.getfile()
- if errcode == -1:
- if fp: fp.close()
- # something went wrong with the HTTP status line
- raise IOError, ('http protocol error', 0,
- 'got a bad status line', None)
- if errcode == 200:
- return addinfourl(fp, headers, "https:" + url)
- else:
- if data is None:
- return self.http_error(url, fp, errcode, errmsg, headers)
- else:
- return self.http_error(url, fp, errcode, errmsg, headers,
- data)
+ return self._open_generic_http(self._https_connection, url, data)
def open_file(self, url):
"""Use local file or FTP depending on form of URL."""