Currently the swiftclient logs sensitive info in headers when logging HTTP requests. This patch hides sensitive info in headers such as 'X-Auth-Token' in a similar way to swift itself (we add a 'reveal_sensitive_prefix' configuration to the client). With this patch, tokens are truncated by removing the specified number of characters, after which '...' is appended to the logged token to indicate that it has been redacted. Co-Authored-By: Li Cheng <shcli@cn.ibm.com> Co-Authored-By: Zack M. Davis <zdavis@swiftstack.com> Change-Id: I43dd7254f7281d4db59b286aa2145643c64e1705 Closes-bug: #1516692
		
			
				
	
	
		
			2576 lines
		
	
	
		
			107 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			2576 lines
		
	
	
		
			107 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Copyright (c) 2010-2012 OpenStack, LLC.
 | 
						|
#
 | 
						|
# Licensed 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 logging
 | 
						|
import mock
 | 
						|
import six
 | 
						|
import socket
 | 
						|
import string
 | 
						|
import testtools
 | 
						|
import warnings
 | 
						|
import tempfile
 | 
						|
from hashlib import md5
 | 
						|
from six import binary_type
 | 
						|
from six.moves.urllib.parse import urlparse
 | 
						|
 | 
						|
from .utils import (MockHttpTest, fake_get_auth_keystone, StubResponse,
 | 
						|
                    FakeKeystone, _make_fake_import_keystone_client)
 | 
						|
 | 
						|
from swiftclient.utils import EMPTY_ETAG
 | 
						|
from swiftclient import client as c
 | 
						|
import swiftclient.utils
 | 
						|
import swiftclient
 | 
						|
 | 
						|
 | 
						|
class TestClientException(testtools.TestCase):
 | 
						|
 | 
						|
    def test_is_exception(self):
 | 
						|
        self.assertTrue(issubclass(c.ClientException, Exception))
 | 
						|
 | 
						|
    def test_format(self):
 | 
						|
        exc = c.ClientException('something failed')
 | 
						|
        self.assertIn('something failed', str(exc))
 | 
						|
        test_kwargs = (
 | 
						|
            'scheme',
 | 
						|
            'host',
 | 
						|
            'port',
 | 
						|
            'path',
 | 
						|
            'query',
 | 
						|
            'status',
 | 
						|
            'reason',
 | 
						|
            'device',
 | 
						|
        )
 | 
						|
        for value in test_kwargs:
 | 
						|
            kwargs = {
 | 
						|
                'http_%s' % value: value,
 | 
						|
            }
 | 
						|
            exc = c.ClientException('test', **kwargs)
 | 
						|
            self.assertIn(value, str(exc))
 | 
						|
 | 
						|
 | 
						|
class MockHttpResponse(object):
 | 
						|
    def __init__(self, status=0, headers=None, verify=False):
 | 
						|
        self.status = status
 | 
						|
        self.status_code = status
 | 
						|
        self.reason = "OK"
 | 
						|
        self.buffer = []
 | 
						|
        self.requests_params = None
 | 
						|
        self.verify = verify
 | 
						|
        self.md5sum = md5()
 | 
						|
        self.headers = {'etag': '"%s"' % EMPTY_ETAG}
 | 
						|
        if headers:
 | 
						|
            self.headers.update(headers)
 | 
						|
        self.closed = False
 | 
						|
 | 
						|
        class Raw(object):
 | 
						|
            def __init__(self, headers):
 | 
						|
                self.headers = headers
 | 
						|
 | 
						|
            def read(self, **kw):
 | 
						|
                return ""
 | 
						|
 | 
						|
            def getheader(self, name, default):
 | 
						|
                return self.headers.get(name, default)
 | 
						|
 | 
						|
        self.raw = Raw(headers)
 | 
						|
 | 
						|
    def read(self):
 | 
						|
        return ""
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        self.closed = True
 | 
						|
 | 
						|
    def getheader(self, name, default):
 | 
						|
        return self.headers.get(name, default)
 | 
						|
 | 
						|
    def getheaders(self):
 | 
						|
        return dict(self.headers)
 | 
						|
 | 
						|
    def fake_response(self):
 | 
						|
        return self
 | 
						|
 | 
						|
    def _fake_request(self, *arg, **kwarg):
 | 
						|
        self.status = 200
 | 
						|
        self.requests_params = kwarg
 | 
						|
        if self.verify:
 | 
						|
            for chunk in kwarg['data']:
 | 
						|
                self.md5sum.update(chunk)
 | 
						|
 | 
						|
        # This simulate previous httplib implementation that would do a
 | 
						|
        # putrequest() and then use putheader() to send header.
 | 
						|
        for k, v in kwarg['headers'].items():
 | 
						|
            self.buffer.append((k, v))
 | 
						|
        return self.fake_response()
 | 
						|
 | 
						|
 | 
						|
class TestHttpHelpers(MockHttpTest):
 | 
						|
 | 
						|
    def test_quote(self):
 | 
						|
        value = b'bytes\xff'
 | 
						|
        self.assertEqual('bytes%FF', c.quote(value))
 | 
						|
        value = 'native string'
 | 
						|
        self.assertEqual('native%20string', c.quote(value))
 | 
						|
        value = u'unicode string'
 | 
						|
        self.assertEqual('unicode%20string', c.quote(value))
 | 
						|
        value = u'unicode:\xe9\u20ac'
 | 
						|
        self.assertEqual('unicode%3A%C3%A9%E2%82%AC', c.quote(value))
 | 
						|
 | 
						|
    def test_parse_header_string(self):
 | 
						|
        value = b'bytes'
 | 
						|
        self.assertEqual(u'bytes', c.parse_header_string(value))
 | 
						|
        value = u'unicode:\xe9\u20ac'
 | 
						|
        self.assertEqual(u'unicode:\xe9\u20ac', c.parse_header_string(value))
 | 
						|
        value = 'native%20string'
 | 
						|
        self.assertEqual(u'native string', c.parse_header_string(value))
 | 
						|
 | 
						|
        value = b'encoded%20bytes%E2%82%AC'
 | 
						|
        self.assertEqual(u'encoded bytes\u20ac', c.parse_header_string(value))
 | 
						|
        value = 'encoded%20unicode%E2%82%AC'
 | 
						|
        self.assertEqual(u'encoded unicode\u20ac',
 | 
						|
                         c.parse_header_string(value))
 | 
						|
 | 
						|
        value = b'bad%20bytes%ff%E2%82%AC'
 | 
						|
        self.assertEqual(u'bad%20bytes%ff%E2%82%AC',
 | 
						|
                         c.parse_header_string(value))
 | 
						|
        value = u'bad%20unicode%ff\u20ac'
 | 
						|
        self.assertEqual(u'bad%20unicode%ff\u20ac',
 | 
						|
                         c.parse_header_string(value))
 | 
						|
 | 
						|
        value = b'really%20bad\xffbytes'
 | 
						|
        self.assertEqual(u'really%2520bad%FFbytes',
 | 
						|
                         c.parse_header_string(value))
 | 
						|
 | 
						|
    def test_http_connection(self):
 | 
						|
        url = 'http://www.test.com'
 | 
						|
        _junk, conn = c.http_connection(url)
 | 
						|
        self.assertIs(type(conn), c.HTTPConnection)
 | 
						|
        url = 'https://www.test.com'
 | 
						|
        _junk, conn = c.http_connection(url)
 | 
						|
        self.assertIs(type(conn), c.HTTPConnection)
 | 
						|
        url = 'ftp://www.test.com'
 | 
						|
        self.assertRaises(c.ClientException, c.http_connection, url)
 | 
						|
 | 
						|
    def test_encode_meta_headers(self):
 | 
						|
        headers = {'abc': '123',
 | 
						|
                   u'x-container-meta-\u0394': '123',
 | 
						|
                   u'x-account-meta-\u0394': '123',
 | 
						|
                   u'x-object-meta-\u0394': '123'}
 | 
						|
 | 
						|
        r = swiftclient.encode_meta_headers(headers)
 | 
						|
 | 
						|
        self.assertEqual(len(headers), len(r))
 | 
						|
        # ensure non meta headers are not encoded
 | 
						|
        self.assertIs(type(r.get('abc')), binary_type)
 | 
						|
        del r['abc']
 | 
						|
 | 
						|
        for k, v in r.items():
 | 
						|
            self.assertIs(type(k), binary_type)
 | 
						|
            self.assertIs(type(v), binary_type)
 | 
						|
 | 
						|
    def test_set_user_agent_default(self):
 | 
						|
        _junk, conn = c.http_connection('http://www.example.com')
 | 
						|
        req_headers = {}
 | 
						|
 | 
						|
        def my_request_handler(*a, **kw):
 | 
						|
            req_headers.update(kw.get('headers', {}))
 | 
						|
        conn._request = my_request_handler
 | 
						|
 | 
						|
        # test the default
 | 
						|
        conn.request('GET', '/')
 | 
						|
        ua = req_headers.get('user-agent', 'XXX-MISSING-XXX')
 | 
						|
        self.assertTrue(ua.startswith('python-swiftclient-'))
 | 
						|
 | 
						|
    def test_set_user_agent_per_request_override(self):
 | 
						|
        _junk, conn = c.http_connection('http://www.example.com')
 | 
						|
        req_headers = {}
 | 
						|
 | 
						|
        def my_request_handler(*a, **kw):
 | 
						|
            req_headers.update(kw.get('headers', {}))
 | 
						|
        conn._request = my_request_handler
 | 
						|
 | 
						|
        # test if it's actually set
 | 
						|
        conn.request('GET', '/', headers={'User-Agent': 'Me'})
 | 
						|
        ua = req_headers.get('user-agent', 'XXX-MISSING-XXX')
 | 
						|
        self.assertEqual(ua, b'Me', req_headers)
 | 
						|
 | 
						|
    def test_set_user_agent_default_override(self):
 | 
						|
        _junk, conn = c.http_connection(
 | 
						|
            'http://www.example.com',
 | 
						|
            default_user_agent='a-new-default')
 | 
						|
        req_headers = {}
 | 
						|
 | 
						|
        def my_request_handler(*a, **kw):
 | 
						|
            req_headers.update(kw.get('headers', {}))
 | 
						|
        conn._request = my_request_handler
 | 
						|
 | 
						|
        # test setting a default
 | 
						|
        conn._request = my_request_handler
 | 
						|
        conn.request('GET', '/')
 | 
						|
        ua = req_headers.get('user-agent', 'XXX-MISSING-XXX')
 | 
						|
        self.assertEqual(ua, 'a-new-default')
 | 
						|
 | 
						|
 | 
						|
class TestGetAuth(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf')
 | 
						|
        self.assertIsNone(url)
 | 
						|
        self.assertIsNone(token)
 | 
						|
 | 
						|
    def test_invalid_auth(self):
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          'http://www.tests.com', 'asdf', 'asdf',
 | 
						|
                          auth_version="foo")
 | 
						|
 | 
						|
    def test_auth_v1(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200, auth_v1=True)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                auth_version="1.0")
 | 
						|
        self.assertEqual(url, 'storageURL')
 | 
						|
        self.assertEqual(token, 'someauthtoken')
 | 
						|
 | 
						|
    def test_auth_v1_insecure(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200, 200, auth_v1=True)
 | 
						|
        url, token = c.get_auth('http://www.test.com/invalid_cert',
 | 
						|
                                'asdf', 'asdf',
 | 
						|
                                auth_version='1.0',
 | 
						|
                                insecure=True)
 | 
						|
        self.assertEqual(url, 'storageURL')
 | 
						|
        self.assertEqual(token, 'someauthtoken')
 | 
						|
 | 
						|
        e = self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                              'http://www.test.com/invalid_cert',
 | 
						|
                              'asdf', 'asdf', auth_version='1.0')
 | 
						|
        # TODO: this test is really on validating the mock and not the
 | 
						|
        # the full plumbing into the requests's 'verify' option
 | 
						|
        self.assertIn('invalid_certificate', str(e))
 | 
						|
 | 
						|
    def test_auth_v1_timeout(self):
 | 
						|
        # this test has some overlap with
 | 
						|
        # TestConnection.test_timeout_passed_down but is required to check that
 | 
						|
        # get_auth does the right thing when it is not passed a timeout arg
 | 
						|
        orig_http_connection = c.http_connection
 | 
						|
        timeouts = []
 | 
						|
 | 
						|
        def fake_request_handler(*a, **kw):
 | 
						|
            if 'timeout' in kw:
 | 
						|
                timeouts.append(kw['timeout'])
 | 
						|
            else:
 | 
						|
                timeouts.append(None)
 | 
						|
            return MockHttpResponse(
 | 
						|
                status=200,
 | 
						|
                headers={
 | 
						|
                    'x-auth-token': 'a_token',
 | 
						|
                    'x-storage-url': 'http://files.example.com/v1/AUTH_user'})
 | 
						|
 | 
						|
        def fake_connection(*a, **kw):
 | 
						|
            url, conn = orig_http_connection(*a, **kw)
 | 
						|
            conn._request = fake_request_handler
 | 
						|
            return url, conn
 | 
						|
 | 
						|
        with mock.patch('swiftclient.client.http_connection', fake_connection):
 | 
						|
            c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                       auth_version="1.0", timeout=42.0)
 | 
						|
            c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                       auth_version="1.0", timeout=None)
 | 
						|
            c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                       auth_version="1.0")
 | 
						|
 | 
						|
        self.assertEqual(timeouts, [42.0, None, None])
 | 
						|
 | 
						|
    def test_auth_v2_timeout(self):
 | 
						|
        # this test has some overlap with
 | 
						|
        # TestConnection.test_timeout_passed_down but is required to check that
 | 
						|
        # get_auth does the right thing when it is not passed a timeout arg
 | 
						|
        fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
 | 
						|
        with mock.patch('swiftclient.client._import_keystone_client',
 | 
						|
                        _make_fake_import_keystone_client(fake_ks)):
 | 
						|
            c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                       os_options=dict(tenant_name='tenant'),
 | 
						|
                       auth_version="2.0", timeout=42.0)
 | 
						|
            c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                       os_options=dict(tenant_name='tenant'),
 | 
						|
                       auth_version="2.0", timeout=None)
 | 
						|
            c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                       os_options=dict(tenant_name='tenant'),
 | 
						|
                       auth_version="2.0")
 | 
						|
        self.assertEqual(3, len(fake_ks.calls))
 | 
						|
        timeouts = [call['timeout'] for call in fake_ks.calls]
 | 
						|
        self.assertEqual([42.0, None, None], timeouts)
 | 
						|
 | 
						|
    def test_auth_v2_with_tenant_name(self):
 | 
						|
        os_options = {'tenant_name': 'asdf'}
 | 
						|
        req_args = {'auth_version': '2.0'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options,
 | 
						|
                                                     required_kwargs=req_args)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_with_tenant_id(self):
 | 
						|
        os_options = {'tenant_id': 'asdf'}
 | 
						|
        req_args = {'auth_version': '2.0'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options,
 | 
						|
                                                     required_kwargs=req_args)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_with_project_name(self):
 | 
						|
        os_options = {'project_name': 'asdf'}
 | 
						|
        req_args = {'auth_version': '2.0'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options,
 | 
						|
                                                     required_kwargs=req_args)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_with_project_id(self):
 | 
						|
        os_options = {'project_id': 'asdf'}
 | 
						|
        req_args = {'auth_version': '2.0'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options,
 | 
						|
                                                     required_kwargs=req_args)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_no_tenant_name_or_tenant_id(self):
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone({})
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          'http://www.tests.com', 'asdf', 'asdf',
 | 
						|
                          os_options={},
 | 
						|
                          auth_version='2.0')
 | 
						|
 | 
						|
    def test_auth_v2_with_tenant_name_none_and_tenant_id_none(self):
 | 
						|
        os_options = {'tenant_name': None,
 | 
						|
                      'tenant_id': None}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options)
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          'http://www.tests.com', 'asdf', 'asdf',
 | 
						|
                          os_options=os_options,
 | 
						|
                          auth_version='2.0')
 | 
						|
 | 
						|
    def test_auth_v2_with_tenant_user_in_user(self):
 | 
						|
        tenant_option = {'tenant_name': 'foo'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(tenant_option)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf',
 | 
						|
                                os_options={},
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_tenant_name_no_os_options(self):
 | 
						|
        tenant_option = {'tenant_name': 'asdf'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(tenant_option)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                tenant_name='asdf',
 | 
						|
                                os_options={},
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_with_os_options(self):
 | 
						|
        os_options = {'service_type': 'object-store',
 | 
						|
                      'endpoint_type': 'internalURL',
 | 
						|
                      'tenant_name': 'asdf'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_with_tenant_user_in_user_no_os_options(self):
 | 
						|
        tenant_option = {'tenant_name': 'foo'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(tenant_option)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf',
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_with_os_region_name(self):
 | 
						|
        os_options = {'region_name': 'good-region',
 | 
						|
                      'tenant_name': 'asdf'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="2.0")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_auth_v2_no_endpoint(self):
 | 
						|
        os_options = {'region_name': 'unknown_region',
 | 
						|
                      'tenant_name': 'asdf'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(
 | 
						|
            os_options, c.ClientException)
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          'http://www.tests.com', 'asdf', 'asdf',
 | 
						|
                          os_options=os_options, auth_version='2.0')
 | 
						|
 | 
						|
    def test_auth_v2_ks_exception(self):
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(
 | 
						|
            {}, c.ClientException)
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          'http://www.tests.com', 'asdf', 'asdf',
 | 
						|
                          os_options={},
 | 
						|
                          auth_version='2.0')
 | 
						|
 | 
						|
    def test_auth_v2_cacert(self):
 | 
						|
        os_options = {'tenant_name': 'foo'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(
 | 
						|
            os_options, None)
 | 
						|
 | 
						|
        auth_url_secure = 'https://www.tests.com'
 | 
						|
        auth_url_insecure = 'https://www.tests.com/self-signed-certificate'
 | 
						|
 | 
						|
        url, token = c.get_auth(auth_url_secure, 'asdf', 'asdf',
 | 
						|
                                os_options=os_options, auth_version='2.0',
 | 
						|
                                insecure=False)
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
        url, token = c.get_auth(auth_url_insecure, 'asdf', 'asdf',
 | 
						|
                                os_options=os_options, auth_version='2.0',
 | 
						|
                                cacert='ca.pem', insecure=False)
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          auth_url_insecure, 'asdf', 'asdf',
 | 
						|
                          os_options=os_options, auth_version='2.0')
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          auth_url_insecure, 'asdf', 'asdf',
 | 
						|
                          os_options=os_options, auth_version='2.0',
 | 
						|
                          insecure=False)
 | 
						|
 | 
						|
    def test_auth_v2_insecure(self):
 | 
						|
        os_options = {'tenant_name': 'foo'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(
 | 
						|
            os_options, None)
 | 
						|
 | 
						|
        auth_url_secure = 'https://www.tests.com'
 | 
						|
        auth_url_insecure = 'https://www.tests.com/invalid-certificate'
 | 
						|
 | 
						|
        url, token = c.get_auth(auth_url_secure, 'asdf', 'asdf',
 | 
						|
                                os_options=os_options, auth_version='2.0')
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
        url, token = c.get_auth(auth_url_insecure, 'asdf', 'asdf',
 | 
						|
                                os_options=os_options, auth_version='2.0',
 | 
						|
                                insecure=True)
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          auth_url_insecure, 'asdf', 'asdf',
 | 
						|
                          os_options=os_options, auth_version='2.0')
 | 
						|
        self.assertRaises(c.ClientException, c.get_auth,
 | 
						|
                          auth_url_insecure, 'asdf', 'asdf',
 | 
						|
                          os_options=os_options, auth_version='2.0',
 | 
						|
                          insecure=False)
 | 
						|
 | 
						|
    def test_auth_v3_with_tenant_name(self):
 | 
						|
        # check the correct auth version is passed to get_auth_keystone
 | 
						|
        os_options = {'tenant_name': 'asdf'}
 | 
						|
        req_args = {'auth_version': '3'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options,
 | 
						|
                                                     required_kwargs=req_args)
 | 
						|
        url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                os_options=os_options,
 | 
						|
                                auth_version="3")
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
    def test_get_keystone_client_2_0(self):
 | 
						|
        # check the correct auth version is passed to get_auth_keystone
 | 
						|
        os_options = {'tenant_name': 'asdf'}
 | 
						|
        req_args = {'auth_version': '2.0'}
 | 
						|
        c.get_auth_keystone = fake_get_auth_keystone(os_options,
 | 
						|
                                                     required_kwargs=req_args)
 | 
						|
        url, token = c.get_keystoneclient_2_0('http://www.test.com', 'asdf',
 | 
						|
                                              'asdf', os_options=os_options)
 | 
						|
        self.assertTrue(url.startswith("http"))
 | 
						|
        self.assertTrue(token)
 | 
						|
 | 
						|
 | 
						|
class TestGetAccount(MockHttpTest):
 | 
						|
 | 
						|
    def test_no_content(self):
 | 
						|
        c.http_connection = self.fake_http_connection(204)
 | 
						|
        value = c.get_account('http://www.test.com/v1/acct', 'asdf')[1]
 | 
						|
        self.assertEqual(value, [])
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct?format=json', '', {
 | 
						|
                'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_marker(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&marker=marker")
 | 
						|
        c.get_account('http://www.test.com/v1/acct', 'asdf', marker='marker')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct?format=json&marker=marker', '', {
 | 
						|
                'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_limit(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&limit=10")
 | 
						|
        c.get_account('http://www.test.com/v1/acct', 'asdf', limit=10)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct?format=json&limit=10', '', {
 | 
						|
                'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_prefix(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&prefix=asdf/")
 | 
						|
        c.get_account('http://www.test.com/v1/acct', 'asdf', prefix='asdf/')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct?format=json&prefix=asdf/', '', {
 | 
						|
                'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_end_marker(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&end_marker=end_marker")
 | 
						|
        c.get_account('http://www.test.com/v1/acct', 'asdf',
 | 
						|
                      end_marker='end_marker')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct?format=json&end_marker=end_marker', '', {
 | 
						|
                'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestHeadAccount(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200, headers={
 | 
						|
            'x-account-meta-color': 'blue',
 | 
						|
        })
 | 
						|
        resp_headers = c.head_account('http://www.tests.com', 'asdf')
 | 
						|
        self.assertEqual(resp_headers['x-account-meta-color'], 'blue')
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', 'http://www.tests.com', '', {'x-auth-token': 'asdf'})
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        body = 'c' * 65
 | 
						|
        c.http_connection = self.fake_http_connection(500, body=body)
 | 
						|
        e = self.assertRaises(c.ClientException, c.head_account,
 | 
						|
                              'http://www.tests.com', 'asdf')
 | 
						|
        self.assertEqual(e.http_response_content, body)
 | 
						|
        self.assertEqual(e.http_status, 500)
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', 'http://www.tests.com', '', {'x-auth-token': 'asdf'})
 | 
						|
        ])
 | 
						|
        # TODO: this is a fairly brittle test of the __repr__ on the
 | 
						|
        # ClientException which should probably be in a targeted test
 | 
						|
        new_body = "[first 60 chars of response] " + body[0:60]
 | 
						|
        self.assertEqual(e.__str__()[-89:], new_body)
 | 
						|
 | 
						|
 | 
						|
class TestPostAccount(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200, headers={
 | 
						|
            'X-Account-Meta-Color': 'blue',
 | 
						|
        }, body='foo')
 | 
						|
        resp_headers, body = c.post_account(
 | 
						|
            'http://www.tests.com/path/to/account', 'asdf',
 | 
						|
            {'x-account-meta-shape': 'square'}, query_string='bar=baz',
 | 
						|
            data='some data')
 | 
						|
        self.assertEqual('blue', resp_headers.get('x-account-meta-color'))
 | 
						|
        self.assertEqual('foo', body)
 | 
						|
        self.assertRequests([
 | 
						|
            ('POST', 'http://www.tests.com/path/to/account?bar=baz',
 | 
						|
             'some data', {'x-auth-token': 'asdf',
 | 
						|
                           'x-account-meta-shape': 'square'})
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        body = 'c' * 65
 | 
						|
        c.http_connection = self.fake_http_connection(500, body=body)
 | 
						|
        e = self.assertRaises(c.ClientException, c.post_account,
 | 
						|
                              'http://www.tests.com', 'asdf', {})
 | 
						|
        self.assertEqual(e.http_response_content, body)
 | 
						|
        self.assertEqual(e.http_status, 500)
 | 
						|
        self.assertRequests([
 | 
						|
            ('POST', 'http://www.tests.com', None, {'x-auth-token': 'asdf'})
 | 
						|
        ])
 | 
						|
        # TODO: this is a fairly brittle test of the __repr__ on the
 | 
						|
        # ClientException which should probably be in a targeted test
 | 
						|
        new_body = "[first 60 chars of response] " + body[0:60]
 | 
						|
        self.assertEqual(e.__str__()[-89:], new_body)
 | 
						|
 | 
						|
 | 
						|
class TestGetContainer(MockHttpTest):
 | 
						|
 | 
						|
    def test_no_content(self):
 | 
						|
        c.http_connection = self.fake_http_connection(204)
 | 
						|
        value = c.get_container('http://www.test.com/v1/acct', 'token',
 | 
						|
                                'container')[1]
 | 
						|
        self.assertEqual(value, [])
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_marker(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&marker=marker")
 | 
						|
        c.get_container('http://www.test.com/v1/acct', 'token', 'container',
 | 
						|
                        marker='marker')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json&marker=marker', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_limit(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&limit=10")
 | 
						|
        c.get_container('http://www.test.com/v1/acct', 'token', 'container',
 | 
						|
                        limit=10)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json&limit=10', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_prefix(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&prefix=asdf/")
 | 
						|
        c.get_container('http://www.test.com/v1/acct', 'token', 'container',
 | 
						|
                        prefix='asdf/')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json&prefix=asdf/', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_delimiter(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&delimiter=/")
 | 
						|
        c.get_container('http://www.test.com/v1/acct', 'token', 'container',
 | 
						|
                        delimiter='/')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json&delimiter=/', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_end_marker(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&end_marker=end_marker")
 | 
						|
        c.get_container('http://www.test.com/v1/acct', 'token', 'container',
 | 
						|
                        end_marker='end_marker')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json&end_marker=end_marker',
 | 
						|
             '', {'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_param_path(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204,
 | 
						|
            query_string="format=json&path=asdf")
 | 
						|
        c.get_container('http://www.test.com/v1/acct', 'token', 'container',
 | 
						|
                        path='asdf')
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/acct/container?format=json&path=asdf', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_request_headers(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            204, query_string="format=json")
 | 
						|
        conn = c.http_connection('http://www.test.com')
 | 
						|
        headers = {'x-client-key': 'client key'}
 | 
						|
        c.get_container('url_is_irrelevant', 'TOKEN', 'container',
 | 
						|
                        http_conn=conn, headers=headers)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/container?format=json', '', {
 | 
						|
                'x-auth-token': 'TOKEN',
 | 
						|
                'x-client-key': 'client key',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestHeadContainer(MockHttpTest):
 | 
						|
 | 
						|
    def test_head_ok(self):
 | 
						|
        fake_conn = self.fake_http_connection(
 | 
						|
            200, headers={'x-container-meta-color': 'blue'})
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        new=fake_conn):
 | 
						|
            resp = c.head_container('https://example.com/v1/AUTH_test',
 | 
						|
                                    'token', 'container')
 | 
						|
        self.assertEqual(resp['x-container-meta-color'], 'blue')
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', 'https://example.com/v1/AUTH_test/container', '',
 | 
						|
             {'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        body = 'c' * 60
 | 
						|
        c.http_connection = self.fake_http_connection(500, body=body)
 | 
						|
        e = self.assertRaises(c.ClientException, c.head_container,
 | 
						|
                              'http://www.test.com', 'asdf', 'container')
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/container', '', {'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
        self.assertEqual(e.http_status, 500)
 | 
						|
        self.assertEqual(e.http_response_content, body)
 | 
						|
 | 
						|
 | 
						|
class TestPutContainer(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        value = c.put_container('http://www.test.com', 'token', 'container')
 | 
						|
        self.assertIsNone(value)
 | 
						|
        self.assertRequests([
 | 
						|
            ('PUT', '/container', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
                'content-length': '0'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        body = 'c' * 60
 | 
						|
        c.http_connection = self.fake_http_connection(500, body=body)
 | 
						|
        e = self.assertRaises(c.ClientException, c.put_container,
 | 
						|
                              'http://www.test.com', 'token', 'container')
 | 
						|
        self.assertEqual(e.http_response_content, body)
 | 
						|
        self.assertRequests([
 | 
						|
            ('PUT', '/container', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
                'content-length': '0'}),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestDeleteContainer(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        value = c.delete_container('http://www.test.com', 'token', 'container')
 | 
						|
        self.assertIsNone(value)
 | 
						|
        self.assertRequests([
 | 
						|
            ('DELETE', '/container', '', {
 | 
						|
                'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestGetObject(MockHttpTest):
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        c.http_connection = self.fake_http_connection(500)
 | 
						|
        self.assertRaises(c.ClientException, c.get_object,
 | 
						|
                          'http://www.test.com', 'asdf', 'asdf', 'asdf')
 | 
						|
 | 
						|
    def test_query_string(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200,
 | 
						|
                                                      query_string="hello=20")
 | 
						|
        c.get_object('http://www.test.com', 'asdf', 'asdf', 'asdf',
 | 
						|
                     query_string="hello=20")
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/asdf/asdf?hello=20', '', {
 | 
						|
                'x-auth-token': 'asdf'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_get_object_as_string(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200, body='abcde')
 | 
						|
        __, resp = c.get_object('http://storage.example.com', 'TOKEN',
 | 
						|
                                'container_name', 'object_name')
 | 
						|
        self.assertEqual(resp, 'abcde')
 | 
						|
 | 
						|
    def test_request_headers(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        conn = c.http_connection('http://www.test.com')
 | 
						|
        headers = {'Range': 'bytes=1-2'}
 | 
						|
        c.get_object('url_is_irrelevant', 'TOKEN', 'container', 'object',
 | 
						|
                     http_conn=conn, headers=headers)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/container/object', '', {
 | 
						|
                'x-auth-token': 'TOKEN',
 | 
						|
                'range': 'bytes=1-2',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_response_headers(self):
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            200, headers={'X-Utf-8-Header': b't%c3%a9st',
 | 
						|
                          'X-Non-Utf-8-Header': b'%ff',
 | 
						|
                          'X-Binary-Header': b'\xff'})
 | 
						|
        conn = c.http_connection('http://www.test.com')
 | 
						|
        headers, data = c.get_object('url_is_irrelevant', 'TOKEN',
 | 
						|
                                     'container', 'object', http_conn=conn)
 | 
						|
        self.assertEqual(u't\xe9st', headers.get('x-utf-8-header', ''))
 | 
						|
        self.assertEqual(u'%ff', headers.get('x-non-utf-8-header', ''))
 | 
						|
        self.assertEqual(u'%FF', headers.get('x-binary-header', ''))
 | 
						|
 | 
						|
    def test_chunk_size_read_method(self):
 | 
						|
        conn = c.Connection('http://auth.url/', 'some_user', 'some_key')
 | 
						|
        with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = ('http://auth.url/', 'tToken')
 | 
						|
            c.http_connection = self.fake_http_connection(200, body='abcde')
 | 
						|
            __, resp = conn.get_object('asdf', 'asdf', resp_chunk_size=3)
 | 
						|
            self.assertTrue(hasattr(resp, 'read'))
 | 
						|
            self.assertEqual(resp.read(3), 'abc')
 | 
						|
            self.assertEqual(resp.read(None), 'de')
 | 
						|
            self.assertEqual(resp.read(), '')
 | 
						|
 | 
						|
    def test_chunk_size_iter(self):
 | 
						|
        conn = c.Connection('http://auth.url/', 'some_user', 'some_key')
 | 
						|
        with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = ('http://auth.url/', 'tToken')
 | 
						|
            c.http_connection = self.fake_http_connection(200, body='abcde')
 | 
						|
            __, resp = conn.get_object('asdf', 'asdf', resp_chunk_size=3)
 | 
						|
            self.assertTrue(hasattr(resp, 'next'))
 | 
						|
            self.assertEqual(next(resp), 'abc')
 | 
						|
            self.assertEqual(next(resp), 'de')
 | 
						|
            self.assertRaises(StopIteration, next, resp)
 | 
						|
 | 
						|
    def test_chunk_size_read_and_iter(self):
 | 
						|
        conn = c.Connection('http://auth.url/', 'some_user', 'some_key')
 | 
						|
        with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = ('http://auth.url/', 'tToken')
 | 
						|
            c.http_connection = self.fake_http_connection(200, body='abcdef')
 | 
						|
            __, resp = conn.get_object('asdf', 'asdf', resp_chunk_size=2)
 | 
						|
            self.assertTrue(hasattr(resp, 'read'))
 | 
						|
            self.assertEqual(resp.read(3), 'abc')
 | 
						|
            self.assertEqual(next(resp), 'de')
 | 
						|
            self.assertEqual(resp.read(), 'f')
 | 
						|
            self.assertRaises(StopIteration, next, resp)
 | 
						|
            self.assertEqual(resp.read(), '')
 | 
						|
 | 
						|
    def test_chunk_size_iter_chunked_no_retry(self):
 | 
						|
        conn = c.Connection('http://auth.url/', 'some_user', 'some_key')
 | 
						|
        with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = ('http://auth.url/', 'tToken')
 | 
						|
            c.http_connection = self.fake_http_connection(
 | 
						|
                200, body='abcdef', headers={'Transfer-Encoding': 'chunked'})
 | 
						|
            __, resp = conn.get_object('asdf', 'asdf', resp_chunk_size=2)
 | 
						|
            self.assertEqual(next(resp), 'ab')
 | 
						|
            # simulate a dropped connection
 | 
						|
            resp.resp.read()
 | 
						|
            self.assertRaises(StopIteration, next, resp)
 | 
						|
 | 
						|
    def test_chunk_size_iter_retry(self):
 | 
						|
        conn = c.Connection('http://auth.url/', 'some_user', 'some_key')
 | 
						|
        with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = ('http://auth.url', 'tToken')
 | 
						|
            c.http_connection = self.fake_http_connection(
 | 
						|
                StubResponse(200, 'abcdef', {'etag': 'some etag',
 | 
						|
                                             'content-length': '6'}),
 | 
						|
                StubResponse(206, 'cdef', {'etag': 'some etag',
 | 
						|
                                           'content-length': '4'}),
 | 
						|
                StubResponse(206, 'ef', {'etag': 'some etag',
 | 
						|
                                         'content-length': '2'}),
 | 
						|
            )
 | 
						|
            __, resp = conn.get_object('asdf', 'asdf', resp_chunk_size=2)
 | 
						|
            self.assertEqual(next(resp), 'ab')
 | 
						|
            self.assertEqual(1, conn.attempts)
 | 
						|
            # simulate a dropped connection
 | 
						|
            resp.resp.read()
 | 
						|
            self.assertEqual(next(resp), 'cd')
 | 
						|
            self.assertEqual(2, conn.attempts)
 | 
						|
            # simulate a dropped connection
 | 
						|
            resp.resp.read()
 | 
						|
            self.assertEqual(next(resp), 'ef')
 | 
						|
            self.assertEqual(3, conn.attempts)
 | 
						|
            self.assertRaises(StopIteration, next, resp)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/asdf/asdf', '', {
 | 
						|
                'x-auth-token': 'tToken',
 | 
						|
            }),
 | 
						|
            ('GET', '/asdf/asdf', '', {
 | 
						|
                'range': 'bytes=2-',
 | 
						|
                'if-match': 'some etag',
 | 
						|
                'x-auth-token': 'tToken',
 | 
						|
            }),
 | 
						|
            ('GET', '/asdf/asdf', '', {
 | 
						|
                'range': 'bytes=4-',
 | 
						|
                'if-match': 'some etag',
 | 
						|
                'x-auth-token': 'tToken',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_get_object_with_resp_chunk_size_zero(self):
 | 
						|
        def get_connection(self):
 | 
						|
            def get_auth():
 | 
						|
                return 'http://auth.test.com', 'token'
 | 
						|
 | 
						|
            conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
 | 
						|
            self.assertIs(type(conn), c.Connection)
 | 
						|
            conn.get_auth = get_auth
 | 
						|
            self.assertEqual(conn.attempts, 0)
 | 
						|
            return conn
 | 
						|
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = get_connection(self)
 | 
						|
            conn.get_object('container1', 'obj1', resp_chunk_size=0)
 | 
						|
            self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
 | 
						|
class TestHeadObject(MockHttpTest):
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        c.http_connection = self.fake_http_connection(500)
 | 
						|
        self.assertRaises(c.ClientException, c.head_object,
 | 
						|
                          'http://www.test.com', 'asdf', 'asdf', 'asdf')
 | 
						|
 | 
						|
    def test_request_headers(self):
 | 
						|
        c.http_connection = self.fake_http_connection(204)
 | 
						|
        conn = c.http_connection('http://www.test.com')
 | 
						|
        headers = {'x-client-key': 'client key'}
 | 
						|
        c.head_object('url_is_irrelevant', 'TOKEN', 'container',
 | 
						|
                      'asdf', http_conn=conn, headers=headers)
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/container/asdf', '', {
 | 
						|
                'x-auth-token': 'TOKEN',
 | 
						|
                'x-client-key': 'client key',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestPutObject(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        args = ('http://www.test.com', 'TOKEN', 'container', 'obj', 'body', 4)
 | 
						|
        value = c.put_object(*args)
 | 
						|
        self.assertIsInstance(value, six.string_types)
 | 
						|
        self.assertEqual(value, EMPTY_ETAG)
 | 
						|
        self.assertRequests([
 | 
						|
            ('PUT', '/container/obj', 'body', {
 | 
						|
                'x-auth-token': 'TOKEN',
 | 
						|
                'content-length': '4',
 | 
						|
                'content-type': ''
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_unicode_ok(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        mock_file = six.StringIO(u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91')
 | 
						|
        args = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                mock_file)
 | 
						|
        text = u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
 | 
						|
        headers = {'X-Header1': text,
 | 
						|
                   'X-2': '1', 'X-3': "{'a': 'b'}", 'a-b': '.x:yz mn:fg:lp'}
 | 
						|
 | 
						|
        resp = MockHttpResponse()
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        value = c.put_object(*args, headers=headers, http_conn=conn)
 | 
						|
        self.assertIsInstance(value, six.string_types)
 | 
						|
        # Test for RFC-2616 encoded symbols
 | 
						|
        self.assertIn(("a-b", b".x:yz mn:fg:lp"),
 | 
						|
                      resp.buffer)
 | 
						|
        # Test unicode header
 | 
						|
        self.assertIn(('x-header1', text.encode('utf8')),
 | 
						|
                      resp.buffer)
 | 
						|
 | 
						|
    def test_chunk_warning(self):
 | 
						|
        conn = c.http_connection('http://www.test.com/')
 | 
						|
        mock_file = six.StringIO('asdf')
 | 
						|
        args = ('asdf', 'asdf', 'asdf', 'asdf', mock_file)
 | 
						|
        resp = MockHttpResponse()
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        with warnings.catch_warnings(record=True) as w:
 | 
						|
            c.put_object(*args, chunk_size=20, headers={}, http_conn=conn)
 | 
						|
            self.assertEqual(len(w), 0)
 | 
						|
 | 
						|
        body = 'c' * 60
 | 
						|
        c.http_connection = self.fake_http_connection(200, body=body)
 | 
						|
        args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf')
 | 
						|
        with warnings.catch_warnings(record=True) as w:
 | 
						|
            c.put_object(*args, chunk_size=20)
 | 
						|
            self.assertEqual(len(w), 1)
 | 
						|
            self.assertTrue(issubclass(w[-1].category, UserWarning))
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        body = 'c' * 60
 | 
						|
        c.http_connection = self.fake_http_connection(500, body=body)
 | 
						|
        args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf')
 | 
						|
        e = self.assertRaises(c.ClientException, c.put_object, *args)
 | 
						|
        self.assertEqual(e.http_response_content, body)
 | 
						|
        self.assertEqual(e.http_status, 500)
 | 
						|
        self.assertRequests([
 | 
						|
            ('PUT', '/asdf/asdf', 'asdf', {
 | 
						|
                'x-auth-token': 'asdf', 'content-type': ''}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_query_string(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200,
 | 
						|
                                                      query_string="hello=20")
 | 
						|
        c.put_object('http://www.test.com', 'asdf', 'asdf', 'asdf',
 | 
						|
                     query_string="hello=20")
 | 
						|
        for req in self.iter_request_log():
 | 
						|
            self.assertEqual(req['method'], 'PUT')
 | 
						|
            self.assertEqual(req['parsed_path'].path, '/asdf/asdf')
 | 
						|
            self.assertEqual(req['parsed_path'].query, 'hello=20')
 | 
						|
            self.assertEqual(req['headers']['x-auth-token'], 'asdf')
 | 
						|
 | 
						|
    def test_raw_upload(self):
 | 
						|
        # Raw upload happens when content_length is passed to put_object
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        resp = MockHttpResponse(status=200)
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        raw_data = b'asdf' * 256
 | 
						|
        raw_data_len = len(raw_data)
 | 
						|
 | 
						|
        for kwarg in ({'headers': {'Content-Length': str(raw_data_len)}},
 | 
						|
                      {'content_length': raw_data_len}):
 | 
						|
            with tempfile.TemporaryFile() as mock_file:
 | 
						|
                mock_file.write(raw_data)
 | 
						|
                mock_file.seek(0)
 | 
						|
 | 
						|
                c.put_object(url='http://www.test.com', http_conn=conn,
 | 
						|
                             contents=mock_file, **kwarg)
 | 
						|
 | 
						|
                req_data = resp.requests_params['data']
 | 
						|
                self.assertIs(type(req_data), swiftclient.utils.LengthWrapper)
 | 
						|
                self.assertEqual(raw_data_len, len(req_data.read()))
 | 
						|
 | 
						|
    def test_chunk_upload(self):
 | 
						|
        # Chunked upload happens when no content_length is passed to put_object
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        resp = MockHttpResponse(status=200)
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        raw_data = b'asdf' * 256
 | 
						|
        chunk_size = 16
 | 
						|
 | 
						|
        with tempfile.TemporaryFile() as mock_file:
 | 
						|
            mock_file.write(raw_data)
 | 
						|
            mock_file.seek(0)
 | 
						|
 | 
						|
            c.put_object(url='http://www.test.com', http_conn=conn,
 | 
						|
                         contents=mock_file, chunk_size=chunk_size)
 | 
						|
            req_data = resp.requests_params['data']
 | 
						|
            self.assertTrue(hasattr(req_data, '__iter__'))
 | 
						|
            data = b''
 | 
						|
            for chunk in req_data:
 | 
						|
                self.assertEqual(chunk_size, len(chunk))
 | 
						|
                data += chunk
 | 
						|
            self.assertEqual(data, raw_data)
 | 
						|
 | 
						|
    def test_iter_upload(self):
 | 
						|
        def data():
 | 
						|
            for chunk in ('foo', '', 'bar'):
 | 
						|
                yield chunk
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        resp = MockHttpResponse(status=200)
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
 | 
						|
        c.put_object(url='http://www.test.com', http_conn=conn,
 | 
						|
                     contents=data())
 | 
						|
        req_headers = resp.requests_params['headers']
 | 
						|
        self.assertNotIn('Content-Length', req_headers)
 | 
						|
        req_data = resp.requests_params['data']
 | 
						|
        self.assertTrue(hasattr(req_data, '__iter__'))
 | 
						|
        # If we emit an empty chunk, requests will go ahead and send it,
 | 
						|
        # causing the server to close the connection. So make sure we don't
 | 
						|
        # do that.
 | 
						|
        self.assertEqual(['foo', 'bar'], list(req_data))
 | 
						|
 | 
						|
    def test_md5_mismatch(self):
 | 
						|
        conn = c.http_connection('http://www.test.com')
 | 
						|
        resp = MockHttpResponse(status=200, verify=True,
 | 
						|
                                headers={'etag': '"badresponseetag"'})
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        raw_data = b'asdf' * 256
 | 
						|
        raw_data_md5 = md5(raw_data).hexdigest()
 | 
						|
        chunk_size = 16
 | 
						|
 | 
						|
        with tempfile.TemporaryFile() as mock_file:
 | 
						|
            mock_file.write(raw_data)
 | 
						|
            mock_file.seek(0)
 | 
						|
 | 
						|
            contents = swiftclient.utils.ReadableToIterable(mock_file,
 | 
						|
                                                            md5=True)
 | 
						|
 | 
						|
            etag = c.put_object(url='http://www.test.com',
 | 
						|
                                http_conn=conn,
 | 
						|
                                contents=contents,
 | 
						|
                                chunk_size=chunk_size)
 | 
						|
 | 
						|
            self.assertNotEqual(etag, contents.get_md5sum())
 | 
						|
            self.assertEqual(etag, 'badresponseetag')
 | 
						|
            self.assertEqual(raw_data_md5, contents.get_md5sum())
 | 
						|
 | 
						|
    def test_md5_match(self):
 | 
						|
        conn = c.http_connection('http://www.test.com')
 | 
						|
        raw_data = b'asdf' * 256
 | 
						|
        raw_data_md5 = md5(raw_data).hexdigest()
 | 
						|
        resp = MockHttpResponse(status=200, verify=True,
 | 
						|
                                headers={'etag': '"' + raw_data_md5 + '"'})
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        chunk_size = 16
 | 
						|
 | 
						|
        with tempfile.TemporaryFile() as mock_file:
 | 
						|
            mock_file.write(raw_data)
 | 
						|
            mock_file.seek(0)
 | 
						|
            contents = swiftclient.utils.ReadableToIterable(mock_file,
 | 
						|
                                                            md5=True)
 | 
						|
 | 
						|
            etag = c.put_object(url='http://www.test.com',
 | 
						|
                                http_conn=conn,
 | 
						|
                                contents=contents,
 | 
						|
                                chunk_size=chunk_size)
 | 
						|
 | 
						|
            self.assertEqual(raw_data_md5, contents.get_md5sum())
 | 
						|
            self.assertEqual(etag, contents.get_md5sum())
 | 
						|
 | 
						|
    def test_params(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        resp = MockHttpResponse(status=200)
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
 | 
						|
        c.put_object(url='http://www.test.com', http_conn=conn,
 | 
						|
                     etag='1234-5678', content_type='text/plain')
 | 
						|
        request_header = resp.requests_params['headers']
 | 
						|
        self.assertEqual(request_header['etag'], b'1234-5678')
 | 
						|
        self.assertEqual(request_header['content-type'], b'text/plain')
 | 
						|
 | 
						|
    def test_no_content_type(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        resp = MockHttpResponse(status=200)
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
 | 
						|
        c.put_object(url='http://www.test.com', http_conn=conn)
 | 
						|
        request_header = resp.requests_params['headers']
 | 
						|
        self.assertEqual(request_header['content-type'], b'')
 | 
						|
 | 
						|
    def test_content_type_in_headers(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        resp = MockHttpResponse(status=200)
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
 | 
						|
        # title-case header
 | 
						|
        hdrs = {'Content-Type': 'text/Plain'}
 | 
						|
        c.put_object(url='http://www.test.com', http_conn=conn, headers=hdrs)
 | 
						|
        request_header = resp.requests_params['headers']
 | 
						|
        self.assertEqual(request_header['content-type'], b'text/Plain')
 | 
						|
 | 
						|
        # method param overrides headers
 | 
						|
        c.put_object(url='http://www.test.com', http_conn=conn, headers=hdrs,
 | 
						|
                     content_type='image/jpeg')
 | 
						|
        request_header = resp.requests_params['headers']
 | 
						|
        self.assertEqual(request_header['content-type'], b'image/jpeg')
 | 
						|
 | 
						|
 | 
						|
class TestPostObject(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        args = ('http://www.test.com', 'token', 'container', 'obj',
 | 
						|
                {'X-Object-Meta-Test': 'mymeta'})
 | 
						|
        c.post_object(*args)
 | 
						|
        self.assertRequests([
 | 
						|
            ('POST', '/container/obj', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
                'X-Object-Meta-Test': 'mymeta'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_unicode_ok(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        args = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91',
 | 
						|
                u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91')
 | 
						|
        text = u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
 | 
						|
        headers = {'X-Header1': text,
 | 
						|
                   b'X-Header2': 'value',
 | 
						|
                   'X-2': '1', 'X-3': "{'a': 'b'}", 'a-b': '.x:yz mn:kl:qr',
 | 
						|
                   'X-Object-Meta-Header-not-encoded': text,
 | 
						|
                   b'X-Object-Meta-Header-encoded': 'value'}
 | 
						|
 | 
						|
        resp = MockHttpResponse()
 | 
						|
        conn[1].getresponse = resp.fake_response
 | 
						|
        conn[1]._request = resp._fake_request
 | 
						|
        c.post_object(*args, headers=headers, http_conn=conn)
 | 
						|
        # Test for RFC-2616 encoded symbols
 | 
						|
        self.assertIn(('a-b', b".x:yz mn:kl:qr"), resp.buffer)
 | 
						|
        # Test unicode header
 | 
						|
        self.assertIn(('x-header1', text.encode('utf8')),
 | 
						|
                      resp.buffer)
 | 
						|
        self.assertIn((b'x-object-meta-header-not-encoded',
 | 
						|
                      text.encode('utf8')), resp.buffer)
 | 
						|
        self.assertIn((b'x-object-meta-header-encoded', b'value'),
 | 
						|
                      resp.buffer)
 | 
						|
        self.assertIn((b'x-header2', b'value'), resp.buffer)
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        body = 'c' * 60
 | 
						|
        c.http_connection = self.fake_http_connection(500, body=body)
 | 
						|
        args = ('http://www.test.com', 'token', 'container', 'obj', {})
 | 
						|
        e = self.assertRaises(c.ClientException, c.post_object, *args)
 | 
						|
        self.assertEqual(e.http_response_content, body)
 | 
						|
        self.assertRequests([
 | 
						|
            ('POST', 'http://www.test.com/container/obj', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestDeleteObject(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        c.delete_object('http://www.test.com', 'token', 'container', 'obj')
 | 
						|
        self.assertRequests([
 | 
						|
            ('DELETE', 'http://www.test.com/container/obj', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        c.http_connection = self.fake_http_connection(500)
 | 
						|
        self.assertRaises(c.ClientException, c.delete_object,
 | 
						|
                          'http://www.test.com', 'asdf', 'asdf', 'asdf')
 | 
						|
 | 
						|
    def test_query_string(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200,
 | 
						|
                                                      query_string="hello=20")
 | 
						|
        c.delete_object('http://www.test.com', 'token', 'container', 'obj',
 | 
						|
                        query_string="hello=20")
 | 
						|
        self.assertRequests([
 | 
						|
            ('DELETE', 'http://www.test.com/container/obj?hello=20', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestGetCapabilities(MockHttpTest):
 | 
						|
 | 
						|
    def test_ok(self):
 | 
						|
        conn = self.fake_http_connection(200, body=b'{}')
 | 
						|
        http_conn = conn('http://www.test.com/info')
 | 
						|
        info = c.get_capabilities(http_conn)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/info', '', {}),
 | 
						|
        ])
 | 
						|
        self.assertEqual(info, {})
 | 
						|
        self.assertTrue(http_conn[1].resp.has_been_read)
 | 
						|
 | 
						|
    def test_server_error(self):
 | 
						|
        conn = self.fake_http_connection(500)
 | 
						|
        http_conn = conn('http://www.test.com/info')
 | 
						|
        self.assertRaises(c.ClientException, c.get_capabilities, http_conn)
 | 
						|
 | 
						|
    def test_conn_get_capabilities_with_auth(self):
 | 
						|
        auth_headers = {
 | 
						|
            'x-auth-token': 'token',
 | 
						|
            'x-storage-url': 'http://storage.example.com/v1/AUTH_test'
 | 
						|
        }
 | 
						|
        auth_v1_response = StubResponse(headers=auth_headers)
 | 
						|
        stub_info = {'swift': {'fake': True}}
 | 
						|
        info_response = StubResponse(body=b'{"swift":{"fake":true}}')
 | 
						|
        fake_conn = self.fake_http_connection(auth_v1_response, info_response)
 | 
						|
 | 
						|
        conn = c.Connection('http://auth.example.com/auth/v1.0',
 | 
						|
                            'user', 'key')
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        new=fake_conn):
 | 
						|
            info = conn.get_capabilities()
 | 
						|
        self.assertEqual(info, stub_info)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/auth/v1.0', '', {
 | 
						|
                'x-auth-user': 'user',
 | 
						|
                'x-auth-key': 'key'}),
 | 
						|
            ('GET', 'http://storage.example.com/info', '', {}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_conn_get_capabilities_with_os_auth(self):
 | 
						|
        fake_keystone = fake_get_auth_keystone(
 | 
						|
            storage_url='http://storage.example.com/v1/AUTH_test')
 | 
						|
        stub_info = {'swift': {'fake': True}}
 | 
						|
        info_response = StubResponse(body=b'{"swift":{"fake":true}}')
 | 
						|
        fake_conn = self.fake_http_connection(info_response)
 | 
						|
 | 
						|
        os_options = {'project_id': 'test'}
 | 
						|
        conn = c.Connection('http://keystone.example.com/v3.0',
 | 
						|
                            'user', 'key', os_options=os_options,
 | 
						|
                            auth_version=3)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 get_auth_keystone=fake_keystone,
 | 
						|
                                 http_connection=fake_conn):
 | 
						|
            info = conn.get_capabilities()
 | 
						|
        self.assertEqual(info, stub_info)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', 'http://storage.example.com/info'),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_conn_get_capabilities_with_url_param(self):
 | 
						|
        stub_info = {'swift': {'fake': True}}
 | 
						|
        info_response = StubResponse(body=b'{"swift":{"fake":true}}')
 | 
						|
        fake_conn = self.fake_http_connection(info_response)
 | 
						|
 | 
						|
        conn = c.Connection('http://auth.example.com/auth/v1.0',
 | 
						|
                            'user', 'key')
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        new=fake_conn):
 | 
						|
            info = conn.get_capabilities(
 | 
						|
                'http://other-storage.example.com/info')
 | 
						|
        self.assertEqual(info, stub_info)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', 'http://other-storage.example.com/info'),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_conn_get_capabilities_with_preauthurl_param(self):
 | 
						|
        stub_info = {'swift': {'fake': True}}
 | 
						|
        info_response = StubResponse(body=b'{"swift":{"fake":true}}')
 | 
						|
        fake_conn = self.fake_http_connection(info_response)
 | 
						|
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_test'
 | 
						|
        conn = c.Connection('http://auth.example.com/auth/v1.0',
 | 
						|
                            'user', 'key', preauthurl=storage_url)
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        new=fake_conn):
 | 
						|
            info = conn.get_capabilities()
 | 
						|
        self.assertEqual(info, stub_info)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', 'http://storage.example.com/info'),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_conn_get_capabilities_with_os_options(self):
 | 
						|
        stub_info = {'swift': {'fake': True}}
 | 
						|
        info_response = StubResponse(body=b'{"swift":{"fake":true}}')
 | 
						|
        fake_conn = self.fake_http_connection(info_response)
 | 
						|
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_test'
 | 
						|
        os_options = {
 | 
						|
            'project_id': 'test',
 | 
						|
            'object_storage_url': storage_url,
 | 
						|
        }
 | 
						|
        conn = c.Connection('http://keystone.example.com/v3.0',
 | 
						|
                            'user', 'key', os_options=os_options,
 | 
						|
                            auth_version=3)
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        new=fake_conn):
 | 
						|
            info = conn.get_capabilities()
 | 
						|
        self.assertEqual(info, stub_info)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', 'http://storage.example.com/info'),
 | 
						|
        ])
 | 
						|
 | 
						|
 | 
						|
class TestHTTPConnection(MockHttpTest):
 | 
						|
 | 
						|
    def test_bad_url_scheme(self):
 | 
						|
        url = u'www.test.com'
 | 
						|
        exc = self.assertRaises(c.ClientException, c.http_connection, url)
 | 
						|
        expected = u'Unsupported scheme "" in url "www.test.com"'
 | 
						|
        self.assertEqual(expected, str(exc))
 | 
						|
 | 
						|
        url = u'://www.test.com'
 | 
						|
        exc = self.assertRaises(c.ClientException, c.http_connection, url)
 | 
						|
        expected = u'Unsupported scheme "" in url "://www.test.com"'
 | 
						|
        self.assertEqual(expected, str(exc))
 | 
						|
 | 
						|
        url = u'blah://www.test.com'
 | 
						|
        exc = self.assertRaises(c.ClientException, c.http_connection, url)
 | 
						|
        expected = u'Unsupported scheme "blah" in url "blah://www.test.com"'
 | 
						|
        self.assertEqual(expected, str(exc))
 | 
						|
 | 
						|
    def test_ok_url_scheme(self):
 | 
						|
        for scheme in ('http', 'https', 'HTTP', 'HTTPS'):
 | 
						|
            url = u'%s://www.test.com' % scheme
 | 
						|
            parsed_url, conn = c.http_connection(url)
 | 
						|
            self.assertEqual(scheme.lower(), parsed_url.scheme)
 | 
						|
            self.assertEqual(u'%s://www.test.com' % scheme, conn.url)
 | 
						|
 | 
						|
    def test_ok_proxy(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/',
 | 
						|
                                 proxy='http://localhost:8080')
 | 
						|
        self.assertEqual(conn[1].requests_args['proxies']['http'],
 | 
						|
                         'http://localhost:8080')
 | 
						|
 | 
						|
    def test_bad_proxy(self):
 | 
						|
        try:
 | 
						|
            c.http_connection(u'http://www.test.com/', proxy='localhost:8080')
 | 
						|
        except c.ClientException as e:
 | 
						|
            self.assertEqual(e.msg, "Proxy's missing scheme")
 | 
						|
 | 
						|
    def test_cacert(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/',
 | 
						|
                                 cacert='/dev/urandom')
 | 
						|
        self.assertEqual(conn[1].requests_args['verify'], '/dev/urandom')
 | 
						|
 | 
						|
    def test_insecure(self):
 | 
						|
        conn = c.http_connection(u'http://www.test.com/', insecure=True)
 | 
						|
        self.assertEqual(conn[1].requests_args['verify'], False)
 | 
						|
 | 
						|
    def test_response_connection_released(self):
 | 
						|
        _parsed_url, conn = c.http_connection(u'http://www.test.com/')
 | 
						|
        conn.resp = MockHttpResponse()
 | 
						|
        conn.resp.raw = mock.Mock()
 | 
						|
        conn.resp.raw.read.side_effect = ["Chunk", ""]
 | 
						|
        resp = conn.getresponse()
 | 
						|
        self.assertFalse(resp.closed)
 | 
						|
        self.assertEqual("Chunk", resp.read())
 | 
						|
        self.assertFalse(resp.read())
 | 
						|
        self.assertTrue(resp.closed)
 | 
						|
 | 
						|
 | 
						|
class TestConnection(MockHttpTest):
 | 
						|
 | 
						|
    def test_instance(self):
 | 
						|
        conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
 | 
						|
        self.assertEqual(conn.retries, 5)
 | 
						|
 | 
						|
    def test_instance_kwargs(self):
 | 
						|
        args = {'user': 'ausername',
 | 
						|
                'key': 'secretpass',
 | 
						|
                'authurl': 'http://www.test.com',
 | 
						|
                'tenant_name': 'atenant'}
 | 
						|
        conn = c.Connection(**args)
 | 
						|
        self.assertEqual(type(conn), c.Connection)
 | 
						|
 | 
						|
    def test_instance_kwargs_token(self):
 | 
						|
        args = {'preauthtoken': 'atoken123',
 | 
						|
                'preauthurl': 'http://www.test.com:8080/v1/AUTH_123456'}
 | 
						|
        conn = c.Connection(**args)
 | 
						|
        self.assertEqual(conn.url, args['preauthurl'])
 | 
						|
        self.assertEqual(conn.token, args['preauthtoken'])
 | 
						|
 | 
						|
    def test_instance_kwargs_os_token(self):
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_test'
 | 
						|
        token = 'token'
 | 
						|
        args = {
 | 
						|
            'os_options': {
 | 
						|
                'object_storage_url': storage_url,
 | 
						|
                'auth_token': token,
 | 
						|
            }
 | 
						|
        }
 | 
						|
        conn = c.Connection(**args)
 | 
						|
        self.assertEqual(conn.url, storage_url)
 | 
						|
        self.assertEqual(conn.token, token)
 | 
						|
 | 
						|
    def test_instance_kwargs_token_precedence(self):
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_test'
 | 
						|
        token = 'token'
 | 
						|
        args = {
 | 
						|
            'preauthurl': storage_url,
 | 
						|
            'preauthtoken': token,
 | 
						|
            'os_options': {
 | 
						|
                'auth_token': 'less-specific-token',
 | 
						|
                'object_storage_url': 'less-specific-storage-url',
 | 
						|
            }
 | 
						|
        }
 | 
						|
        conn = c.Connection(**args)
 | 
						|
        self.assertEqual(conn.url, storage_url)
 | 
						|
        self.assertEqual(conn.token, token)
 | 
						|
 | 
						|
    def test_storage_url_override(self):
 | 
						|
        static_url = 'http://overridden.storage.url'
 | 
						|
        conn = c.Connection('http://auth.url/', 'some_user', 'some_key',
 | 
						|
                            os_options={
 | 
						|
                                'object_storage_url': static_url})
 | 
						|
        method_signatures = (
 | 
						|
            (conn.head_account, []),
 | 
						|
            (conn.get_account, []),
 | 
						|
            (conn.head_container, ('asdf',)),
 | 
						|
            (conn.get_container, ('asdf',)),
 | 
						|
            (conn.put_container, ('asdf',)),
 | 
						|
            (conn.delete_container, ('asdf',)),
 | 
						|
            (conn.head_object, ('asdf', 'asdf')),
 | 
						|
            (conn.get_object, ('asdf', 'asdf')),
 | 
						|
            (conn.put_object, ('asdf', 'asdf', 'asdf')),
 | 
						|
            (conn.post_object, ('asdf', 'asdf', {})),
 | 
						|
            (conn.delete_object, ('asdf', 'asdf')),
 | 
						|
        )
 | 
						|
 | 
						|
        with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = ('http://auth.storage.url', 'tToken')
 | 
						|
 | 
						|
            for method, args in method_signatures:
 | 
						|
                c.http_connection = self.fake_http_connection(
 | 
						|
                    200, body=b'[]', storage_url=static_url)
 | 
						|
                method(*args)
 | 
						|
                self.assertEqual(len(self.request_log), 1)
 | 
						|
                for request in self.iter_request_log():
 | 
						|
                    self.assertEqual(request['parsed_path'].netloc,
 | 
						|
                                     'overridden.storage.url')
 | 
						|
                    self.assertEqual(request['headers']['x-auth-token'],
 | 
						|
                                     'tToken')
 | 
						|
 | 
						|
    def test_get_capabilities(self):
 | 
						|
        conn = c.Connection()
 | 
						|
        with mock.patch('swiftclient.client.get_capabilities') as get_cap:
 | 
						|
            conn.get_capabilities('http://storage2.test.com')
 | 
						|
            parsed = get_cap.call_args[0][0][0]
 | 
						|
            self.assertEqual(parsed.path, '/info')
 | 
						|
            self.assertEqual(parsed.netloc, 'storage2.test.com')
 | 
						|
            conn.get_auth = lambda: ('http://storage.test.com/v1/AUTH_test',
 | 
						|
                                     'token')
 | 
						|
            conn.get_capabilities()
 | 
						|
            parsed = get_cap.call_args[0][0][0]
 | 
						|
            self.assertEqual(parsed.path, '/info')
 | 
						|
            self.assertEqual(parsed.netloc, 'storage.test.com')
 | 
						|
 | 
						|
    def test_retry(self):
 | 
						|
        def quick_sleep(*args):
 | 
						|
            pass
 | 
						|
        c.sleep = quick_sleep
 | 
						|
        conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
 | 
						|
        code_iter = [500] * (conn.retries + 1)
 | 
						|
        c.http_connection = self.fake_http_connection(*code_iter)
 | 
						|
 | 
						|
        self.assertRaises(c.ClientException, conn.head_account)
 | 
						|
        self.assertEqual(conn.attempts, conn.retries + 1)
 | 
						|
 | 
						|
    def test_retry_on_ratelimit(self):
 | 
						|
 | 
						|
        def quick_sleep(*args):
 | 
						|
            pass
 | 
						|
        c.sleep = quick_sleep
 | 
						|
 | 
						|
        # test retries
 | 
						|
        conn = c.Connection('http://www.test.com/auth/v1.0', 'asdf', 'asdf',
 | 
						|
                            retry_on_ratelimit=True)
 | 
						|
        code_iter = [200] + [498] * (conn.retries + 1)
 | 
						|
        auth_resp_headers = {
 | 
						|
            'x-auth-token': 'asdf',
 | 
						|
            'x-storage-url': 'http://storage/v1/test',
 | 
						|
        }
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            *code_iter, headers=auth_resp_headers)
 | 
						|
        e = self.assertRaises(c.ClientException, conn.head_account)
 | 
						|
        self.assertIn('Account HEAD failed', str(e))
 | 
						|
        self.assertEqual(conn.attempts, conn.retries + 1)
 | 
						|
 | 
						|
        # test default no-retry
 | 
						|
        c.http_connection = self.fake_http_connection(
 | 
						|
            200, 498,
 | 
						|
            headers=auth_resp_headers)
 | 
						|
        conn = c.Connection('http://www.test.com/auth/v1.0', 'asdf', 'asdf')
 | 
						|
        e = self.assertRaises(c.ClientException, conn.head_account)
 | 
						|
        self.assertIn('Account HEAD failed', str(e))
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_resp_read_on_server_error(self):
 | 
						|
        conn = c.Connection('http://www.test.com', 'asdf', 'asdf', retries=0)
 | 
						|
 | 
						|
        def get_auth(*args, **kwargs):
 | 
						|
            return 'http://www.new.com', 'new'
 | 
						|
        conn.get_auth = get_auth
 | 
						|
        self.url, self.token = conn.get_auth()
 | 
						|
 | 
						|
        method_signatures = (
 | 
						|
            (conn.head_account, []),
 | 
						|
            (conn.get_account, []),
 | 
						|
            (conn.head_container, ('asdf',)),
 | 
						|
            (conn.get_container, ('asdf',)),
 | 
						|
            (conn.put_container, ('asdf',)),
 | 
						|
            (conn.delete_container, ('asdf',)),
 | 
						|
            (conn.head_object, ('asdf', 'asdf')),
 | 
						|
            (conn.get_object, ('asdf', 'asdf')),
 | 
						|
            (conn.put_object, ('asdf', 'asdf', 'asdf')),
 | 
						|
            (conn.post_object, ('asdf', 'asdf', {})),
 | 
						|
            (conn.delete_object, ('asdf', 'asdf')),
 | 
						|
        )
 | 
						|
 | 
						|
        for method, args in method_signatures:
 | 
						|
            c.http_connection = self.fake_http_connection(500)
 | 
						|
            self.assertRaises(c.ClientException, method, *args)
 | 
						|
            requests = list(self.iter_request_log())
 | 
						|
            self.assertEqual(len(requests), 1)
 | 
						|
            for req in requests:
 | 
						|
                msg = '%s did not read resp on server error' % method.__name__
 | 
						|
                self.assertTrue(req['resp'].has_been_read, msg)
 | 
						|
 | 
						|
    def test_reauth(self):
 | 
						|
        c.http_connection = self.fake_http_connection(401, 200)
 | 
						|
 | 
						|
        def get_auth(*args, **kwargs):
 | 
						|
            # this mock, and by extension this test are not
 | 
						|
            # representative of the unit under test.  The real get_auth
 | 
						|
            # method will always return the os_option dict's
 | 
						|
            # object_storage_url which will be overridden by the
 | 
						|
            # preauthurl parameter to Connection if it is provided.
 | 
						|
            return 'http://www.new.com', 'new'
 | 
						|
 | 
						|
        def swap_sleep(*args):
 | 
						|
            self.swap_sleep_called = True
 | 
						|
            c.get_auth = get_auth
 | 
						|
        c.sleep = swap_sleep
 | 
						|
        self.swap_sleep_called = False
 | 
						|
 | 
						|
        conn = c.Connection('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                            preauthurl='http://www.old.com',
 | 
						|
                            preauthtoken='old',
 | 
						|
                            )
 | 
						|
 | 
						|
        self.assertEqual(conn.attempts, 0)
 | 
						|
        self.assertEqual(conn.url, 'http://www.old.com')
 | 
						|
        self.assertEqual(conn.token, 'old')
 | 
						|
 | 
						|
        conn.head_account()
 | 
						|
 | 
						|
        self.assertTrue(self.swap_sleep_called)
 | 
						|
        self.assertEqual(conn.attempts, 2)
 | 
						|
        self.assertEqual(conn.url, 'http://www.new.com')
 | 
						|
        self.assertEqual(conn.token, 'new')
 | 
						|
 | 
						|
    def test_reauth_preauth(self):
 | 
						|
        conn = c.Connection(
 | 
						|
            'http://auth.example.com', 'user', 'password',
 | 
						|
            preauthurl='http://storage.example.com/v1/AUTH_test',
 | 
						|
            preauthtoken='expired')
 | 
						|
        auth_v1_response = StubResponse(200, headers={
 | 
						|
            'x-auth-token': 'token',
 | 
						|
            'x-storage-url': 'http://storage.example.com/v1/AUTH_user',
 | 
						|
        })
 | 
						|
        fake_conn = self.fake_http_connection(401, auth_v1_response, 200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'expired'}),
 | 
						|
            ('GET', 'http://auth.example.com', '', {
 | 
						|
                'x-auth-user': 'user',
 | 
						|
                'x-auth-key': 'password'}),
 | 
						|
            ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_reauth_os_preauth(self):
 | 
						|
        os_preauth_options = {
 | 
						|
            'tenant_name': 'demo',
 | 
						|
            'object_storage_url': 'http://storage.example.com/v1/AUTH_test',
 | 
						|
            'auth_token': 'expired',
 | 
						|
        }
 | 
						|
        conn = c.Connection('http://auth.example.com', 'user', 'password',
 | 
						|
                            os_options=os_preauth_options, auth_version=2)
 | 
						|
        fake_keystone = fake_get_auth_keystone(os_preauth_options)
 | 
						|
        fake_conn = self.fake_http_connection(401, 200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 get_auth_keystone=fake_keystone,
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'expired'}),
 | 
						|
            ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_preauth_token_with_no_storage_url_requires_auth(self):
 | 
						|
        conn = c.Connection(
 | 
						|
            'http://auth.example.com', 'user', 'password',
 | 
						|
            preauthtoken='expired')
 | 
						|
        auth_v1_response = StubResponse(200, headers={
 | 
						|
            'x-auth-token': 'token',
 | 
						|
            'x-storage-url': 'http://storage.example.com/v1/AUTH_user',
 | 
						|
        })
 | 
						|
        fake_conn = self.fake_http_connection(auth_v1_response, 200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', 'http://auth.example.com', '', {
 | 
						|
                'x-auth-user': 'user',
 | 
						|
                'x-auth-key': 'password'}),
 | 
						|
            ('HEAD', '/v1/AUTH_user', '', {'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_os_preauth_token_with_no_storage_url_requires_auth(self):
 | 
						|
        os_preauth_options = {
 | 
						|
            'tenant_name': 'demo',
 | 
						|
            'auth_token': 'expired',
 | 
						|
        }
 | 
						|
        conn = c.Connection('http://auth.example.com', 'user', 'password',
 | 
						|
                            os_options=os_preauth_options, auth_version=2)
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_user'
 | 
						|
        fake_keystone = fake_get_auth_keystone(storage_url=storage_url)
 | 
						|
        fake_conn = self.fake_http_connection(200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 get_auth_keystone=fake_keystone,
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/AUTH_user', '', {'x-auth-token': 'token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_preauth_url_trumps_auth_url(self):
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_pre_url'
 | 
						|
        conn = c.Connection(
 | 
						|
            'http://auth.example.com', 'user', 'password',
 | 
						|
            preauthurl=storage_url)
 | 
						|
        auth_v1_response = StubResponse(200, headers={
 | 
						|
            'x-auth-token': 'post_token',
 | 
						|
            'x-storage-url': 'http://storage.example.com/v1/AUTH_post_url',
 | 
						|
        })
 | 
						|
        fake_conn = self.fake_http_connection(auth_v1_response, 200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', 'http://auth.example.com', '', {
 | 
						|
                'x-auth-user': 'user',
 | 
						|
                'x-auth-key': 'password'}),
 | 
						|
            ('HEAD', '/v1/AUTH_pre_url', '', {'x-auth-token': 'post_token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_os_preauth_url_trumps_auth_url(self):
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_pre_url'
 | 
						|
        os_preauth_options = {
 | 
						|
            'tenant_name': 'demo',
 | 
						|
            'object_storage_url': storage_url,
 | 
						|
        }
 | 
						|
        conn = c.Connection('http://auth.example.com', 'user', 'password',
 | 
						|
                            os_options=os_preauth_options, auth_version=2)
 | 
						|
        fake_keystone = fake_get_auth_keystone(
 | 
						|
            storage_url='http://storage.example.com/v1/AUTH_post_url',
 | 
						|
            token='post_token')
 | 
						|
        fake_conn = self.fake_http_connection(200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 get_auth_keystone=fake_keystone,
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/AUTH_pre_url', '', {'x-auth-token': 'post_token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
    def test_preauth_url_trumps_os_preauth_url(self):
 | 
						|
        storage_url = 'http://storage.example.com/v1/AUTH_pre_url'
 | 
						|
        os_storage_url = 'http://storage.example.com/v1/AUTH_os_pre_url'
 | 
						|
        os_preauth_options = {
 | 
						|
            'tenant_name': 'demo',
 | 
						|
            'object_storage_url': os_storage_url,
 | 
						|
        }
 | 
						|
        orig_os_preauth_options = dict(os_preauth_options)
 | 
						|
        conn = c.Connection('http://auth.example.com', 'user', 'password',
 | 
						|
                            os_options=os_preauth_options, auth_version=2,
 | 
						|
                            preauthurl=storage_url, tenant_name='not_demo')
 | 
						|
        fake_keystone = fake_get_auth_keystone(
 | 
						|
            storage_url='http://storage.example.com/v1/AUTH_post_url',
 | 
						|
            token='post_token')
 | 
						|
        fake_conn = self.fake_http_connection(200)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 get_auth_keystone=fake_keystone,
 | 
						|
                                 http_connection=fake_conn,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/AUTH_pre_url', '', {'x-auth-token': 'post_token'}),
 | 
						|
        ])
 | 
						|
 | 
						|
        # check that Connection has not modified our os_options
 | 
						|
        self.assertEqual(orig_os_preauth_options, os_preauth_options)
 | 
						|
 | 
						|
    def test_get_auth_sets_url_and_token(self):
 | 
						|
        with mock.patch('swiftclient.client.get_auth') as mock_get_auth:
 | 
						|
            mock_get_auth.return_value = (
 | 
						|
                "https://storage.url/v1/AUTH_storage_acct", "AUTH_token"
 | 
						|
            )
 | 
						|
            conn = c.Connection("https://auth.url/auth/v2.0",
 | 
						|
                                "user", "passkey", tenant_name="tenant")
 | 
						|
            conn.get_auth()
 | 
						|
        self.assertEqual("https://storage.url/v1/AUTH_storage_acct", conn.url)
 | 
						|
        self.assertEqual("AUTH_token", conn.token)
 | 
						|
 | 
						|
    def test_timeout_passed_down(self):
 | 
						|
        # We want to avoid mocking http_connection(), and most especially
 | 
						|
        # avoid passing it down in argument. However, we cannot simply
 | 
						|
        # instantiate C=Connection(), then shim C.http_conn. Doing so would
 | 
						|
        # avoid some of the code under test (where _retry() invokes
 | 
						|
        # http_connection()), and would miss get_auth() completely.
 | 
						|
        # So, with regret, we do mock http_connection(), but with a very
 | 
						|
        # light shim that swaps out _request() as originally intended.
 | 
						|
 | 
						|
        orig_http_connection = c.http_connection
 | 
						|
 | 
						|
        timeouts = []
 | 
						|
 | 
						|
        def my_request_handler(*a, **kw):
 | 
						|
            if 'timeout' in kw:
 | 
						|
                timeouts.append(kw['timeout'])
 | 
						|
            else:
 | 
						|
                timeouts.append(None)
 | 
						|
            return MockHttpResponse(
 | 
						|
                status=200,
 | 
						|
                headers={
 | 
						|
                    'x-auth-token': 'a_token',
 | 
						|
                    'x-storage-url': 'http://files.example.com/v1/AUTH_user'})
 | 
						|
 | 
						|
        def shim_connection(*a, **kw):
 | 
						|
            url, conn = orig_http_connection(*a, **kw)
 | 
						|
            conn._request = my_request_handler
 | 
						|
            return url, conn
 | 
						|
 | 
						|
        # v1 auth
 | 
						|
        conn = c.Connection(
 | 
						|
            'http://auth.example.com', 'user', 'password', timeout=33.0)
 | 
						|
        with mock.patch.multiple('swiftclient.client',
 | 
						|
                                 http_connection=shim_connection,
 | 
						|
                                 sleep=mock.DEFAULT):
 | 
						|
            conn.head_account()
 | 
						|
 | 
						|
        # 1 call is through get_auth, 1 call is HEAD for account
 | 
						|
        self.assertEqual(timeouts, [33.0, 33.0])
 | 
						|
 | 
						|
        # v2 auth
 | 
						|
        timeouts = []
 | 
						|
        os_options = {'tenant_name': 'tenant', 'auth_token': 'meta-token'}
 | 
						|
        conn = c.Connection(
 | 
						|
            'http://auth.example.com', 'user', 'password', timeout=33.0,
 | 
						|
            os_options=os_options, auth_version=2.0)
 | 
						|
        fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
 | 
						|
        with mock.patch('swiftclient.client._import_keystone_client',
 | 
						|
                        _make_fake_import_keystone_client(fake_ks)):
 | 
						|
            with mock.patch.multiple('swiftclient.client',
 | 
						|
                                     http_connection=shim_connection,
 | 
						|
                                     sleep=mock.DEFAULT):
 | 
						|
                conn.head_account()
 | 
						|
 | 
						|
        # check timeout is passed to keystone client
 | 
						|
        self.assertEqual(1, len(fake_ks.calls))
 | 
						|
        self.assertEqual(33.0, fake_ks.calls[0].get('timeout'))
 | 
						|
        # check timeout passed to HEAD for account
 | 
						|
        self.assertEqual(timeouts, [33.0])
 | 
						|
 | 
						|
        # check token passed to keystone client
 | 
						|
        self.assertIn('token', fake_ks.calls[0])
 | 
						|
        self.assertEqual('meta-token', fake_ks.calls[0].get('token'))
 | 
						|
 | 
						|
    def test_reset_stream(self):
 | 
						|
 | 
						|
        class LocalContents(object):
 | 
						|
 | 
						|
            def __init__(self, tell_value=0):
 | 
						|
                self.data = six.BytesIO(string.ascii_letters.encode() * 10)
 | 
						|
                self.data.seek(tell_value)
 | 
						|
                self.reads = []
 | 
						|
                self.seeks = []
 | 
						|
                self.tells = []
 | 
						|
 | 
						|
            def tell(self):
 | 
						|
                self.tells.append(self.data.tell())
 | 
						|
                return self.tells[-1]
 | 
						|
 | 
						|
            def seek(self, position, mode=0):
 | 
						|
                self.seeks.append((position, mode))
 | 
						|
                self.data.seek(position, mode)
 | 
						|
 | 
						|
            def read(self, size=-1):
 | 
						|
                read_data = self.data.read(size)
 | 
						|
                self.reads.append((size, read_data))
 | 
						|
                return read_data
 | 
						|
 | 
						|
        class LocalConnection(object):
 | 
						|
 | 
						|
            def __init__(self, parsed_url=None):
 | 
						|
                self.reason = ""
 | 
						|
                if parsed_url:
 | 
						|
                    self.host = parsed_url.netloc
 | 
						|
                    self.port = parsed_url.netloc
 | 
						|
 | 
						|
            def putrequest(self, *args, **kwargs):
 | 
						|
                self.send('PUT', *args, **kwargs)
 | 
						|
 | 
						|
            def putheader(self, *args, **kwargs):
 | 
						|
                return
 | 
						|
 | 
						|
            def endheaders(self, *args, **kwargs):
 | 
						|
                return
 | 
						|
 | 
						|
            def send(self, *args, **kwargs):
 | 
						|
                data = kwargs.get('data')
 | 
						|
                if data is not None:
 | 
						|
                    if hasattr(data, 'read'):
 | 
						|
                        data.read()
 | 
						|
                    else:
 | 
						|
                        for datum in data:
 | 
						|
                            pass
 | 
						|
                raise socket.error('oops')
 | 
						|
 | 
						|
            def request(self, *args, **kwargs):
 | 
						|
                return
 | 
						|
 | 
						|
            def getresponse(self, *args, **kwargs):
 | 
						|
                self.status = 200
 | 
						|
                return self
 | 
						|
 | 
						|
            def getheader(self, *args, **kwargs):
 | 
						|
                return 'header'
 | 
						|
 | 
						|
            def getheaders(self):
 | 
						|
                return {"key1": "value1", "key2": "value2"}
 | 
						|
 | 
						|
            def read(self, *args, **kwargs):
 | 
						|
                return ''
 | 
						|
 | 
						|
        def local_http_connection(url, proxy=None, cacert=None,
 | 
						|
                                  insecure=False, ssl_compression=True,
 | 
						|
                                  timeout=None):
 | 
						|
            parsed = urlparse(url)
 | 
						|
            return parsed, LocalConnection()
 | 
						|
 | 
						|
        with mock.patch.object(c, 'http_connection', local_http_connection):
 | 
						|
            conn = c.Connection('http://www.example.com', 'asdf', 'asdf',
 | 
						|
                                retries=1, starting_backoff=.0001)
 | 
						|
 | 
						|
            contents = LocalContents()
 | 
						|
            exc = None
 | 
						|
            try:
 | 
						|
                conn.put_object('c', 'o', contents)
 | 
						|
            except socket.error as err:
 | 
						|
                exc = err
 | 
						|
            self.assertEqual(contents.tells, [0])
 | 
						|
            self.assertEqual(contents.seeks, [(0, 0)])
 | 
						|
            # four reads: two in the initial pass, two in the retry
 | 
						|
            self.assertEqual(4, len(contents.reads))
 | 
						|
            self.assertEqual((65536, b''), contents.reads[1])
 | 
						|
            self.assertEqual((65536, b''), contents.reads[3])
 | 
						|
            self.assertEqual(str(exc), 'oops')
 | 
						|
 | 
						|
            contents = LocalContents(tell_value=123)
 | 
						|
            exc = None
 | 
						|
            try:
 | 
						|
                conn.put_object('c', 'o', contents)
 | 
						|
            except socket.error as err:
 | 
						|
                exc = err
 | 
						|
            self.assertEqual(contents.tells, [123])
 | 
						|
            self.assertEqual(contents.seeks, [(123, 0)])
 | 
						|
            # four reads: two in the initial pass, two in the retry
 | 
						|
            self.assertEqual(4, len(contents.reads))
 | 
						|
            self.assertEqual((65536, b''), contents.reads[1])
 | 
						|
            self.assertEqual((65536, b''), contents.reads[3])
 | 
						|
            self.assertEqual(str(exc), 'oops')
 | 
						|
 | 
						|
            contents = LocalContents(tell_value=123)
 | 
						|
            wrapped_contents = swiftclient.utils.LengthWrapper(
 | 
						|
                contents, 6, md5=True)
 | 
						|
            exc = None
 | 
						|
            try:
 | 
						|
                conn.put_object('c', 'o', wrapped_contents)
 | 
						|
            except socket.error as err:
 | 
						|
                exc = err
 | 
						|
            self.assertEqual(contents.tells, [123])
 | 
						|
            self.assertEqual(contents.seeks, [(123, 0)])
 | 
						|
            self.assertEqual(contents.reads, [(6, b'tuvwxy')] * 2)
 | 
						|
            self.assertEqual(str(exc), 'oops')
 | 
						|
            self.assertEqual(md5(b'tuvwxy').hexdigest(),
 | 
						|
                             wrapped_contents.get_md5sum())
 | 
						|
 | 
						|
            contents = LocalContents()
 | 
						|
            contents.tell = None
 | 
						|
            exc = None
 | 
						|
            try:
 | 
						|
                conn.put_object('c', 'o', contents)
 | 
						|
            except c.ClientException as err:
 | 
						|
                exc = err
 | 
						|
            self.assertEqual(contents.seeks, [])
 | 
						|
            self.assertEqual(str(exc), "put_object('c', 'o', ...) failure "
 | 
						|
                             "and no ability to reset contents for reupload.")
 | 
						|
 | 
						|
    def test_get_container(self):
 | 
						|
        headers = {'X-Favourite-Pet': 'Aardvark'}
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200, body=b'{}')):
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            lambda *a, **k: ('http://url:8080/v1/a', 'token')):
 | 
						|
                conn = c.Connection()
 | 
						|
                conn.get_container('c1', prefix='p', limit=5,
 | 
						|
                                   headers=headers)
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        self.assertRequests([
 | 
						|
            ('GET', '/v1/a/c1?format=json&limit=5&prefix=p', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
                'X-Favourite-Pet': 'Aardvark',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_head_container(self):
 | 
						|
        headers = {'X-Favourite-Pet': 'Aardvark'}
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200, body=b'{}')):
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            lambda *a, **k: ('http://url:8080/v1/a', 'token')):
 | 
						|
                conn = c.Connection()
 | 
						|
                conn.head_container('c1', headers=headers)
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/a/c1', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
                'X-Favourite-Pet': 'Aardvark',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_head_object(self):
 | 
						|
        headers = {'X-Favourite-Pet': 'Aardvark'}
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            lambda *a, **k: ('http://url:8080/v1/a', 'token')):
 | 
						|
                conn = c.Connection()
 | 
						|
                conn.head_object('c1', 'o1',
 | 
						|
                                 headers=headers)
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        self.assertRequests([
 | 
						|
            ('HEAD', '/v1/a/c1/o1', '', {
 | 
						|
                'x-auth-token': 'token',
 | 
						|
                'X-Favourite-Pet': 'Aardvark',
 | 
						|
            }),
 | 
						|
        ])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
 | 
						|
class TestResponseDict(MockHttpTest):
 | 
						|
    """
 | 
						|
    Verify handling of optional response_dict argument.
 | 
						|
    """
 | 
						|
    calls = [('post_account', {}),
 | 
						|
             ('post_container', 'c', {}),
 | 
						|
             ('put_container', 'c'),
 | 
						|
             ('delete_container', 'c'),
 | 
						|
             ('post_object', 'c', 'o', {}),
 | 
						|
             ('put_object', 'c', 'o', 'body'),
 | 
						|
             ('delete_object', 'c', 'o')]
 | 
						|
 | 
						|
    def fake_get_auth(*args, **kwargs):
 | 
						|
        return 'http://url', 'token'
 | 
						|
 | 
						|
    def test_response_dict_with_auth_error(self):
 | 
						|
        def bad_get_auth(*args, **kwargs):
 | 
						|
            raise c.ClientException('test')
 | 
						|
 | 
						|
        for call in self.calls:
 | 
						|
            resp_dict = {'test': 'should be untouched'}
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            bad_get_auth):
 | 
						|
                conn = c.Connection('http://127.0.0.1:8080', 'user', 'key')
 | 
						|
                self.assertRaises(c.ClientException, getattr(conn, call[0]),
 | 
						|
                                  *call[1:], response_dict=resp_dict)
 | 
						|
 | 
						|
            self.assertEqual({'test': 'should be untouched'}, resp_dict)
 | 
						|
 | 
						|
    def test_response_dict_with_request_error(self):
 | 
						|
        for call in self.calls:
 | 
						|
            resp_dict = {'test': 'should be untouched'}
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            self.fake_get_auth):
 | 
						|
                exc = c.ClientException('test')
 | 
						|
                with mock.patch('swiftclient.client.http_connection',
 | 
						|
                                self.fake_http_connection(200, exc=exc)):
 | 
						|
                    conn = c.Connection('http://127.0.0.1:8080', 'user', 'key')
 | 
						|
                    self.assertRaises(c.ClientException,
 | 
						|
                                      getattr(conn, call[0]),
 | 
						|
                                      *call[1:],
 | 
						|
                                      response_dict=resp_dict)
 | 
						|
 | 
						|
            self.assertEqual('should be untouched', resp_dict.get('test'))
 | 
						|
            self.assertEqual([{}], resp_dict.get('response_dicts'))
 | 
						|
 | 
						|
    def test_response_dict(self):
 | 
						|
        # test response_dict is populated and
 | 
						|
        # new list of response_dicts is created
 | 
						|
        for call in self.calls:
 | 
						|
            resp_dict = {'test': 'should be untouched'}
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            self.fake_get_auth):
 | 
						|
                with mock.patch('swiftclient.client.http_connection',
 | 
						|
                                self.fake_http_connection(200)):
 | 
						|
                    conn = c.Connection('http://127.0.0.1:8080', 'user', 'key')
 | 
						|
                    getattr(conn, call[0])(*call[1:], response_dict=resp_dict)
 | 
						|
 | 
						|
            self.assertEqual('should be untouched',
 | 
						|
                             resp_dict.pop('test', None))
 | 
						|
            self.assertEqual('Fake', resp_dict.get('reason'))
 | 
						|
            self.assertEqual(200, resp_dict.get('status'))
 | 
						|
            self.assertIn('headers', resp_dict)
 | 
						|
            self.assertEqual('yes', resp_dict['headers'].get('x-works'))
 | 
						|
            children = resp_dict.pop('response_dicts', [])
 | 
						|
            self.assertEqual(1, len(children))
 | 
						|
            self.assertEqual(resp_dict, children[0])
 | 
						|
 | 
						|
    def test_response_dict_with_existing(self):
 | 
						|
        # check response_dict is populated and new dict is appended
 | 
						|
        # to existing response_dicts list
 | 
						|
        for call in self.calls:
 | 
						|
            resp_dict = {'test': 'should be untouched',
 | 
						|
                         'response_dicts': [{'existing': 'response dict'}]}
 | 
						|
            with mock.patch('swiftclient.client.get_auth',
 | 
						|
                            self.fake_get_auth):
 | 
						|
                with mock.patch('swiftclient.client.http_connection',
 | 
						|
                                self.fake_http_connection(200)):
 | 
						|
                    conn = c.Connection('http://127.0.0.1:8080', 'user', 'key')
 | 
						|
                    getattr(conn, call[0])(*call[1:], response_dict=resp_dict)
 | 
						|
 | 
						|
            self.assertEqual('should be untouched',
 | 
						|
                             resp_dict.pop('test', None))
 | 
						|
            self.assertEqual('Fake', resp_dict.get('reason'))
 | 
						|
            self.assertEqual(200, resp_dict.get('status'))
 | 
						|
            self.assertIn('headers', resp_dict)
 | 
						|
            self.assertEqual('yes', resp_dict['headers'].get('x-works'))
 | 
						|
            children = resp_dict.pop('response_dicts', [])
 | 
						|
            self.assertEqual(2, len(children))
 | 
						|
            self.assertEqual({'existing': 'response dict'}, children[0])
 | 
						|
            self.assertEqual(resp_dict, children[1])
 | 
						|
 | 
						|
 | 
						|
class TestLogging(MockHttpTest):
 | 
						|
    """
 | 
						|
    Make sure all the lines in http_log are covered.
 | 
						|
    """
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(TestLogging, self).setUp()
 | 
						|
        self.swiftclient_logger = logging.getLogger("swiftclient")
 | 
						|
        self.log_level = self.swiftclient_logger.getEffectiveLevel()
 | 
						|
        self.swiftclient_logger.setLevel(logging.INFO)
 | 
						|
 | 
						|
    def tearDown(self):
 | 
						|
        self.swiftclient_logger.setLevel(self.log_level)
 | 
						|
        super(TestLogging, self).tearDown()
 | 
						|
 | 
						|
    def test_put_ok(self):
 | 
						|
        c.http_connection = self.fake_http_connection(200)
 | 
						|
        args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf')
 | 
						|
        value = c.put_object(*args)
 | 
						|
        self.assertIsInstance(value, six.string_types)
 | 
						|
 | 
						|
    def test_head_error(self):
 | 
						|
        c.http_connection = self.fake_http_connection(500)
 | 
						|
        self.assertRaises(c.ClientException, c.head_object,
 | 
						|
                          'http://www.test.com', 'asdf', 'asdf', 'asdf')
 | 
						|
 | 
						|
    def test_get_error(self):
 | 
						|
        c.http_connection = self.fake_http_connection(404)
 | 
						|
        e = self.assertRaises(c.ClientException, c.get_object,
 | 
						|
                              'http://www.test.com', 'asdf', 'asdf', 'asdf')
 | 
						|
        self.assertEqual(e.http_status, 404)
 | 
						|
 | 
						|
    def test_redact_token(self):
 | 
						|
        with mock.patch('swiftclient.client.logger.debug') as mock_log:
 | 
						|
            token_value = 'tkee96b40a8ca44fc5ad72ec5a7c90d9b'
 | 
						|
            unicode_token_value = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
 | 
						|
                                   u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
 | 
						|
                                   u'\u5929\u7a7a\u4e2d\u7684\u4e4c')
 | 
						|
            set_cookie_value = 'X-Auth-Token=%s' % token_value
 | 
						|
            c.http_log(
 | 
						|
                ['GET'],
 | 
						|
                {'headers': {
 | 
						|
                    'X-Auth-Token': token_value,
 | 
						|
                    'X-Storage-Token': unicode_token_value
 | 
						|
                }},
 | 
						|
                MockHttpResponse(
 | 
						|
                    status=200,
 | 
						|
                    headers={
 | 
						|
                        'X-Auth-Token': token_value,
 | 
						|
                        'X-Storage-Token': unicode_token_value,
 | 
						|
                        'Etag': b'mock_etag',
 | 
						|
                        'Set-Cookie': set_cookie_value
 | 
						|
                    }
 | 
						|
                ),
 | 
						|
                ''
 | 
						|
            )
 | 
						|
            out = []
 | 
						|
            for _, args, kwargs in mock_log.mock_calls:
 | 
						|
                for arg in args:
 | 
						|
                    out.append(u'%s' % arg)
 | 
						|
            output = u''.join(out)
 | 
						|
            self.assertIn('X-Auth-Token', output)
 | 
						|
            self.assertIn(token_value[:16] + '...', output)
 | 
						|
            self.assertIn('X-Storage-Token', output)
 | 
						|
            self.assertIn(unicode_token_value[:8] + '...', output)
 | 
						|
            self.assertIn('Set-Cookie', output)
 | 
						|
            self.assertIn(set_cookie_value[:16] + '...', output)
 | 
						|
            self.assertNotIn(token_value, output)
 | 
						|
            self.assertNotIn(unicode_token_value, output)
 | 
						|
            self.assertNotIn(set_cookie_value, output)
 | 
						|
 | 
						|
    def test_show_token(self):
 | 
						|
        with mock.patch('swiftclient.client.logger.debug') as mock_log:
 | 
						|
            token_value = 'tkee96b40a8ca44fc5ad72ec5a7c90d9b'
 | 
						|
            unicode_token_value = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
 | 
						|
                                   u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
 | 
						|
                                   u'\u5929\u7a7a\u4e2d\u7684\u4e4c')
 | 
						|
            c.logger_settings['redact_sensitive_tokens'] = False
 | 
						|
            c.http_log(
 | 
						|
                ['GET'],
 | 
						|
                {'headers': {
 | 
						|
                    'X-Auth-Token': token_value,
 | 
						|
                    'X-Storage-Token': unicode_token_value
 | 
						|
                }},
 | 
						|
                MockHttpResponse(
 | 
						|
                    status=200,
 | 
						|
                    headers=[
 | 
						|
                        ('X-Auth-Token', token_value),
 | 
						|
                        ('X-Storage-Token', unicode_token_value),
 | 
						|
                        ('Etag', b'mock_etag')
 | 
						|
                    ]
 | 
						|
                ),
 | 
						|
                ''
 | 
						|
            )
 | 
						|
            out = []
 | 
						|
            for _, args, kwargs in mock_log.mock_calls:
 | 
						|
                for arg in args:
 | 
						|
                    out.append(u'%s' % arg)
 | 
						|
            output = u''.join(out)
 | 
						|
            self.assertIn('X-Auth-Token', output)
 | 
						|
            self.assertIn(token_value, output)
 | 
						|
            self.assertIn('X-Storage-Token', output)
 | 
						|
            self.assertIn(unicode_token_value, output)
 | 
						|
 | 
						|
 | 
						|
class TestCloseConnection(MockHttpTest):
 | 
						|
 | 
						|
    def test_close_none(self):
 | 
						|
        c.http_connection = self.fake_http_connection()
 | 
						|
        conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
 | 
						|
        self.assertIsNone(conn.http_conn)
 | 
						|
        conn.close()
 | 
						|
        self.assertIsNone(conn.http_conn)
 | 
						|
 | 
						|
    def test_close_ok(self):
 | 
						|
        url = 'http://www.test.com'
 | 
						|
        conn = c.Connection(url, 'asdf', 'asdf')
 | 
						|
        self.assertIsNone(conn.http_conn)
 | 
						|
        conn.http_conn = c.http_connection(url)
 | 
						|
        self.assertEqual(type(conn.http_conn), tuple)
 | 
						|
        self.assertEqual(len(conn.http_conn), 2)
 | 
						|
        http_conn_obj = conn.http_conn[1]
 | 
						|
        self.assertIsInstance(http_conn_obj, c.HTTPConnection)
 | 
						|
        self.assertFalse(hasattr(http_conn_obj, 'close'))
 | 
						|
        conn.close()
 | 
						|
 | 
						|
 | 
						|
class TestServiceToken(MockHttpTest):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(TestServiceToken, self).setUp()
 | 
						|
        self.os_options = {
 | 
						|
            'object_storage_url': 'http://storage_url.com',
 | 
						|
            'service_username': 'service_username',
 | 
						|
            'service_project_name': 'service_project_name',
 | 
						|
            'service_key': 'service_key'}
 | 
						|
 | 
						|
    def get_connection(self):
 | 
						|
        conn = c.Connection('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                            os_options=self.os_options)
 | 
						|
 | 
						|
        self.assertIs(type(conn), c.Connection)
 | 
						|
        conn.get_auth = self.get_auth
 | 
						|
        conn.get_service_auth = self.get_service_auth
 | 
						|
 | 
						|
        self.assertEqual(conn.attempts, 0)
 | 
						|
        self.assertIsNone(conn.service_token)
 | 
						|
 | 
						|
        self.assertIs(type(conn), c.Connection)
 | 
						|
        return conn
 | 
						|
 | 
						|
    def get_auth(self):
 | 
						|
        # The real get_auth function will always return the os_option
 | 
						|
        # dict's object_storage_url which will be overridden by the
 | 
						|
        # preauthurl parameter to Connection if it is provided.
 | 
						|
        return self.os_options.get('object_storage_url'), 'token'
 | 
						|
 | 
						|
    def get_service_auth(self):
 | 
						|
        # The real get_auth function will always return the os_option
 | 
						|
        # dict's object_storage_url which will be overridden by the
 | 
						|
        # preauthurl parameter to Connection if it is provided.
 | 
						|
        return self.os_options.get('object_storage_url'), 'stoken'
 | 
						|
 | 
						|
    def test_service_token_reauth(self):
 | 
						|
        get_auth_call_list = []
 | 
						|
 | 
						|
        def get_auth(url, user, key, **kwargs):
 | 
						|
            # The real get_auth function will always return the os_option
 | 
						|
            # dict's object_storage_url which will be overridden by the
 | 
						|
            # preauthurl parameter to Connection if it is provided.
 | 
						|
            args = {'url': url, 'user': user, 'key': key, 'kwargs': kwargs}
 | 
						|
            get_auth_call_list.append(args)
 | 
						|
            return_dict = {'asdf': 'new', 'service_username': 'newserv'}
 | 
						|
            storage_url = kwargs['os_options'].get('object_storage_url')
 | 
						|
            return storage_url, return_dict[user]
 | 
						|
 | 
						|
        def swap_sleep(*args):
 | 
						|
            self.swap_sleep_called = True
 | 
						|
            c.get_auth = get_auth
 | 
						|
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(401, 200)):
 | 
						|
            with mock.patch('swiftclient.client.sleep', swap_sleep):
 | 
						|
                self.swap_sleep_called = False
 | 
						|
 | 
						|
                conn = c.Connection('http://www.test.com', 'asdf', 'asdf',
 | 
						|
                                    preauthurl='http://www.old.com',
 | 
						|
                                    preauthtoken='old',
 | 
						|
                                    os_options=self.os_options)
 | 
						|
 | 
						|
                self.assertEqual(conn.attempts, 0)
 | 
						|
                self.assertEqual(conn.url, 'http://www.old.com')
 | 
						|
                self.assertEqual(conn.token, 'old')
 | 
						|
 | 
						|
                conn.head_account()
 | 
						|
 | 
						|
        self.assertTrue(self.swap_sleep_called)
 | 
						|
        self.assertEqual(conn.attempts, 2)
 | 
						|
        # The original 'preauth' storage URL *must* be preserved
 | 
						|
        self.assertEqual(conn.url, 'http://www.old.com')
 | 
						|
        self.assertEqual(conn.token, 'new')
 | 
						|
        self.assertEqual(conn.service_token, 'newserv')
 | 
						|
 | 
						|
        # Check get_auth was called with expected args
 | 
						|
        auth_args = get_auth_call_list[0]
 | 
						|
        auth_kwargs = get_auth_call_list[0]['kwargs']
 | 
						|
        self.assertEqual('asdf', auth_args['user'])
 | 
						|
        self.assertEqual('asdf', auth_args['key'])
 | 
						|
        self.assertEqual('service_key',
 | 
						|
                         auth_kwargs['os_options']['service_key'])
 | 
						|
        self.assertEqual('service_username',
 | 
						|
                         auth_kwargs['os_options']['service_username'])
 | 
						|
        self.assertEqual('service_project_name',
 | 
						|
                         auth_kwargs['os_options']['service_project_name'])
 | 
						|
 | 
						|
        auth_args = get_auth_call_list[1]
 | 
						|
        auth_kwargs = get_auth_call_list[1]['kwargs']
 | 
						|
        self.assertEqual('service_username', auth_args['user'])
 | 
						|
        self.assertEqual('service_key', auth_args['key'])
 | 
						|
        self.assertEqual('service_project_name',
 | 
						|
                         auth_kwargs['os_options']['tenant_name'])
 | 
						|
 | 
						|
    def test_service_token_get_account(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            with mock.patch('swiftclient.client.parse_api_response'):
 | 
						|
                conn = self.get_connection()
 | 
						|
                conn.get_account()
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('GET', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/?format=json',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_head_account(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.head_account()
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('HEAD', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com', actual['full_path'])
 | 
						|
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_post_account(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(201)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.post_account(headers={})
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('POST', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com', actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_delete_container(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(204)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.delete_container('container1')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('DELETE', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_get_container(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            with mock.patch('swiftclient.client.parse_api_response'):
 | 
						|
                conn = self.get_connection()
 | 
						|
                conn.get_container('container1')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('GET', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1?format=json',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_head_container(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.head_container('container1')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('HEAD', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_post_container(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(201)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.post_container('container1', {})
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('POST', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_put_container(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.put_container('container1')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('PUT', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_get_object(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.get_object('container1', 'obj1')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('GET', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1/obj1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_head_object(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.head_object('container1', 'obj1')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('HEAD', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1/obj1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_put_object(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(200)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.put_object('container1', 'obj1', 'a_string')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('PUT', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1/obj1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_post_object(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(202)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.post_object('container1', 'obj1', {})
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('POST', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1/obj1',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 | 
						|
 | 
						|
    def test_service_token_delete_object(self):
 | 
						|
        with mock.patch('swiftclient.client.http_connection',
 | 
						|
                        self.fake_http_connection(202)):
 | 
						|
            conn = self.get_connection()
 | 
						|
            conn.delete_object('container1', 'obj1', 'a_string')
 | 
						|
        self.assertEqual(1, len(self.request_log), self.request_log)
 | 
						|
        for actual in self.iter_request_log():
 | 
						|
            self.assertEqual('DELETE', actual['method'])
 | 
						|
            actual_hdrs = actual['headers']
 | 
						|
            self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
 | 
						|
            self.assertEqual('token', actual_hdrs['X-Auth-Token'])
 | 
						|
            self.assertEqual('http://storage_url.com/container1/obj1?a_string',
 | 
						|
                             actual['full_path'])
 | 
						|
        self.assertEqual(conn.attempts, 1)
 |