Repository: libcloud Updated Branches: refs/heads/trunk ac9518cec -> ab59cf4a2
rename libcloud.httplib_ssl to libcloud.http since it has nothing to do with httplib anymore Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/18da5097 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/18da5097 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/18da5097 Branch: refs/heads/trunk Commit: 18da50976369000ea286e518f583df42ee3e61b7 Parents: ac9518c Author: Anthony Shaw <anthonys...@apache.org> Authored: Sun Apr 9 16:56:06 2017 +1000 Committer: Anthony Shaw <anthonys...@apache.org> Committed: Sun Apr 9 16:56:06 2017 +1000 ---------------------------------------------------------------------- docs/other/changes_in_2_0.rst | 4 +- libcloud/common/azure_arm.py | 2 +- libcloud/common/base.py | 2 +- libcloud/common/ovh.py | 2 +- libcloud/http.py | 299 ++++++++++++++++++++++++++ libcloud/httplib_ssl.py | 299 -------------------------- libcloud/test/test_http.py | 87 ++++++++ libcloud/test/test_httplib_ssl.py | 87 -------- libcloud/test/test_logging_connection.py | 2 +- libcloud/test/test_response_classes.py | 2 +- 10 files changed, 393 insertions(+), 393 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/docs/other/changes_in_2_0.rst ---------------------------------------------------------------------- diff --git a/docs/other/changes_in_2_0.rst b/docs/other/changes_in_2_0.rst index e6a3d23..4dc21b5 100644 --- a/docs/other/changes_in_2_0.rst +++ b/docs/other/changes_in_2_0.rst @@ -27,8 +27,8 @@ HTTP redirects are allowed by default in 2.0. To disable redirects, set this glo .. code-block:: Python - import libcloud.httplib_ssl - libcloud.httplib_ssl.ALLOW_REDIRECTS = False + import libcloud.http + libcloud.http.ALLOW_REDIRECTS = False HTTP/HTTPS Proxies ~~~~~~~~~~~~~~~~~~ http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/common/azure_arm.py ---------------------------------------------------------------------- diff --git a/libcloud/common/azure_arm.py b/libcloud/common/azure_arm.py index 7ad64dc..d8c07c1 100644 --- a/libcloud/common/azure_arm.py +++ b/libcloud/common/azure_arm.py @@ -23,7 +23,7 @@ import time from libcloud.common.base import (ConnectionUserAndKey, JsonResponse, RawResponse) -from libcloud.httplib_ssl import LibcloudConnection +from libcloud.http import LibcloudConnection from libcloud.utils.py3 import basestring, urlencode http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/common/base.py ---------------------------------------------------------------------- diff --git a/libcloud/common/base.py b/libcloud/common/base.py index ca510e7..9c5731e 100644 --- a/libcloud/common/base.py +++ b/libcloud/common/base.py @@ -44,7 +44,7 @@ from libcloud.utils.py3 import urlencode from libcloud.utils.misc import lowercase_keys, retry from libcloud.common.exceptions import exception_from_message from libcloud.common.types import LibcloudError, MalformedResponseError -from libcloud.httplib_ssl import LibcloudConnection, HttpLibResponseProxy +from libcloud.http import LibcloudConnection, HttpLibResponseProxy __all__ = [ 'RETRY_FAILED_HTTP_REQUESTS', http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/common/ovh.py ---------------------------------------------------------------------- diff --git a/libcloud/common/ovh.py b/libcloud/common/ovh.py index 0eae99b..029e66f 100644 --- a/libcloud/common/ovh.py +++ b/libcloud/common/ovh.py @@ -26,7 +26,7 @@ from libcloud.utils.py3 import httplib from libcloud.utils.connection import get_response_object from libcloud.common.types import InvalidCredsError from libcloud.common.base import ConnectionUserAndKey, JsonResponse -from libcloud.httplib_ssl import LibcloudConnection +from libcloud.http import LibcloudConnection __all__ = [ 'OvhResponse', http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/http.py ---------------------------------------------------------------------- diff --git a/libcloud/http.py b/libcloud/http.py new file mode 100644 index 0000000..e78d92c --- /dev/null +++ b/libcloud/http.py @@ -0,0 +1,299 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Subclass for httplib.HTTPSConnection with optional certificate name +verification, depending on libcloud.security settings. +""" + +import os +import warnings +import requests +from requests.adapters import HTTPAdapter +from requests.packages.urllib3.poolmanager import PoolManager + +import libcloud.security +from libcloud.utils.py3 import urlparse, PY3 + + +__all__ = [ + 'LibcloudBaseConnection', + 'LibcloudConnection' +] + +ALLOW_REDIRECTS = 1 + +HTTP_PROXY_ENV_VARIABLE_NAME = 'http_proxy' + + +class SignedHTTPSAdapter(HTTPAdapter): + def __init__(self, cert_file, key_file): + self.cert_file = cert_file + self.key_file = key_file + super(SignedHTTPSAdapter, self).__init__() + + def init_poolmanager(self, connections, maxsize, block=False): + self.poolmanager = PoolManager( + num_pools=connections, maxsize=maxsize, + block=block, + cert_file=self.cert_file, + key_file=self.key_file) + + +class LibcloudBaseConnection(object): + """ + Base connection class to inherit from. + + Note: This class should not be instantiated directly. + """ + + session = None + + proxy_scheme = None + proxy_host = None + proxy_port = None + + proxy_username = None + proxy_password = None + + http_proxy_used = False + + ca_cert = None + + def __init__(self): + self.session = requests.Session() + + def set_http_proxy(self, proxy_url): + """ + Set a HTTP proxy which will be used with this connection. + + :param proxy_url: Proxy URL (e.g. http://<hostname>:<port> without + authentication and + http://<username>:<password>@<hostname>:<port> for + basic auth authentication information. + :type proxy_url: ``str`` + """ + result = self._parse_proxy_url(proxy_url=proxy_url) + scheme = result[0] + host = result[1] + port = result[2] + username = result[3] + password = result[4] + + self.proxy_scheme = scheme + self.proxy_host = host + self.proxy_port = port + self.proxy_username = username + self.proxy_password = password + self.http_proxy_used = True + + self.session.proxies = { + self.proxy_scheme: proxy_url + } + + def _parse_proxy_url(self, proxy_url): + """ + Parse and validate a proxy URL. + + :param proxy_url: Proxy URL (e.g. http://hostname:3128) + :type proxy_url: ``str`` + + :rtype: ``tuple`` (``scheme``, ``hostname``, ``port``) + """ + parsed = urlparse.urlparse(proxy_url) + + if parsed.scheme != 'http': + raise ValueError('Only http proxies are supported') + + if not parsed.hostname or not parsed.port: + raise ValueError('proxy_url must be in the following format: ' + 'http://<proxy host>:<proxy port>') + + proxy_scheme = parsed.scheme + proxy_host, proxy_port = parsed.hostname, parsed.port + + netloc = parsed.netloc + + if '@' in netloc: + username_password = netloc.split('@', 1)[0] + split = username_password.split(':', 1) + + if len(split) < 2: + raise ValueError('URL is in an invalid format') + + proxy_username, proxy_password = split[0], split[1] + else: + proxy_username = None + proxy_password = None + + return (proxy_scheme, proxy_host, proxy_port, proxy_username, + proxy_password) + + def _setup_verify(self): + self.verify = libcloud.security.VERIFY_SSL_CERT + + def _setup_ca_cert(self): + if self.verify is False: + pass + else: + if isinstance(libcloud.security.CA_CERTS_PATH, list): + if len(libcloud.security.CA_CERTS_PATH) > 1: + warnings.warn('Only 1 certificate path is supported') + self.ca_cert = libcloud.security.CA_CERTS_PATH[0] + else: + self.ca_cert = libcloud.security.CA_CERTS_PATH + + def _setup_signing(self, cert_file=None, key_file=None): + """ + Setup request signing by mounting a signing + adapter to the session + """ + self.session.mount('https://', SignedHTTPSAdapter(cert_file, key_file)) + + +class LibcloudConnection(LibcloudBaseConnection): + timeout = None + host = None + response = None + + def __init__(self, host, port, secure=None, **kwargs): + scheme = 'https' if secure is not None and secure else 'http' + self.host = '{0}://{1}{2}'.format( + 'https' if port == 443 else scheme, + host, + ":{0}".format(port) if port not in (80, 443) else "" + ) + # Support for HTTP proxy + proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME, None) + proxy_url = kwargs.pop('proxy_url', proxy_url_env) + + self._setup_verify() + self._setup_ca_cert() + + LibcloudBaseConnection.__init__(self) + + if 'cert_file' in kwargs or 'key_file' in kwargs: + self._setup_signing(**kwargs) + + if proxy_url: + self.set_http_proxy(proxy_url=proxy_url) + self.session.timeout = kwargs.get('timeout', 60) + + @property + def verification(self): + """ + The option for SSL verification given to underlying requests + """ + return self.ca_cert if self.ca_cert is not None else self.verify + + def request(self, method, url, body=None, headers=None, raw=False, + stream=False): + url = urlparse.urljoin(self.host, url) + self.response = self.session.request( + method=method.lower(), + url=url, + data=body, + headers=headers, + allow_redirects=ALLOW_REDIRECTS, + stream=stream, + verify=self.verification + ) + + def prepared_request(self, method, url, body=None, + headers=None, raw=False, stream=False): + req = requests.Request(method, ''.join([self.host, url]), + data=body, headers=headers) + + prepped = self.session.prepare_request(req) + + prepped.body = body + + self.response = self.session.send( + prepped, + stream=raw, + verify=self.ca_cert if self.ca_cert is not None else self.verify) + + def getresponse(self): + return self.response + + def getheaders(self): + # urlib decoded response body, libcloud has a bug + # and will not check if content is gzipped, so let's + # remove headers indicating compressed content. + if 'content-encoding' in self.response.headers: + del self.response.headers['content-encoding'] + return self.response.headers + + @property + def status(self): + return self.response.status_code + + @property + def reason(self): + return None if self.response.status_code > 400 else self.response.text + + def connect(self): # pragma: no cover + pass + + def read(self): + return self.response.content + + def close(self): # pragma: no cover + # return connection back to pool + self.response.close() + + +class HttpLibResponseProxy(object): + """ + Provides a proxy pattern around the :class:`requests.Reponse` + object to a :class:`httplib.HTTPResponse` object + """ + def __init__(self, response): + self._response = response + + def read(self, amt=None): + return self._response.text + + def getheader(self, name, default=None): + """ + Get the contents of the header name, or default + if there is no matching header. + """ + if name in self._response.headers.keys(): + return self._response.headers[name] + else: + return default + + def getheaders(self): + """ + Return a list of (header, value) tuples. + """ + if PY3: + return list(self._response.headers.items()) + else: + return self._response.headers.items() + + @property + def status(self): + return self._response.status_code + + @property + def reason(self): + return self._response.reason + + @property + def version(self): + # requests doesn't expose this + return '11' http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/httplib_ssl.py ---------------------------------------------------------------------- diff --git a/libcloud/httplib_ssl.py b/libcloud/httplib_ssl.py deleted file mode 100644 index e78d92c..0000000 --- a/libcloud/httplib_ssl.py +++ /dev/null @@ -1,299 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Subclass for httplib.HTTPSConnection with optional certificate name -verification, depending on libcloud.security settings. -""" - -import os -import warnings -import requests -from requests.adapters import HTTPAdapter -from requests.packages.urllib3.poolmanager import PoolManager - -import libcloud.security -from libcloud.utils.py3 import urlparse, PY3 - - -__all__ = [ - 'LibcloudBaseConnection', - 'LibcloudConnection' -] - -ALLOW_REDIRECTS = 1 - -HTTP_PROXY_ENV_VARIABLE_NAME = 'http_proxy' - - -class SignedHTTPSAdapter(HTTPAdapter): - def __init__(self, cert_file, key_file): - self.cert_file = cert_file - self.key_file = key_file - super(SignedHTTPSAdapter, self).__init__() - - def init_poolmanager(self, connections, maxsize, block=False): - self.poolmanager = PoolManager( - num_pools=connections, maxsize=maxsize, - block=block, - cert_file=self.cert_file, - key_file=self.key_file) - - -class LibcloudBaseConnection(object): - """ - Base connection class to inherit from. - - Note: This class should not be instantiated directly. - """ - - session = None - - proxy_scheme = None - proxy_host = None - proxy_port = None - - proxy_username = None - proxy_password = None - - http_proxy_used = False - - ca_cert = None - - def __init__(self): - self.session = requests.Session() - - def set_http_proxy(self, proxy_url): - """ - Set a HTTP proxy which will be used with this connection. - - :param proxy_url: Proxy URL (e.g. http://<hostname>:<port> without - authentication and - http://<username>:<password>@<hostname>:<port> for - basic auth authentication information. - :type proxy_url: ``str`` - """ - result = self._parse_proxy_url(proxy_url=proxy_url) - scheme = result[0] - host = result[1] - port = result[2] - username = result[3] - password = result[4] - - self.proxy_scheme = scheme - self.proxy_host = host - self.proxy_port = port - self.proxy_username = username - self.proxy_password = password - self.http_proxy_used = True - - self.session.proxies = { - self.proxy_scheme: proxy_url - } - - def _parse_proxy_url(self, proxy_url): - """ - Parse and validate a proxy URL. - - :param proxy_url: Proxy URL (e.g. http://hostname:3128) - :type proxy_url: ``str`` - - :rtype: ``tuple`` (``scheme``, ``hostname``, ``port``) - """ - parsed = urlparse.urlparse(proxy_url) - - if parsed.scheme != 'http': - raise ValueError('Only http proxies are supported') - - if not parsed.hostname or not parsed.port: - raise ValueError('proxy_url must be in the following format: ' - 'http://<proxy host>:<proxy port>') - - proxy_scheme = parsed.scheme - proxy_host, proxy_port = parsed.hostname, parsed.port - - netloc = parsed.netloc - - if '@' in netloc: - username_password = netloc.split('@', 1)[0] - split = username_password.split(':', 1) - - if len(split) < 2: - raise ValueError('URL is in an invalid format') - - proxy_username, proxy_password = split[0], split[1] - else: - proxy_username = None - proxy_password = None - - return (proxy_scheme, proxy_host, proxy_port, proxy_username, - proxy_password) - - def _setup_verify(self): - self.verify = libcloud.security.VERIFY_SSL_CERT - - def _setup_ca_cert(self): - if self.verify is False: - pass - else: - if isinstance(libcloud.security.CA_CERTS_PATH, list): - if len(libcloud.security.CA_CERTS_PATH) > 1: - warnings.warn('Only 1 certificate path is supported') - self.ca_cert = libcloud.security.CA_CERTS_PATH[0] - else: - self.ca_cert = libcloud.security.CA_CERTS_PATH - - def _setup_signing(self, cert_file=None, key_file=None): - """ - Setup request signing by mounting a signing - adapter to the session - """ - self.session.mount('https://', SignedHTTPSAdapter(cert_file, key_file)) - - -class LibcloudConnection(LibcloudBaseConnection): - timeout = None - host = None - response = None - - def __init__(self, host, port, secure=None, **kwargs): - scheme = 'https' if secure is not None and secure else 'http' - self.host = '{0}://{1}{2}'.format( - 'https' if port == 443 else scheme, - host, - ":{0}".format(port) if port not in (80, 443) else "" - ) - # Support for HTTP proxy - proxy_url_env = os.environ.get(HTTP_PROXY_ENV_VARIABLE_NAME, None) - proxy_url = kwargs.pop('proxy_url', proxy_url_env) - - self._setup_verify() - self._setup_ca_cert() - - LibcloudBaseConnection.__init__(self) - - if 'cert_file' in kwargs or 'key_file' in kwargs: - self._setup_signing(**kwargs) - - if proxy_url: - self.set_http_proxy(proxy_url=proxy_url) - self.session.timeout = kwargs.get('timeout', 60) - - @property - def verification(self): - """ - The option for SSL verification given to underlying requests - """ - return self.ca_cert if self.ca_cert is not None else self.verify - - def request(self, method, url, body=None, headers=None, raw=False, - stream=False): - url = urlparse.urljoin(self.host, url) - self.response = self.session.request( - method=method.lower(), - url=url, - data=body, - headers=headers, - allow_redirects=ALLOW_REDIRECTS, - stream=stream, - verify=self.verification - ) - - def prepared_request(self, method, url, body=None, - headers=None, raw=False, stream=False): - req = requests.Request(method, ''.join([self.host, url]), - data=body, headers=headers) - - prepped = self.session.prepare_request(req) - - prepped.body = body - - self.response = self.session.send( - prepped, - stream=raw, - verify=self.ca_cert if self.ca_cert is not None else self.verify) - - def getresponse(self): - return self.response - - def getheaders(self): - # urlib decoded response body, libcloud has a bug - # and will not check if content is gzipped, so let's - # remove headers indicating compressed content. - if 'content-encoding' in self.response.headers: - del self.response.headers['content-encoding'] - return self.response.headers - - @property - def status(self): - return self.response.status_code - - @property - def reason(self): - return None if self.response.status_code > 400 else self.response.text - - def connect(self): # pragma: no cover - pass - - def read(self): - return self.response.content - - def close(self): # pragma: no cover - # return connection back to pool - self.response.close() - - -class HttpLibResponseProxy(object): - """ - Provides a proxy pattern around the :class:`requests.Reponse` - object to a :class:`httplib.HTTPResponse` object - """ - def __init__(self, response): - self._response = response - - def read(self, amt=None): - return self._response.text - - def getheader(self, name, default=None): - """ - Get the contents of the header name, or default - if there is no matching header. - """ - if name in self._response.headers.keys(): - return self._response.headers[name] - else: - return default - - def getheaders(self): - """ - Return a list of (header, value) tuples. - """ - if PY3: - return list(self._response.headers.items()) - else: - return self._response.headers.items() - - @property - def status(self): - return self._response.status_code - - @property - def reason(self): - return self._response.reason - - @property - def version(self): - # requests doesn't expose this - return '11' http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/test/test_http.py ---------------------------------------------------------------------- diff --git a/libcloud/test/test_http.py b/libcloud/test/test_http.py new file mode 100644 index 0000000..a64cad9 --- /dev/null +++ b/libcloud/test/test_http.py @@ -0,0 +1,87 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import sys +import os.path +from mock import patch + +import libcloud.security + +from libcloud.utils.py3 import reload +from libcloud.http import LibcloudConnection + +from libcloud.test import unittest + +ORIGINAL_CA_CERS_PATH = libcloud.security.CA_CERTS_PATH + + +class TestHttpLibSSLTests(unittest.TestCase): + + def setUp(self): + libcloud.security.VERIFY_SSL_CERT = False + libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH + self.httplib_object = LibcloudConnection('foo.bar', port=80) + + def test_custom_ca_path_using_env_var_doesnt_exist(self): + os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist' + + try: + reload(libcloud.security) + except ValueError: + e = sys.exc_info()[1] + msg = 'Certificate file /foo/doesnt/exist doesn\'t exist' + self.assertEqual(str(e), msg) + else: + self.fail('Exception was not thrown') + + def test_custom_ca_path_using_env_var_is_directory(self): + file_path = os.path.dirname(os.path.abspath(__file__)) + os.environ['SSL_CERT_FILE'] = file_path + + expected_msg = 'Certificate file can\'t be a directory' + self.assertRaisesRegexp(ValueError, expected_msg, + reload, libcloud.security) + + def test_custom_ca_path_using_env_var_exist(self): + # When setting a path we don't actually check that a valid CA file is + # provided. + # This happens later in the code in http.connect method + file_path = os.path.abspath(__file__) + os.environ['SSL_CERT_FILE'] = file_path + + reload(libcloud.security) + + self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path]) + + @patch('warnings.warn') + def test_setup_ca_cert(self, _): + # verify = False, _setup_ca_cert should be a no-op + self.httplib_object.verify = False + self.httplib_object._setup_ca_cert() + + self.assertEqual(self.httplib_object.ca_cert, None) + + # verify = True, a valid path is provided, self.ca_cert should be set to + # a valid path + self.httplib_object.verify = True + + libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] + self.httplib_object._setup_ca_cert() + + self.assertTrue(self.httplib_object.ca_cert is not None) + +if __name__ == '__main__': + sys.exit(unittest.main()) http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/test/test_httplib_ssl.py ---------------------------------------------------------------------- diff --git a/libcloud/test/test_httplib_ssl.py b/libcloud/test/test_httplib_ssl.py deleted file mode 100644 index 55c705e..0000000 --- a/libcloud/test/test_httplib_ssl.py +++ /dev/null @@ -1,87 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import sys -import os.path -from mock import patch - -import libcloud.security - -from libcloud.utils.py3 import reload -from libcloud.httplib_ssl import LibcloudConnection - -from libcloud.test import unittest - -ORIGINAL_CA_CERS_PATH = libcloud.security.CA_CERTS_PATH - - -class TestHttpLibSSLTests(unittest.TestCase): - - def setUp(self): - libcloud.security.VERIFY_SSL_CERT = False - libcloud.security.CA_CERTS_PATH = ORIGINAL_CA_CERS_PATH - self.httplib_object = LibcloudConnection('foo.bar', port=80) - - def test_custom_ca_path_using_env_var_doesnt_exist(self): - os.environ['SSL_CERT_FILE'] = '/foo/doesnt/exist' - - try: - reload(libcloud.security) - except ValueError: - e = sys.exc_info()[1] - msg = 'Certificate file /foo/doesnt/exist doesn\'t exist' - self.assertEqual(str(e), msg) - else: - self.fail('Exception was not thrown') - - def test_custom_ca_path_using_env_var_is_directory(self): - file_path = os.path.dirname(os.path.abspath(__file__)) - os.environ['SSL_CERT_FILE'] = file_path - - expected_msg = 'Certificate file can\'t be a directory' - self.assertRaisesRegexp(ValueError, expected_msg, - reload, libcloud.security) - - def test_custom_ca_path_using_env_var_exist(self): - # When setting a path we don't actually check that a valid CA file is - # provided. - # This happens later in the code in httplib_ssl.connect method - file_path = os.path.abspath(__file__) - os.environ['SSL_CERT_FILE'] = file_path - - reload(libcloud.security) - - self.assertEqual(libcloud.security.CA_CERTS_PATH, [file_path]) - - @patch('warnings.warn') - def test_setup_ca_cert(self, _): - # verify = False, _setup_ca_cert should be a no-op - self.httplib_object.verify = False - self.httplib_object._setup_ca_cert() - - self.assertEqual(self.httplib_object.ca_cert, None) - - # verify = True, a valid path is provided, self.ca_cert should be set to - # a valid path - self.httplib_object.verify = True - - libcloud.security.CA_CERTS_PATH = [os.path.abspath(__file__)] - self.httplib_object._setup_ca_cert() - - self.assertTrue(self.httplib_object.ca_cert is not None) - -if __name__ == '__main__': - sys.exit(unittest.main()) http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/test/test_logging_connection.py ---------------------------------------------------------------------- diff --git a/libcloud/test/test_logging_connection.py b/libcloud/test/test_logging_connection.py index 85c6547..781551b 100644 --- a/libcloud/test/test_logging_connection.py +++ b/libcloud/test/test_logging_connection.py @@ -21,7 +21,7 @@ import requests_mock import libcloud from libcloud.test import unittest from libcloud.common.base import Connection -from libcloud.httplib_ssl import LibcloudConnection +from libcloud.http import LibcloudConnection from libcloud.utils.loggingconnection import LoggingConnection http://git-wip-us.apache.org/repos/asf/libcloud/blob/18da5097/libcloud/test/test_response_classes.py ---------------------------------------------------------------------- diff --git a/libcloud/test/test_response_classes.py b/libcloud/test/test_response_classes.py index 3572bcb..8beff7e 100644 --- a/libcloud/test/test_response_classes.py +++ b/libcloud/test/test_response_classes.py @@ -21,7 +21,7 @@ import requests_mock from libcloud.common.base import XmlResponse, JsonResponse, Connection from libcloud.common.types import MalformedResponseError -from libcloud.httplib_ssl import LibcloudConnection +from libcloud.http import LibcloudConnection class ResponseClassesTests(unittest.TestCase):