Py3 compat for https downloader

This commit is contained in:
Kovid Goyal 2014-02-23 18:24:31 +05:30
parent 1e64794997
commit ec2567b580

View File

@ -6,11 +6,11 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3'
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
import ssl, socket, re, httplib
from urlparse import urlsplit
import ssl, socket, re
from contextlib import closing
from calibre import get_proxies
from calibre.constants import ispy3
class HTTPError(ValueError):
@ -21,12 +21,27 @@ class HTTPError(ValueError):
self.code = code
self.url = url
# Check certificate hostname {{{
# Implementation taken from python 3
class CertificateError(ValueError):
if ispy3:
from urllib.parse import urlparse
import http.client as httplib
class HTTPSConnection(httplib.HTTPSConnection):
def __init__(self, ssl_version, *args, **kwargs):
context = kwargs['context'] = ssl.SSLContext(ssl_version)
cf = kwargs.pop('cert_file')
context.load_verify_locations(cf)
context.verify_mode = ssl.CERT_REQUIRED
httplib.HTTPSConnection.__init__(self, *args, **kwargs)
else:
import httplib
from urlparse import urlsplit as urlparse
# Check certificate hostname {{{
# Implementation taken from python 3
class CertificateError(ValueError):
pass
def _dnsname_match(dn, hostname, max_wildcards=1):
def _dnsname_match(dn, hostname, max_wildcards=1):
"""Matching according to RFC 6125, section 6.4.3
http://tools.ietf.org/html/rfc6125#section-6.4.3
@ -75,7 +90,7 @@ def _dnsname_match(dn, hostname, max_wildcards=1):
pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
return pat.match(hostname)
def match_hostname(cert, hostname):
def match_hostname(cert, hostname):
"""Verify that *cert* (in decoded format as returned by
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
rules are followed, but IP addresses are not accepted for *hostname*.
@ -114,9 +129,9 @@ def match_hostname(cert, hostname):
else:
raise CertificateError("no appropriate commonName or "
"subjectAltName fields were found")
# }}}
# }}}
class HTTPSConnection(httplib.HTTPSConnection):
class HTTPSConnection(httplib.HTTPSConnection):
def __init__(self, ssl_version, *args, **kwargs):
httplib.HTTPSConnection.__init__(self, *args, **kwargs)
@ -146,7 +161,7 @@ def get_https_resource_securely(
if ssl_version is None:
ssl_version = ssl.PROTOCOL_TLSv1
cacerts = P(cacerts, allow_user_override=False)
p = urlsplit(url)
p = urlparse(url)
if p.scheme != 'https':
raise ValueError('URL scheme must be https, not %s' % p.scheme)