Fix: ListObjectsV2 behaving differently than AWS API (#3545)
* fix : localstack issue https://github.com/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+language%3Ago * add assertion for error message as well
This commit is contained in:
parent
e6be3265ca
commit
dffc0e449c
@ -424,3 +424,15 @@ class InvalidRange(S3ClientError):
|
|||||||
actual_size=actual_size,
|
actual_size=actual_size,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidContinuationToken(S3ClientError):
|
||||||
|
code = 400
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(InvalidContinuationToken, self).__init__(
|
||||||
|
"InvalidArgument",
|
||||||
|
"The continuation token provided is incorrect",
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
@ -25,6 +25,7 @@ from moto.s3bucket_path.utils import (
|
|||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
BucketAlreadyExists,
|
BucketAlreadyExists,
|
||||||
DuplicateTagKeys,
|
DuplicateTagKeys,
|
||||||
|
InvalidContinuationToken,
|
||||||
S3ClientError,
|
S3ClientError,
|
||||||
MissingBucket,
|
MissingBucket,
|
||||||
MissingKey,
|
MissingKey,
|
||||||
@ -529,6 +530,10 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
|||||||
template = self.response_template(S3_BUCKET_GET_RESPONSE_V2)
|
template = self.response_template(S3_BUCKET_GET_RESPONSE_V2)
|
||||||
bucket = self.backend.get_bucket(bucket_name)
|
bucket = self.backend.get_bucket(bucket_name)
|
||||||
|
|
||||||
|
continuation_token = querystring.get("continuation-token", [None])[0]
|
||||||
|
if continuation_token is not None and continuation_token == "":
|
||||||
|
raise InvalidContinuationToken()
|
||||||
|
|
||||||
prefix = querystring.get("prefix", [None])[0]
|
prefix = querystring.get("prefix", [None])[0]
|
||||||
if prefix and isinstance(prefix, six.binary_type):
|
if prefix and isinstance(prefix, six.binary_type):
|
||||||
prefix = prefix.decode("utf-8")
|
prefix = prefix.decode("utf-8")
|
||||||
@ -539,7 +544,6 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
|||||||
|
|
||||||
fetch_owner = querystring.get("fetch-owner", [False])[0]
|
fetch_owner = querystring.get("fetch-owner", [False])[0]
|
||||||
max_keys = int(querystring.get("max-keys", [1000])[0])
|
max_keys = int(querystring.get("max-keys", [1000])[0])
|
||||||
continuation_token = querystring.get("continuation-token", [None])[0]
|
|
||||||
start_after = querystring.get("start-after", [None])[0]
|
start_after = querystring.get("start-after", [None])[0]
|
||||||
|
|
||||||
# sort the combination of folders and keys into lexicographical order
|
# sort the combination of folders and keys into lexicographical order
|
||||||
|
@ -1809,6 +1809,32 @@ def test_boto3_list_objects_v2_common_prefix_pagination():
|
|||||||
assert prefixes == [k[: k.rindex("/") + 1] for k in keys]
|
assert prefixes == [k[: k.rindex("/") + 1] for k in keys]
|
||||||
|
|
||||||
|
|
||||||
|
@mock_s3
|
||||||
|
def test_boto3_list_objects_v2_common_invalid_continuation_token():
|
||||||
|
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
||||||
|
s3.create_bucket(Bucket="mybucket")
|
||||||
|
|
||||||
|
max_keys = 1
|
||||||
|
keys = ["test/{i}/{i}".format(i=i) for i in range(3)]
|
||||||
|
for key in keys:
|
||||||
|
s3.put_object(Bucket="mybucket", Key=key, Body=b"v")
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"Bucket": "mybucket",
|
||||||
|
"Delimiter": "/",
|
||||||
|
"Prefix": "test/",
|
||||||
|
"MaxKeys": max_keys,
|
||||||
|
"ContinuationToken": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
with pytest.raises(botocore.exceptions.ClientError) as exc:
|
||||||
|
s3.list_objects_v2(**args)
|
||||||
|
exc.value.response["Error"]["Code"].should.equal("InvalidArgument")
|
||||||
|
exc.value.response["Error"]["Message"].should.equal(
|
||||||
|
"The continuation token provided is incorrect"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_s3
|
@mock_s3
|
||||||
def test_boto3_list_objects_v2_truncated_response():
|
def test_boto3_list_objects_v2_truncated_response():
|
||||||
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
||||||
|
Loading…
Reference in New Issue
Block a user