#2567 - When mocking URLs, always return the first match
This commit is contained in:
parent
f009f7da8c
commit
47349b30df
@ -7,6 +7,7 @@ import inspect
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
|
import types
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from botocore.handlers import BUILTIN_HANDLERS
|
from botocore.handlers import BUILTIN_HANDLERS
|
||||||
@ -217,12 +218,29 @@ botocore_mock = responses.RequestsMock(
|
|||||||
assert_all_requests_are_fired=False,
|
assert_all_requests_are_fired=False,
|
||||||
target="botocore.vendored.requests.adapters.HTTPAdapter.send",
|
target="botocore.vendored.requests.adapters.HTTPAdapter.send",
|
||||||
)
|
)
|
||||||
|
|
||||||
responses_mock = responses._default_mock
|
responses_mock = responses._default_mock
|
||||||
# Add passthrough to allow any other requests to work
|
# Add passthrough to allow any other requests to work
|
||||||
# Since this uses .startswith, it applies to http and https requests.
|
# Since this uses .startswith, it applies to http and https requests.
|
||||||
responses_mock.add_passthru("http")
|
responses_mock.add_passthru("http")
|
||||||
|
|
||||||
|
|
||||||
|
def _find_first_match(self, request):
|
||||||
|
for i, match in enumerate(self._matches):
|
||||||
|
if match.matches(request):
|
||||||
|
return match
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# Modify behaviour of the matcher to only/always return the first match
|
||||||
|
# Default behaviour is to return subsequent matches for subsequent requests, which leads to https://github.com/spulec/moto/issues/2567
|
||||||
|
# - First request matches on the appropriate S3 URL
|
||||||
|
# - Same request, executed again, will be matched on the subsequent match, which happens to be the catch-all, not-yet-implemented, callback
|
||||||
|
# Fix: Always return the first match
|
||||||
|
responses_mock._find_match = types.MethodType(_find_first_match, responses_mock)
|
||||||
|
|
||||||
|
|
||||||
BOTOCORE_HTTP_METHODS = ["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
|
BOTOCORE_HTTP_METHODS = ["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ import moto.s3.models as s3model
|
|||||||
from moto.core.exceptions import InvalidNextTokenException
|
from moto.core.exceptions import InvalidNextTokenException
|
||||||
from moto.core.utils import py2_strip_unicode_keys
|
from moto.core.utils import py2_strip_unicode_keys
|
||||||
|
|
||||||
|
|
||||||
if settings.TEST_SERVER_MODE:
|
if settings.TEST_SERVER_MODE:
|
||||||
REDUCED_PART_SIZE = s3model.UPLOAD_PART_MIN_SIZE
|
REDUCED_PART_SIZE = s3model.UPLOAD_PART_MIN_SIZE
|
||||||
EXPECTED_ETAG = '"140f92a6df9f9e415f74a1463bcee9bb-2"'
|
EXPECTED_ETAG = '"140f92a6df9f9e415f74a1463bcee9bb-2"'
|
||||||
@ -1018,12 +1019,23 @@ def test_s3_object_in_public_bucket():
|
|||||||
s3_anonymous.Object(key="file.txt", bucket_name="test-bucket").get()
|
s3_anonymous.Object(key="file.txt", bucket_name="test-bucket").get()
|
||||||
exc.exception.response["Error"]["Code"].should.equal("403")
|
exc.exception.response["Error"]["Code"].should.equal("403")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_s3
|
||||||
|
def test_s3_object_in_public_bucket_using_multiple_presigned_urls():
|
||||||
|
s3 = boto3.resource("s3")
|
||||||
|
bucket = s3.Bucket("test-bucket")
|
||||||
|
bucket.create(
|
||||||
|
ACL="public-read", CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
|
||||||
|
)
|
||||||
|
bucket.put_object(Body=b"ABCD", Key="file.txt")
|
||||||
|
|
||||||
params = {"Bucket": "test-bucket", "Key": "file.txt"}
|
params = {"Bucket": "test-bucket", "Key": "file.txt"}
|
||||||
presigned_url = boto3.client("s3").generate_presigned_url(
|
presigned_url = boto3.client("s3").generate_presigned_url(
|
||||||
"get_object", params, ExpiresIn=900
|
"get_object", params, ExpiresIn=900
|
||||||
)
|
)
|
||||||
|
for i in range(1, 10):
|
||||||
response = requests.get(presigned_url)
|
response = requests.get(presigned_url)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200, "Failed on req number {}".format(i)
|
||||||
|
|
||||||
|
|
||||||
@mock_s3
|
@mock_s3
|
||||||
|
Loading…
Reference in New Issue
Block a user