diff --git a/botocore/client.py b/botocore/client.py index a3122c8c70..df65c3ae4c 100644 --- a/botocore/client.py +++ b/botocore/client.py @@ -21,15 +21,12 @@ from botocore.endpoint import EndpointCreator, DEFAULT_TIMEOUT from botocore.exceptions import ClientError, DataNotFoundError from botocore.exceptions import OperationNotPageableError -from botocore.exceptions import InvalidS3AddressingStyleError from botocore.hooks import first_non_none_response from botocore.model import ServiceModel from botocore.paginate import Paginator from botocore.signers import RequestSigner from botocore.utils import CachedProperty from botocore.utils import get_service_module_name -from botocore.utils import fix_s3_host -from botocore.utils import switch_to_virtual_host_style from botocore.docs.docstring import ClientMethodDocstring from botocore.docs.docstring import PaginatorDocstring @@ -167,30 +164,6 @@ def _determine_region_name(self, endpoint_config, region_name=None, return region_name - def _inject_s3_configuration(self, config_kwargs, scoped_config, - client_config): - s3_configuration = None - - # Check the scoped config first - if scoped_config is not None: - s3_configuration = scoped_config.get('s3') - - # Next specfic client config values takes precedence over - # specific values in the scoped config. - if client_config is not None: - if client_config.s3 is not None: - if s3_configuration is None: - s3_configuration = client_config.s3 - else: - # The current s3_configuration dictionary may be - # from a source that only should be read from so - # we want to be safe and just make a copy of it to modify - # before it actually gets updated. - s3_configuration = s3_configuration.copy() - s3_configuration.update(client_config.s3) - - config_kwargs['s3'] = s3_configuration - def _get_client_args(self, service_model, region_name, is_secure, endpoint_url, verify, credentials, scoped_config, client_config): @@ -245,11 +218,6 @@ def _get_client_args(self, service_model, region_name, is_secure, config_kwargs.update( connect_timeout=client_config.connect_timeout, read_timeout=client_config.read_timeout) - - # Add any additional s3 configuration for client - self._inject_s3_configuration( - config_kwargs, scoped_config, client_config) - new_config = Config(**config_kwargs) endpoint_creator = EndpointCreator(self._endpoint_resolver, @@ -339,29 +307,10 @@ def __init__(self, serializer, endpoint, response_parser, self.meta = ClientMeta(event_emitter, self._client_config, endpoint.host, service_model, self._PY_TO_OP_NAME) - self._register_handlers() - - def _register_handlers(self): - # Register the handler required to sign requests. self.meta.events.register('request-created.%s' % - self.meta.service_model.endpoint_prefix, + service_model.endpoint_prefix, self._sign_request) - # If the virtual host addressing style is being forced, - # switch the default fix_s3_host handler for the more general - # switch_to_virtual_host_style handler that does not have opt out - # cases (other than throwing an error if the name is DNS incompatible) - if self.meta.config.s3 is None: - s3_addressing_style = None - else: - s3_addressing_style = self.meta.config.s3.get('addressing_style') - - if s3_addressing_style in [None, 'auto']: - self.meta.events.register('before-sign.s3', fix_s3_host) - elif s3_addressing_style == 'virtual': - self.meta.events.register( - 'before-sign.s3', switch_to_virtual_host_style) - @property def _service_model(self): return self.meta.service_model @@ -592,60 +541,23 @@ def method_to_api_mapping(self): class Config(object): """Advanced configuration for Botocore clients. - :type region_name: str - :param region_name: The region to use in instantiating the client - - :type signature_version: str - :param signature_version: The signature version when signing requests. - - :type user_agent: str - :param user_agent: The value to use in the User-Agent header. - - :type user_agent_extra: str - :param user_agent_extra: The value to append to the current User-Agent - header value. - - :type connect_timeout: int - :param connect_timeout: The time in seconds till a timeout exception is - thrown when attempting to make a connection. - - :type read_timeout: int - :param read_timeout: The time in seconds till a timeout exception is - thrown when attempting to read from a connection. - - :type s3: dict - :param s3: A dictionary of s3 specific configurations. - Valid keys are: - * 'addressing_style' -- Refers to the style in which to address - s3 endpoints. Values must be a string that equals: - * auto -- Addressing style is chosen for user. Depending - on the configuration of client, the endpoint - may be addressed in the virtual or the path - style. - * virtual -- Addressing style is always virtual. The name of - the bucket must be DNS compatible or an - exception will be thrown. Endpoints will be - addressed as such: mybucket.s3.amazonaws.com - * path -- Addressing style is always by path. Endpoints will - be addressed as such: s3.amazonaws.com/mybucket + This class allows you to configure: + + * Region name + * Signature version + * User agent + * User agent extra + * Connect timeout + * Read timeout + """ def __init__(self, region_name=None, signature_version=None, user_agent=None, user_agent_extra=None, connect_timeout=DEFAULT_TIMEOUT, - read_timeout=DEFAULT_TIMEOUT, - s3=None): + read_timeout=DEFAULT_TIMEOUT): self.region_name = region_name self.signature_version = signature_version self.user_agent = user_agent self.user_agent_extra = user_agent_extra self.connect_timeout = connect_timeout self.read_timeout = read_timeout - self._validate_s3_configuration(s3) - self.s3 = s3 - - def _validate_s3_configuration(self, s3): - if s3 is not None: - addressing_style = s3.get('addressing_style') - if addressing_style not in ['virtual', 'auto', 'path', None]: - raise InvalidS3AddressingStyleError( - s3_addressing_style=addressing_style) diff --git a/botocore/exceptions.py b/botocore/exceptions.py index f56ad9f8ac..b5a3426e98 100644 --- a/botocore/exceptions.py +++ b/botocore/exceptions.py @@ -305,22 +305,3 @@ def __init__(self, error_response, operation_name): class ImminentRemovalWarning(Warning): pass - - -class InvalidDNSNameError(BotoCoreError): - """Error when virtual host path is forced on a non-DNS compatible bucket""" - fmt = ( - 'Bucket named {bucket_name} is not DNS compatible. Virtual ' - 'hosted-style addressing cannot be used. The addressing style ' - 'can be configured by removing the addressing_style value ' - 'or setting that value to \'path\' or \'auto\' in the AWS Config ' - 'file or in the botocore.client.Config object.' - ) - - -class InvalidS3AddressingStyleError(BotoCoreError): - """Error when an invalid path style is specified""" - fmt = ( - 'S3 addressing style {s3_addressing_style} is invaild. Valid options ' - 'are: \'auto\', \'virtual\', and \'path\'' - ) diff --git a/botocore/handlers.py b/botocore/handlers.py index a40da89b57..200e20e6b0 100644 --- a/botocore/handlers.py +++ b/botocore/handlers.py @@ -504,6 +504,7 @@ def switch_host_with_param(request, param_name): disable_signing), ('choose-signer.sts.AssumeRoleWithSAML', disable_signing), ('choose-signer.sts.AssumeRoleWithWebIdentity', disable_signing), + ('before-sign.s3', utils.fix_s3_host), ('before-parameter-build.s3.HeadObject', sse_md5), ('before-parameter-build.s3.GetObject', sse_md5), ('before-parameter-build.s3.PutObject', sse_md5), diff --git a/botocore/utils.py b/botocore/utils.py index 021c5da495..c93e9933ec 100644 --- a/botocore/utils.py +++ b/botocore/utils.py @@ -22,7 +22,6 @@ from dateutil.tz import tzlocal, tzutc from botocore.exceptions import InvalidExpressionError, ConfigNotFound -from botocore.exceptions import InvalidDNSNameError from botocore.compat import json, quote, zip_longest, urlsplit, urlunsplit from botocore.vendored import requests from botocore.compat import OrderedDict @@ -622,33 +621,6 @@ def fix_s3_host(request, signature_version, region_name, **kwargs): addressing. This allows us to avoid 301 redirects for all bucket names that can be CNAME'd. """ - # By default we do not use virtual hosted style addressing when - # signed with signature version 4. - if signature_version in ['s3v4', 'v4']: - return - try: - switch_to_virtual_host_style( - request, signature_version, region_name, 's3.amazonaws.com') - except InvalidDNSNameError as e: - bucket_name = e.kwargs['bucket_name'] - logger.debug('Not changing URI, bucket is not DNS compatible: %s', - bucket_name) - - -def switch_to_virtual_host_style(request, signature_version, region_name, - default_endpoint_url=None, **kwargs): - """ - This is a handler to force virtual host style s3 addressing no matter - the signature version (which is taken in consideration for the default - case). If the bucket is not DNS compatible an InvalidDNSName is thrown. - - :param request: A AWSRequest object that is about to be sent. - :param signature_version: The signature version to sign with - :param region_name: The name of the region to sign with - :param default_endpoint_url: The endpoint to use when switching to a - virtual style. If None is supplied, the virtual host will be - constructed from the url of the request. - """ if request.auth_path is not None: # The auth_path has already been applied (this may be a # retried request). We don't need to perform this @@ -664,17 +636,10 @@ def switch_to_virtual_host_style(request, signature_version, region_name, parts = urlsplit(request.url) request.auth_path = parts.path path_parts = parts.path.split('/') - - # Retrieve what the endpoint we will be prepending the bucket name to. - if default_endpoint_url is None: - default_endpoint_url = parts.netloc - + if signature_version in ['s3v4', 'v4']: + return if len(path_parts) > 1: bucket_name = path_parts[1] - if not bucket_name: - # If the bucket name is empty we should not be checking for - # dns compatibility. - return logger.debug('Checking for DNS compatible bucket for: %s', request.url) if check_dns_name(bucket_name) and _allowed_region(region_name): @@ -684,19 +649,16 @@ def switch_to_virtual_host_style(request, signature_version, region_name, if request.auth_path[-1] != '/': request.auth_path += '/' path_parts.remove(bucket_name) - # At the very least the path must be a '/', such as with the - # CreateBucket operation when DNS style is being used. If this - # is not used you will get an empty path which is incorrect. - path = '/'.join(path_parts) or '/' - global_endpoint = default_endpoint_url + global_endpoint = 's3.amazonaws.com' host = bucket_name + '.' + global_endpoint - new_tuple = (parts.scheme, host, path, + new_tuple = (parts.scheme, host, '/'.join(path_parts), parts.query, '') new_uri = urlunsplit(new_tuple) request.url = new_uri logger.debug('URI updated to: %s', new_uri) else: - raise InvalidDNSNameError(bucket_name=bucket_name) + logger.debug('Not changing URI, bucket is not DNS compatible: %s', + bucket_name) def _is_get_bucket_location_request(request): diff --git a/tests/functional/test_s3.py b/tests/functional/test_s3.py index e85148d5f9..96aa88b911 100644 --- a/tests/functional/test_s3.py +++ b/tests/functional/test_s3.py @@ -13,7 +13,6 @@ from tests import unittest, mock, BaseSessionTest import botocore.session -from botocore.client import Config from botocore.exceptions import ParamValidationError @@ -88,62 +87,3 @@ def test_multiple_transitions_returns_one(self): response['Rules'][1]['NoncurrentVersionTransition'], {'NoncurrentDays': 40, 'StorageClass': 'STANDARD_IA'} ) - - -class BaseS3AddressingStyle(BaseSessionTest): - def setUp(self): - super(BaseS3AddressingStyle, self).setUp() - self.http_response = mock.Mock() - self.http_response.status_code = 200 - self.http_response.headers = {} - self.http_response.content = b'' - - -class TestVirtualHostStyle(BaseS3AddressingStyle): - def test_default_endpoint_for_virtual_addressing(self): - s3 = self.session.create_client( - 's3', config=Config(s3={'addressing_style': 'virtual'})) - with mock.patch('botocore.endpoint.Session.send') \ - as mock_send: - mock_send.return_value = self.http_response - s3.put_object(Bucket='mybucket', Key='mykey', Body='mybody') - request_sent = mock_send.call_args[0][0] - self.assertEqual( - 'https://mybucket.s3.amazonaws.com/mykey', request_sent.url) - - def test_provided_endpoint_url_for_virtual_addressing(self): - s3 = self.session.create_client( - 's3', config=Config(s3={'addressing_style': 'virtual'}), - endpoint_url='https://foo.amazonaws.com') - with mock.patch('botocore.endpoint.Session.send') \ - as mock_send: - mock_send.return_value = self.http_response - s3.put_object(Bucket='mybucket', Key='mykey', Body='mybody') - request_sent = mock_send.call_args[0][0] - self.assertEqual( - 'https://mybucket.foo.amazonaws.com/mykey', request_sent.url) - - -class TestPathHostStyle(BaseS3AddressingStyle): - def test_default_endpoint_for_path_addressing(self): - s3 = self.session.create_client( - 's3', config=Config(s3={'addressing_style': 'path'})) - with mock.patch('botocore.endpoint.Session.send') \ - as mock_send: - mock_send.return_value = self.http_response - s3.put_object(Bucket='mybucket', Key='mykey', Body='mybody') - request_sent = mock_send.call_args[0][0] - self.assertEqual( - 'https://s3.amazonaws.com/mybucket/mykey', request_sent.url) - - def test_provided_endpoint_url_for_path_addressing(self): - s3 = self.session.create_client( - 's3', config=Config(s3={'addressing_style': 'path'}), - endpoint_url='https://foo.amazonaws.com') - with mock.patch('botocore.endpoint.Session.send') \ - as mock_send: - mock_send.return_value = self.http_response - s3.put_object(Bucket='mybucket', Key='mykey', Body='mybody') - request_sent = mock_send.call_args[0][0] - self.assertEqual( - 'https://foo.amazonaws.com/mybucket/mykey', request_sent.url) diff --git a/tests/integration/test_s3.py b/tests/integration/test_s3.py index d9fc3ddc72..a7641e2f4a 100644 --- a/tests/integration/test_s3.py +++ b/tests/integration/test_s3.py @@ -900,52 +900,5 @@ def create_client(self): config=client_config) -class TestAutoS3Addressing(BaseS3ClientTest): - def setUp(self): - super(TestAutoS3Addressing, self).setUp() - self.region = 'us-west-2' - self.addressing_style = 'auto' - self.client = self.create_client() - - def create_client(self): - return self.session.create_client( - 's3', region_name=self.region, - config=Config(s3={'addressing_style': self.addressing_style})) - - def test_can_list_buckets(self): - response = self.client.list_buckets() - self.assertIn('Buckets', response) - - def test_can_make_bucket_and_put_object(self): - bucket_name = self.create_bucket(self.region) - response = self.client.put_object( - Bucket=bucket_name, Key='foo', Body='contents') - self.assertEqual( - response['ResponseMetadata']['HTTPStatusCode'], 200) - - def test_can_make_bucket_and_put_object_with_sigv4(self): - self.region = 'eu-central-1' - self.client = self.create_client() - bucket_name = self.create_bucket(self.region) - response = self.client.put_object( - Bucket=bucket_name, Key='foo', Body='contents') - self.assertEqual( - response['ResponseMetadata']['HTTPStatusCode'], 200) - - -class TestS3VirtualAddressing(TestAutoS3Addressing): - def setUp(self): - super(TestS3VirtualAddressing, self).setUp() - self.addressing_style = 'virtual' - self.client = self.create_client() - - -class TestS3PathAddressing(TestAutoS3Addressing): - def setUp(self): - super(TestS3PathAddressing, self).setUp() - self.addressing_style = 'path' - self.client = self.create_client() - - if __name__ == '__main__': unittest.main() diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 98b19ec5d9..33c97790fc 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -15,13 +15,11 @@ import mock import botocore -from botocore import utils from botocore import client from botocore.endpoint import DEFAULT_TIMEOUT from botocore import hooks from botocore.credentials import Credentials from botocore.exceptions import ParamValidationError -from botocore.exceptions import InvalidS3AddressingStyleError from botocore import exceptions from botocore.compat import six @@ -408,9 +406,8 @@ def test_client_registers_request_created_handler(self): creator = self.create_client_creator(event_emitter=event_emitter) creator.create_client( 'myservice', 'us-west-2', credentials=self.credentials) - self.assertIn( - mock.call('request-created.myservice', mock.ANY), - event_emitter.register.call_args_list) + event_emitter.register.assert_called_with('request-created.myservice', + mock.ANY) def test_client_makes_call(self): creator = self.create_client_creator() @@ -1000,94 +997,3 @@ def inject_params(params, **kwargs): # Ensure the handler passed on the correct param values. body = self.endpoint.make_request.call_args[0][1]['body'] self.assertEqual(body['Foo'], 'zero') - - def test_client_default_for_s3_addressing_style(self): - creator = self.create_client_creator() - client = creator.create_client('myservice', 'us-west-2') - self.assertEqual(client.meta.config.s3, None) - - def test_client_s3_addressing_style_with_config(self): - creator = self.create_client_creator() - my_client = creator.create_client( - 'myservice', 'us-west-2', - client_config=client.Config(s3={'addressing_style': 'auto'}) - ) - self.assertEqual( - my_client.meta.config.s3['addressing_style'], 'auto') - - def test_client_s3_addressing_style_with_scoped_config(self): - creator = self.create_client_creator() - client = creator.create_client( - 'myservice', 'us-west-2', - scoped_config={'s3': {'addressing_style': 'virtual'}} - ) - self.assertEqual( - client.meta.config.s3['addressing_style'], 'virtual') - - def test_client_s3_addressing_style_with_incorrect_style(self): - creator = self.create_client_creator() - with self.assertRaises(InvalidS3AddressingStyleError): - client_config=client.Config(s3={'addressing_style': 'foo'}) - - def test_client_s3_addressing_style_config_overrides_scoped_config(self): - creator = self.create_client_creator() - my_client = creator.create_client( - 'myservice', 'us-west-2', - scoped_config={'s3': {'addressing_style': 'virtual'}}, - client_config=client.Config(s3={'addressing_style': 'auto'}) - ) - self.assertEqual( - my_client.meta.config.s3['addressing_style'], 'auto') - - def test_client_s3_addressing_style_default_registers_correctly(self): - event_emitter = mock.Mock() - creator = self.create_client_creator(event_emitter=event_emitter) - client = creator.create_client('myservice', 'us-west-2') - self.assertNotIn( - mock.call('before-sign.s3', utils.switch_to_virtual_host_style), - client.meta.events.register.call_args_list - ) - self.assertNotIn( - mock.call('before-sign.s3', utils.fix_s3_host), - client.meta.events.unregister.call_args_list - ) - - def test_client_s3_addressing_style_default_registers_correctly(self): - event_emitter = mock.Mock() - creator = self.create_client_creator(event_emitter=event_emitter) - client = creator.create_client( - 'myservice', 'us-west-2', - scoped_config={'s3': {'addressing_style': 'auto'}} - ) - self.assertIn( - mock.call('before-sign.s3', utils.fix_s3_host), - client.meta.events.register.call_args_list - ) - - def test_client_s3_addressing_style_virtual_registers_correctly(self): - event_emitter = mock.Mock() - creator = self.create_client_creator(event_emitter=event_emitter) - client = creator.create_client( - 'myservice', 'us-west-2', - scoped_config={'s3': {'addressing_style': 'virtual'}} - ) - self.assertIn( - mock.call('before-sign.s3', utils.switch_to_virtual_host_style), - client.meta.events.register.call_args_list - ) - - def test_client_s3_addressing_style_path_registers_correctly(self): - event_emitter = mock.Mock() - creator = self.create_client_creator(event_emitter=event_emitter) - client = creator.create_client( - 'myservice', 'us-west-2', - scoped_config={'s3': {'addressing_style': 'path'}} - ) - self.assertNotIn( - mock.call('before-sign.s3', utils.fix_s3_host), - client.meta.events.register.call_args_list - ) - self.assertNotIn( - mock.call('before-sign.s3', utils.switch_to_virtual_host_style), - client.meta.events.register.call_args_list - ) diff --git a/tests/unit/test_signers.py b/tests/unit/test_signers.py index fac36e75c3..b2b8d6c38b 100644 --- a/tests/unit/test_signers.py +++ b/tests/unit/test_signers.py @@ -323,7 +323,7 @@ def test_generate_presigned_post_fixes_s3_host(self): credentials=self.credentials, region_name='region_name', service_name='signing_name') self.assertEqual(post_form_args['url'], - 'https://mybucket.s3.amazonaws.com/') + 'https://mybucket.s3.amazonaws.com') def test_presigned_post_throws_unsupported_signature_error(self): self.request_signer = RequestSigner( diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 8a1239e15c..5459e6751e 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -21,7 +21,6 @@ from botocore import xform_name from botocore.awsrequest import AWSRequest from botocore.exceptions import InvalidExpressionError, ConfigNotFound -from botocore.exceptions import InvalidDNSNameError from botocore.model import ServiceModel from botocore.utils import remove_dot_segments from botocore.utils import normalize_url_path @@ -37,7 +36,6 @@ from botocore.utils import calculate_sha256 from botocore.utils import is_valid_endpoint_url from botocore.utils import fix_s3_host -from botocore.utils import switch_to_virtual_host_style from botocore.utils import instance_cache from botocore.utils import merge_dicts from botocore.utils import get_service_module_name @@ -559,125 +557,6 @@ def test_dns_style_not_used_for_get_bucket_location(self): self.assertEqual(request.url, original_url) -class TestSwitchToVirtualHostStyle(unittest.TestCase): - def test_switch_to_virtual_host_style(self): - request = AWSRequest( - method='PUT', headers={}, - url='https://foo.amazonaws.com/bucket/key.txt' - ) - region_name = 'us-west-2' - signature_version = 's3' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - self.assertEqual(request.url, - 'https://bucket.foo.amazonaws.com/key.txt') - self.assertEqual(request.auth_path, '/bucket/key.txt') - - def test_uses_default_endpoint(self): - request = AWSRequest( - method='PUT', headers={}, - url='https://foo.amazonaws.com/bucket/key.txt' - ) - region_name = 'us-west-2' - signature_version = 's3' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name, default_endpoint_url='s3.amazonaws.com') - self.assertEqual(request.url, - 'https://bucket.s3.amazonaws.com/key.txt') - self.assertEqual(request.auth_path, '/bucket/key.txt') - - def test_throws_invalid_dns_name_error(self): - request = AWSRequest( - method='PUT', headers={}, - url='https://foo.amazonaws.com/mybucket.foo/key.txt' - ) - region_name = 'us-west-2' - signature_version = 's3' - with self.assertRaises(InvalidDNSNameError): - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - - def test_fix_s3_host_only_applied_once(self): - request = AWSRequest( - method='PUT', headers={}, - url='https://foo.amazonaws.com/bucket/key.txt' - ) - region_name = 'us-west-2' - signature_version = 's3' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - # Calling the handler again should not affect the end result: - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - self.assertEqual(request.url, - 'https://bucket.foo.amazonaws.com/key.txt') - # This was a bug previously. We want to make sure that - # calling fix_s3_host() again does not alter the auth_path. - # Otherwise we'll get signature errors. - self.assertEqual(request.auth_path, '/bucket/key.txt') - - def test_virtual_host_style_for_make_bucket(self): - request = AWSRequest( - method='PUT', headers={}, - url='https://foo.amazonaws.com/bucket' - ) - region_name = 'us-west-2' - signature_version = 's3' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - self.assertEqual(request.url, - 'https://bucket.foo.amazonaws.com/') - - def test_virtual_host_style_not_used_for_get_bucket_location(self): - original_url = 'https://foo.amazonaws.com/bucket?location' - request = AWSRequest( - method='GET', headers={}, - url=original_url, - ) - signature_version = 's3' - region_name = 'us-west-2' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - # The request url should not have been modified because this is - # a request for GetBucketLocation. - self.assertEqual(request.url, original_url) - - def test_virtual_host_style_not_used_for_list_buckets(self): - original_url = 'https://foo.amazonaws.com/' - request = AWSRequest( - method='GET', headers={}, - url=original_url, - ) - signature_version = 's3' - region_name = 'us-west-2' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name) - # The request url should not have been modified because this is - # a request for GetBucketLocation. - self.assertEqual(request.url, original_url) - - def test_is_unaffected_by_sigv4(self): - request = AWSRequest( - method='PUT', headers={}, - url='https://foo.amazonaws.com/bucket/key.txt' - ) - region_name = 'us-west-2' - signature_version = 's3v4' - switch_to_virtual_host_style( - request=request, signature_version=signature_version, - region_name=region_name, default_endpoint_url='s3.amazonaws.com') - self.assertEqual(request.url, - 'https://bucket.s3.amazonaws.com/key.txt') - - class TestInstanceCache(unittest.TestCase): class DummyClass(object): def __init__(self, cache):