diff --git a/changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml b/changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml new file mode 100644 index 00000000000..6051a344d5e --- /dev/null +++ b/changelogs/fragments/1881-allow-s3_object-to-specify-content-type-in-metadata.yml @@ -0,0 +1,3 @@ +bugfixes: + - s3_object - when doing a put and specifying ``Content-Type`` in metadata, this module (since 6.0.0) erroneously set the ``Content-Type`` to ``None`` causing the put to fail. + Fix now correctly honours the specified ``Content-Type`` (https://github.com/ansible-collections/amazon.aws/issues/1881). diff --git a/plugins/modules/s3_object.py b/plugins/modules/s3_object.py index 8dd8275ffd7..0adb2e8bbaa 100644 --- a/plugins/modules/s3_object.py +++ b/plugins/modules/s3_object.py @@ -654,15 +654,14 @@ def path_check(path): return False -def get_content_type(src, present=True): - if not present: - content_type = None - if src: - content_type = mimetypes.guess_type(src)[0] - if content_type is None: - # s3 default content type - content_type = "binary/octet-stream" - return content_type +def guess_content_type(src): + if src: + content_type = mimetypes.guess_type(src)[0] + if content_type: + return content_type + + # S3 default content type + return "binary/octet-stream" def get_extra_params( @@ -747,7 +746,8 @@ def upload_s3file( elif isinstance(permissions, list): extra["ACL"] = permissions[0] - extra["ContentType"] = get_content_type(src, present=extra.get("ContentType")) + if "ContentType" not in extra: + extra["ContentType"] = guess_content_type(src) if src: s3.upload_file(aws_retry=True, Filename=src, Bucket=bucket, Key=obj, ExtraArgs=extra) diff --git a/tests/integration/targets/s3_object/tasks/main.yml b/tests/integration/targets/s3_object/tasks/main.yml index cb7b89bd389..8cb9970ab70 100644 --- a/tests/integration/targets/s3_object/tasks/main.yml +++ b/tests/integration/targets/s3_object/tasks/main.yml @@ -458,6 +458,34 @@ - "'Object deleted from bucket' in result.msg" - result is changed + - name: test putting an object in the bucket with metadata set + s3_object: + bucket: "{{ bucket_name }}" + mode: put + src: "{{ remote_tmp_dir }}/upload.txt" + metadata: "Content-Type=text/plain" + object: delete_meta.txt + tags: + "lowercase spaced": "hello cruel world" + "Title Case": "Hello Cruel World" + retries: 3 + delay: 3 + register: result + + - assert: + that: + - result is changed + - result.msg == "PUT operation complete" + + - name: test delobj to just delete an object in the bucket + s3_object: + bucket: "{{ bucket_name }}" + mode: delobj + object: delete_meta.txt + retries: 3 + delay: 3 + register: result + - name: test putting an encrypted object in the bucket s3_object: bucket: "{{ bucket_name }}"