)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15719776ed49da3d1a579f556946b9fc43ffb632","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Tim Burke \u003ctim.burke@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2025-01-24 14:08:39 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"s3api: Test with newer boto3 \u0026c"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Apparently Content-MD5 is no longer strictly required by AWS?"},{"line_number":10,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"0620f000_4082d76e","line":7,"updated":"2025-02-10 21:13:00.000000000","message":"FWIW I\u0027ve never seen etc abbreviated this way, as best I can grep (accounting for the obvious and common usage of usage of /etc and etc/) we\u0027ve abbreviated et cetera in our commit messages ~40 times as etc. and never as \u0026c\n\nTIL\n\nhttps://en.wikipedia.org/wiki/Et_cetera","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fadc5e22d49082414f7bf73d01e4138429966302","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Tim Burke \u003ctim.burke@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2025-01-24 14:08:39 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"s3api: Test with newer boto3 \u0026c"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Apparently Content-MD5 is no longer strictly required by AWS?"},{"line_number":10,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"c698f9c3_20ffd030","line":7,"in_reply_to":"0620f000_4082d76e","updated":"2025-02-11 18:17:13.000000000","message":"Done; may as well be specific.\n\nAlso re-arranged the commit message; the up-revving for tests is almost a drive-by -- the functional change ought to be the lede.","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":10,"context_line":"Apparently Content-MD5 is no longer strictly required by AWS? Or maybe"},{"line_number":11,"context_line":"it never was, provided the client sent a SHA256 of the content."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This also allows us to test with newer boto3, botocore, s3transfer."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-Authored-By: Clay Gerrard \u003cclay.gerrard@gmail.com\u003e"},{"line_number":16,"context_line":"Change-Id: Ifbcde9820bee72d80cab0fe3e67ea0f5817df949"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"1101902e_6e6cb8d9","line":13,"updated":"2025-02-14 20:44:59.000000000","message":"ah, yes this is all correct - actually if you just REMOVE the misleading comment I think the git blame will stand on it\u0027s own for anyone that needs additional context.","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":10,"context_line":"Apparently Content-MD5 is no longer strictly required by AWS? Or maybe"},{"line_number":11,"context_line":"it never was, provided the client sent a SHA256 of the content."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This also allows us to test with newer boto3, botocore, s3transfer."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Co-Authored-By: Clay Gerrard \u003cclay.gerrard@gmail.com\u003e"},{"line_number":16,"context_line":"Change-Id: Ifbcde9820bee72d80cab0fe3e67ea0f5817df949"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"8a75375f_169429a7","line":13,"in_reply_to":"1101902e_6e6cb8d9","updated":"2025-02-14 21:58:35.000000000","message":"Done","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15719776ed49da3d1a579f556946b9fc43ffb632","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"0f2673c6_3288b838","updated":"2025-02-10 21:13:00.000000000","message":"Now is better than never.\nAlthough never is often better than *right* now.","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c486fcaf5c3f34640ba6605feed4e12099d34d3e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"98f01aaf_671120bc","updated":"2025-01-27 18:21:47.000000000","message":"check experimental","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"311722c3ce69564b0c6d5ec4d84aaa29d3a46c75","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"9abbb966_6873431b","updated":"2025-01-25 04:22:13.000000000","message":"recheck\n\ngrenade failure looks unrelated; not sure what\u0027s up with the probe test failure -- `Object returning 503 for []` doesn\u0027t make a lick of sense.","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"53e93927e82bb5f3955b43aa9f2b30bc3e82e1e3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"473afb4e_8ba3a439","updated":"2025-01-28 16:16:33.000000000","message":"this doesn\u0027t fix the aws-chunked transfer issue with latest boto\n\n```\nvagrant@saio:~$ aws s3 cp test s3://s3test/obj2\nupload failed: ./test to s3://s3test/obj2 An error occurred (InvalidArgument) when calling the PutObject operation: x-amz-content-sha256 must be UNSIGNED-PAYLOAD, or a valid sha256 value.\n```\n\nwhat DOES it fix exactly?  Needs tests.","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"822dbfa47406e29c80faba481e56a615917a3c8c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d1e1eee6_70ec9742","in_reply_to":"473afb4e_8ba3a439","updated":"2025-01-28 17:01:33.000000000","message":"It fixes the ceph s3 tests that [have been failing for two weeks](https://zuul.opendev.org/t/openstack/builds?job_name\u003dswift-tox-func-s3api-ceph-s3tests-tempauth).","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"66a8599851700af4a2f04a4fa0b38f84f689572f","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8fc7a018_b89b3ba8","updated":"2025-02-13 23:14:06.000000000","message":"I also ran into this error while debugging https://review.opendev.org/c/openstack/swift/+/836755:\n```\ntest/s3api/test_input_errors.py:1764 (TestV4AuthHeaders.test_no_md5_streaming_unsigned_multiple_trailers)\ncls \u003d \u003cclass \u0027test.s3api.test_input_errors.TestV4AuthHeaders\u0027\u003e\n\n    @classmethod\n    def tearDownClass(cls):\n        client \u003d cls.get_s3_client(1)\n\u003e       cls.clear_account(client)\n\n__init__.py:271: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n__init__.py:246: in clear_account\n    cls.clear_bucket(client, bucket[\u0027Name\u0027])\n__init__.py:201: in clear_bucket\n    cls._remove_all_object_versions_from_bucket(client, bucket_name)\n__init__.py:183: in _remove_all_object_versions_from_bucket\n    del_resp \u003d client.delete_objects(Bucket\u003dbucket_name,\n../../venv/lib/python3.8/site-packages/botocore/client.py:569: in _api_call\n    return self._make_api_call(operation_name, kwargs)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself \u003d \u003cbotocore.client.S3 object at 0x108ef1790\u003e\noperation_name \u003d \u0027DeleteObjects\u0027\napi_params \u003d {\u0027Bucket\u0027: \u0027s3api-test-test-bucket-203b6c1710694163978b32991d91d37d\u0027, \u0027Delete\u0027: {\u0027Objects\u0027: [{\u0027Key\u0027: \u0027s3api-test-get-o...\u0027null\u0027}, {\u0027Key\u0027: \u0027s3api-test-get-object-9ca9fdbe52f842fc8e26a401572f4257\u0027, \u0027VersionId\u0027: \u0027null\u0027}, ...], \u0027Quiet\u0027: False}}\n\n    def _make_api_call(self, operation_name, api_params):\n        operation_model \u003d self._service_model.operation_model(operation_name)\n        service_name \u003d self._service_model.service_name\n        history_recorder.record(\n            \u0027API_CALL\u0027,\n            {\n                \u0027service\u0027: service_name,\n                \u0027operation\u0027: operation_name,\n                \u0027params\u0027: api_params,\n            },\n        )\n        if operation_model.deprecated:\n            logger.debug(\n                \u0027Warning: %s.%s() is deprecated\u0027, service_name, operation_name\n            )\n        request_context \u003d {\n            \u0027client_region\u0027: self.meta.region_name,\n            \u0027client_config\u0027: self.meta.config,\n            \u0027has_streaming_input\u0027: operation_model.has_streaming_input,\n            \u0027auth_type\u0027: operation_model.resolved_auth_type,\n            \u0027unsigned_payload\u0027: operation_model.unsigned_payload,\n        }\n    \n        api_params \u003d self._emit_api_params(\n            api_params\u003dapi_params,\n            operation_model\u003doperation_model,\n            context\u003drequest_context,\n        )\n        (\n            endpoint_url,\n            additional_headers,\n            properties,\n        ) \u003d self._resolve_endpoint_ruleset(\n            operation_model, api_params, request_context\n        )\n        if properties:\n            # Pass arbitrary endpoint info with the Request\n            # for use during construction.\n            request_context[\u0027endpoint_properties\u0027] \u003d properties\n        request_dict \u003d self._convert_to_request_dict(\n            api_params\u003dapi_params,\n            operation_model\u003doperation_model,\n            endpoint_url\u003dendpoint_url,\n            context\u003drequest_context,\n            headers\u003dadditional_headers,\n        )\n        resolve_checksum_context(request_dict, operation_model, api_params)\n    \n        service_id \u003d self._service_model.service_id.hyphenize()\n        handler, event_response \u003d self.meta.events.emit_until_response(\n            f\u0027before-call.{service_id}.{operation_name}\u0027,\n            model\u003doperation_model,\n            params\u003drequest_dict,\n            request_signer\u003dself._request_signer,\n            context\u003drequest_context,\n        )\n    \n        if event_response is not None:\n            http, parsed_response \u003d event_response\n        else:\n            maybe_compress_request(\n                self.meta.config, request_dict, operation_model\n            )\n            apply_request_checksum(request_dict)\n            http, parsed_response \u003d self._make_request(\n                operation_model, request_dict, request_context\n            )\n    \n        self.meta.events.emit(\n            f\u0027after-call.{service_id}.{operation_name}\u0027,\n            http_response\u003dhttp,\n            parsed\u003dparsed_response,\n            model\u003doperation_model,\n            context\u003drequest_context,\n        )\n    \n        if http.status_code \u003e\u003d 300:\n            error_info \u003d parsed_response.get(\"Error\", {})\n            error_code \u003d error_info.get(\"QueryErrorCode\") or error_info.get(\n                \"Code\"\n            )\n            error_class \u003d self.exceptions.from_code(error_code)\n\u003e           raise error_class(parsed_response, operation_name)\nE           botocore.errorfactory.InvalidRequest: An error occurred (InvalidRequest) when calling the DeleteObjects operation: Missing required header for this request: Content-MD5\n\n../../venv/lib/python3.8/site-packages/botocore/client.py:1023: InvalidRequest\n```","commit_id":"973c2e6eb428ad32312144bc1fd0708f1b0f209a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fadc5e22d49082414f7bf73d01e4138429966302","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"0efd39a8_410a27fd","updated":"2025-02-11 18:17:13.000000000","message":"Thanks for the tests! Sorry I hadn\u0027t gotten around to them yet.","commit_id":"973c2e6eb428ad32312144bc1fd0708f1b0f209a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"67a2f6b6_3eb37902","in_reply_to":"8fc7a018_b89b3ba8","updated":"2025-02-14 21:58:35.000000000","message":"I think that makes sense, the compat tests use boto3 and multi-delete during teardown - so they would have been making multi-delete requests with content-sha256 instead of content-md5 (which probably work just fine on AWS)","commit_id":"973c2e6eb428ad32312144bc1fd0708f1b0f209a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1d8a8715_d5b1ca1f","updated":"2025-02-14 20:44:59.000000000","message":"this is probably good enough.\n\nplease remove/correct the confusing/misleading comment and consider extending/correcting the \"bad\" sha256 test.","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"90220acf_5e225e47","updated":"2025-02-14 21:58:35.000000000","message":"it this the greatest change ever?  I think it it might be.\n\nBut maybe only b/c @tburke@nvidia.com attributed co-blame to me?  The truth is I just (barely) helped with the tests - he figured out what was going on.\n\nThis is great progress on the related bug (thanks for adding that tim!).  The change is very surgical and commented.  The new tests look quite adequate.  Earlier versions worked for me locally and I assume the functional testing in the gate will succeed.\n\nGetting the failing non-voting ceph compat tests working again AND up-reving the pin on the swift/test/s3api cross-compat suite so we can start digging into the SSL/aws-chunked failures with newest boto3 is also the correct thing to do IMHO and quite helpful.\n\nlet\u0027s keep going!","commit_id":"a5db202c552e22db6de0a7f3eb6e439e88cb97bc"}],"swift/common/middleware/s3api/controllers/multi_delete.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"            if \u0027x-amz-content-sha256\u0027 not in req.headers:"},{"line_number":81,"context_line":"                # Apparently Content-MD5 is only required for v2-signed"},{"line_number":82,"context_line":"                # requests?"},{"line_number":83,"context_line":"                # TODO: investigate further with UNSIGNED-PAYLOAD and chunked"},{"line_number":84,"context_line":"                # transfers w/ \u0026 w/o checksums"},{"line_number":85,"context_line":"                req.check_md5(xml)"}],"source_content_type":"text/x-python","patch_set":4,"id":"0bc39f1c_9ba83d75","line":82,"updated":"2025-02-14 20:44:59.000000000","message":"I\u0027m not actually sure if v2 required/requires content-md5 or not; it *seems* like these tests are MOSTLY just telling us that IF the client is doing sig4 AND sending content-sha256... that it\u0027s ok to NOT send content-md5 (at least for this one request)\n\nI would prefer that this said:\n\n```\nif \u0027x-amz-content-sha256\u0027 not in req.headers:\n   # the x-amz-content-sha256 checksum appears to be validated and enforced\n   # earlier in the request processing ...\n   # ... at least for signv4 (which is the majority of our requests and\n   # the only one we\u0027ve tested)\n   # since we have functests that won\u0027t send content-md5 header anymore with\n   # newer boto versions, but they WILL send content-sha256:\n   #    we can not fail this request for missing a content-md5 header\n   # ... but are confident the sha256 checksumming is happening (somewhere)\n   req.check_md5(xml)\n```","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"            if \u0027x-amz-content-sha256\u0027 not in req.headers:"},{"line_number":81,"context_line":"                # Apparently Content-MD5 is only required for v2-signed"},{"line_number":82,"context_line":"                # requests?"},{"line_number":83,"context_line":"                # TODO: investigate further with UNSIGNED-PAYLOAD and chunked"},{"line_number":84,"context_line":"                # transfers w/ \u0026 w/o checksums"},{"line_number":85,"context_line":"                req.check_md5(xml)"}],"source_content_type":"text/x-python","patch_set":4,"id":"1f87fb1e_7c2cb274","line":82,"in_reply_to":"0bc39f1c_9ba83d75","updated":"2025-02-14 21:58:35.000000000","message":"Done","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":82,"context_line":"                # requests?"},{"line_number":83,"context_line":"                # TODO: investigate further with UNSIGNED-PAYLOAD and chunked"},{"line_number":84,"context_line":"                # transfers w/ \u0026 w/o checksums"},{"line_number":85,"context_line":"                req.check_md5(xml)"},{"line_number":86,"context_line":"            elem \u003d fromstring(xml, \u0027Delete\u0027, self.logger)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"            quiet \u003d elem.find(\u0027./Quiet\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"db5bc0f3_94069db3","line":85,"updated":"2025-02-14 20:44:59.000000000","message":"I don\u0027t think the TODO belongs in the source code so much as in our issue tracker.","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                # requests?"},{"line_number":83,"context_line":"                # TODO: investigate further with UNSIGNED-PAYLOAD and chunked"},{"line_number":84,"context_line":"                # transfers w/ \u0026 w/o checksums"},{"line_number":85,"context_line":"                req.check_md5(xml)"},{"line_number":86,"context_line":"            elem \u003d fromstring(xml, \u0027Delete\u0027, self.logger)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"            quiet \u003d elem.find(\u0027./Quiet\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5928bd6e_896d6262","line":85,"in_reply_to":"db5bc0f3_94069db3","updated":"2025-02-14 21:58:35.000000000","message":"Done","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"15719776ed49da3d1a579f556946b9fc43ffb632","unresolved":true,"context_lines":[{"line_number":964,"context_line":""},{"line_number":965,"context_line":"    def check_md5(self, body):"},{"line_number":966,"context_line":"        if \u0027HTTP_X_AMZ_CONTENT_SHA256\u0027 in self.environ:"},{"line_number":967,"context_line":"            return  # Good enough, hopefully!"},{"line_number":968,"context_line":""},{"line_number":969,"context_line":"        if \u0027HTTP_CONTENT_MD5\u0027 not in self.environ:"},{"line_number":970,"context_line":"            raise InvalidRequest(\u0027Missing required header for this request: \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"68d85ad3_89b76871","line":967,"updated":"2025-02-10 21:13:00.000000000","message":"as best I can tell this is only called from multi_delete.py; and Tim has explained to me those are the tests that are failing with ceph and in our s3-cross-compat cleanup.\n\nPerhaps it would be better to fix it at the call-site rather than this \"generic\" (sounding?) helper to make it more obvious what this fix is for?\n\n... esp since having a helper called \"check_md5\" noop when a sha256 related content header is *present* is rather strange.\n\nFWIW it looks like we are validing the content-sha256 header *somewhere* when it\u0027s provided:\n\n941157: sq: some tests for multi-delete-fix | https://review.opendev.org/c/openstack/swift/+/941157\n\nDo we not currently checksum content-md5 on other POSTS with a body like complete-mpu?  Should we just do that when the header is provided next to where we\u0027re doing the sha256 business?","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":964,"context_line":""},{"line_number":965,"context_line":"    def check_md5(self, body):"},{"line_number":966,"context_line":"        if \u0027HTTP_X_AMZ_CONTENT_SHA256\u0027 in self.environ:"},{"line_number":967,"context_line":"            return  # Good enough, hopefully!"},{"line_number":968,"context_line":""},{"line_number":969,"context_line":"        if \u0027HTTP_CONTENT_MD5\u0027 not in self.environ:"},{"line_number":970,"context_line":"            raise InvalidRequest(\u0027Missing required header for this request: \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"012d1a52_d1d436f2","line":967,"in_reply_to":"22bb41b6_f13515c9","updated":"2025-02-14 21:58:35.000000000","message":"Acknowledged","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fadc5e22d49082414f7bf73d01e4138429966302","unresolved":true,"context_lines":[{"line_number":964,"context_line":""},{"line_number":965,"context_line":"    def check_md5(self, body):"},{"line_number":966,"context_line":"        if \u0027HTTP_X_AMZ_CONTENT_SHA256\u0027 in self.environ:"},{"line_number":967,"context_line":"            return  # Good enough, hopefully!"},{"line_number":968,"context_line":""},{"line_number":969,"context_line":"        if \u0027HTTP_CONTENT_MD5\u0027 not in self.environ:"},{"line_number":970,"context_line":"            raise InvalidRequest(\u0027Missing required header for this request: \u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"22bb41b6_f13515c9","line":967,"in_reply_to":"68d85ad3_89b76871","updated":"2025-02-11 18:17:13.000000000","message":"\u003e Do we not currently checksum content-md5 on other POSTS with a body like complete-mpu?\n\nYeah, we should really do some MD5 validation in https://github.com/openstack/swift/blob/2.34.0/swift/common/middleware/s3api/s3request.py#L935 ...\n\nI definitely think this all could use more investigation, but I\u0027m also a fan of getting a minimal fix in _first_ to get all our tests passing (even the non-voting ceph-tests), up-rev packages used in the gate, and fix dev envs that weren\u0027t set up with our (slightly out-dated) `py3-constraints.txt`, then dig in and get it all straightened out **after**.\n\nSeparately, I should also look at up-rev\u0027ing the version of the ceph-tests used -- I last did that ~3 years and 200+ commits ago.","commit_id":"226b43855e81891b18b906bcdfaa29da2c70ba4b"}],"test/unit/common/middleware/s3api/test_multi_delete.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":51,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":52,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":53,"context_line":"        content_md5 \u003d base64.b64encode("},{"line_number":54,"context_line":"            md5(body, usedforsecurity\u003dFalse).digest()).strip()"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":57,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"015bc195_fa4a4b52","line":54,"updated":"2025-02-14 20:44:59.000000000","message":"FWIW it\u0027s correct to send content-md5 as base64 encoded digest IME","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":52,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":53,"context_line":"        content_md5 \u003d base64.b64encode("},{"line_number":54,"context_line":"            md5(body, usedforsecurity\u003dFalse).digest()).strip()"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":57,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"1b4e32ef_443ce864","line":54,"in_reply_to":"015bc195_fa4a4b52","updated":"2025-02-14 21:58:35.000000000","message":"Acknowledged","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        obj \u003d SubElement(elem, \u0027Object\u0027)"},{"line_number":88,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":89,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":90,"context_line":"        content_sha256 \u003d \u0027invalid\u0027"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":93,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"74c56101_b6c2de2f","line":90,"updated":"2025-02-14 20:44:59.000000000","message":"we could also send this as `deadbeef` if we want to show it\u0027s not just \"non-hex-data\" that will 400, but ANY hex data !\u003d the sha-256 hex of the content.","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        obj \u003d SubElement(elem, \u0027Object\u0027)"},{"line_number":88,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":89,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":90,"context_line":"        content_sha256 \u003d \u0027invalid\u0027"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":93,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"5ad589ce_4efab969","line":90,"in_reply_to":"74c56101_b6c2de2f","updated":"2025-02-14 21:58:35.000000000","message":"Acknowledged","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":110,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":111,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":112,"context_line":"        content_sha256 \u003d base64.b64encode("},{"line_number":113,"context_line":"            hashlib.sha256(body[:-1]).digest()).strip()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":116,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"a4c1d01d_bb9cc3fd","line":113,"updated":"2025-02-14 20:44:59.000000000","message":"so \"bad\" here means it\u0027s base64 encoded?  Or they didn\u0027t sha256 the whole body?  In which way is this test trying to demonstrate the client is wrong?","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":111,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":112,"context_line":"        content_sha256 \u003d base64.b64encode("},{"line_number":113,"context_line":"            hashlib.sha256(body[:-1]).digest()).strip()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":116,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"d1ff2d1b_a25a7a07","line":113,"in_reply_to":"a4c1d01d_bb9cc3fd","updated":"2025-02-14 21:58:35.000000000","message":"seems like the intent was \"didn\u0027t sha256 the whole body\" - which is probably a good test that should be included - we want the content-sha256 header to *look* as valid as possible; but just be *wrong*","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fd3aba8234c61a836c2b4392c57b799341c61d75","unresolved":true,"context_lines":[{"line_number":133,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":134,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":135,"context_line":"        content_sha256 \u003d hashlib.sha256(body).hexdigest()"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":138,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"},{"line_number":139,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"930556d7_6355f602","line":136,"updated":"2025-02-14 20:44:59.000000000","message":"In my testing clients send the content-sha256 value as the raw hexdigest.","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a02961e00997dd7e38d68595e6fba69fe00f4fdd","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        SubElement(obj, \u0027Key\u0027).text \u003d \u0027object\u0027"},{"line_number":134,"context_line":"        body \u003d tostring(elem, use_s3ns\u003dFalse)"},{"line_number":135,"context_line":"        content_sha256 \u003d hashlib.sha256(body).hexdigest()"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"        req \u003d Request.blank(\u0027/bucket/object?delete\u0027,"},{"line_number":138,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"},{"line_number":139,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"c09d5fe3_b0b169ac","line":136,"in_reply_to":"930556d7_6355f602","updated":"2025-02-14 21:58:35.000000000","message":"Acknowledged","commit_id":"f376eb1c41c0826ece8239fc2d0eb5766f111151"}]}
