From e0304bc5000620262746dcdc15422b51740cd7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Sznuk?= Date: Wed, 28 Aug 2019 16:17:45 +0200 Subject: [PATCH] Allows leading // for mocked s3 paths (#1637). --- moto/s3/urls.py | 2 ++ moto/server.py | 5 +++-- tests/test_s3/test_s3.py | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/moto/s3/urls.py b/moto/s3/urls.py index fa81568a4..1388c81e5 100644 --- a/moto/s3/urls.py +++ b/moto/s3/urls.py @@ -15,4 +15,6 @@ url_paths = { '{0}/(?P[^/]+)/?$': S3ResponseInstance.ambiguous_response, # path-based bucket + key '{0}/(?P[^/]+)/(?P.+)': S3ResponseInstance.key_response, + # subdomain bucket + key with empty first part of path + '{0}//(?P.*)$': S3ResponseInstance.key_response, } diff --git a/moto/server.py b/moto/server.py index 89be47093..b245f6e6f 100644 --- a/moto/server.py +++ b/moto/server.py @@ -174,10 +174,11 @@ def create_backend_app(service): backend_app.url_map.converters['regex'] = RegexConverter backend = list(BACKENDS[service].values())[0] for url_path, handler in backend.flask_paths.items(): + view_func = convert_flask_to_httpretty_response(handler) if handler.__name__ == 'dispatch': endpoint = '{0}.dispatch'.format(handler.__self__.__name__) else: - endpoint = None + endpoint = view_func.__name__ original_endpoint = endpoint index = 2 @@ -191,7 +192,7 @@ def create_backend_app(service): url_path, endpoint=endpoint, methods=HTTP_METHODS, - view_func=convert_flask_to_httpretty_response(handler), + view_func=view_func, strict_slashes=False, ) diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py index cd57fc92b..0c0721f01 100644 --- a/tests/test_s3/test_s3.py +++ b/tests/test_s3/test_s3.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import datetime +import os from six.moves.urllib.request import urlopen from six.moves.urllib.error import HTTPError from functools import wraps @@ -23,6 +24,7 @@ from freezegun import freeze_time import six import requests import tests.backport_assert_raises # noqa +from nose import SkipTest from nose.tools import assert_raises import sure # noqa @@ -2991,3 +2993,28 @@ def test_accelerate_configuration_is_not_supported_when_bucket_name_has_dots(): AccelerateConfiguration={'Status': 'Enabled'}, ) exc.exception.response['Error']['Code'].should.equal('InvalidRequest') + +def store_and_read_back_a_key(key): + s3 = boto3.client('s3', region_name='us-east-1') + bucket_name = 'mybucket' + body = b'Some body' + + s3.create_bucket(Bucket=bucket_name) + s3.put_object( + Bucket=bucket_name, + Key=key, + Body=body + ) + + response = s3.get_object(Bucket=bucket_name, Key=key) + response['Body'].read().should.equal(body) + +@mock_s3 +def test_paths_with_leading_slashes_work(): + store_and_read_back_a_key('/a-key') + +@mock_s3 +def test_root_dir_with_empty_name_works(): + if os.environ.get('TEST_SERVER_MODE', 'false').lower() == 'true': + raise SkipTest('Does not work in server mode due to error in Workzeug') + store_and_read_back_a_key('/')