diff options
| author | Ian Cordasco <ian.cordasco@rackspace.com> | 2014-12-08 15:28:04 -0600 |
|---|---|---|
| committer | Ian Cordasco <ian.cordasco@rackspace.com> | 2015-02-06 13:49:13 -0600 |
| commit | 7ee96cbe390b2492f8d837c93f33a8f5bebdb388 (patch) | |
| tree | 2e2f0c2ed31b7361e0399cc5cb3d254c0d1823ba /glanceclient/common/https.py | |
| parent | 521cc25a0aed5c2783830847baa09344efaaf817 (diff) | |
| download | python-glanceclient-7ee96cbe390b2492f8d837c93f33a8f5bebdb388.tar.gz | |
Register our own ConnectionPool without globals
Currently, on systems like Fedora and Debian, it is possible to import
urllib3 as well as requests.packages.urllib3. They functionally point to
the same code but sys.modules considers them to be separate items. When
downstream packagers unvendor urllib3 from requests, they also change
all the imports inside of the package. So if the code imports urllib3
from requests.packages.urllib3 and modifies globals in a submodule, that
will not be visible to requests since it has been rewritten to use
urllib3 (not requests.packages.urllib3). By handling this logic
ourselves, we can issue a release until upstream packages and requests
can fix this and cut a new release.
Change-Id: Ic77ce8a06d9d148a899b4b8695990fca8fdaefc5
Closes-bug: 1396550
Diffstat (limited to 'glanceclient/common/https.py')
| -rw-r--r-- | glanceclient/common/https.py | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/glanceclient/common/https.py b/glanceclient/common/https.py index 6baa6af..fc719e2 100644 --- a/glanceclient/common/https.py +++ b/glanceclient/common/https.py @@ -14,19 +14,18 @@ # under the License. import socket +import ssl import struct import OpenSSL from requests import adapters +from requests import compat try: from requests.packages.urllib3 import connectionpool - from requests.packages.urllib3 import poolmanager except ImportError: from urllib3 import connectionpool - from urllib3 import poolmanager import six -import ssl from glanceclient.common import utils @@ -70,19 +69,37 @@ class HTTPSAdapter(adapters.HTTPAdapter): one. """ - def __init__(self, *args, **kwargs): - # NOTE(flaper87): This line forces poolmanager to use - # glanceclient HTTPSConnection - classes_by_scheme = poolmanager.pool_classes_by_scheme - classes_by_scheme["glance+https"] = HTTPSConnectionPool - super(HTTPSAdapter, self).__init__(*args, **kwargs) - def request_url(self, request, proxies): # NOTE(flaper87): Make sure the url is encoded, otherwise # python's standard httplib will fail with a TypeError. url = super(HTTPSAdapter, self).request_url(request, proxies) return strutils.safe_encode(url) + def _create_glance_httpsconnectionpool(self, url): + kw = self.poolmanager.connection_kw + # Parse the url to get the scheme, host, and port + parsed = compat.urlparse(url) + # If there is no port specified, we should use the standard HTTPS port + port = parsed.port or 443 + pool = HTTPSConnectionPool(parsed.host, port, **kw) + + with self.poolmanager.pools.lock: + self.poolmanager.pools[(parsed.scheme, parsed.host, port)] = pool + + return pool + + def get_connection(self, url, proxies=None): + try: + return super(HTTPSAdapter, self).get_connection(url, proxies) + except KeyError: + # NOTE(sigamvirus24): This works around modifying a module global + # which fixes bug #1396550 + # The scheme is most likely glance+https but check anyway + if not url.startswith('glance+https://'): + raise + + return self._create_glance_httpsconnectionpool(url) + def cert_verify(self, conn, url, verify, cert): super(HTTPSAdapter, self).cert_verify(conn, url, verify, cert) conn.ca_certs = verify[0] |
