)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":true,"context_lines":[{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This covers both \"normal\" objects and part-uploads for MPUs, but since"},{"line_number":13,"context_line":"we don\u0027t write anything down, we can\u0027t do any verification during"},{"line_number":14,"context_line":"complete-MPU calls."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"crc64nvme checksums are not yet supported; clients attempting to use"},{"line_number":17,"context_line":"them will get back 501s."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":38,"id":"6b9736bf_37be378f","line":14,"updated":"2025-06-25 21:10:58.000000000","message":"probably also worth to mention that we are not even planning to do verification during complete-MPU? according to Alistair\u0027s test, AWS S3 CompleteMultipartUpload POST don\u0027t do this.\n\nhttps://review.opendev.org/c/openstack/swift/+/952462","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0faa46379162270361059ed30841d60e067c3a","unresolved":false,"context_lines":[{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This covers both \"normal\" objects and part-uploads for MPUs, but since"},{"line_number":13,"context_line":"we don\u0027t write anything down, we can\u0027t do any verification during"},{"line_number":14,"context_line":"complete-MPU calls."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"crc64nvme checksums are not yet supported; clients attempting to use"},{"line_number":17,"context_line":"them will get back 501s."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":38,"id":"19507502_83c50546","line":14,"in_reply_to":"26c2db2b_44d34f03","updated":"2025-06-27 01:53:44.000000000","message":"Acknowledged","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"028f9cdf860b8c14543146620f68fcd0d7b9a950","unresolved":true,"context_lines":[{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This covers both \"normal\" objects and part-uploads for MPUs, but since"},{"line_number":13,"context_line":"we don\u0027t write anything down, we can\u0027t do any verification during"},{"line_number":14,"context_line":"complete-MPU calls."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"crc64nvme checksums are not yet supported; clients attempting to use"},{"line_number":17,"context_line":"them will get back 501s."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":38,"id":"26c2db2b_44d34f03","line":14,"in_reply_to":"6b9736bf_37be378f","updated":"2025-06-26 19:42:58.000000000","message":"I think what I\u0027d meant to convey is that S3 can (I think?) do verification on complete, *but only because the checksum was provided (and written down) during the initiate call*.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cc0a0782f469707b49c4d9a0a59a313387ac488e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"43a7f5d8_85e95a90","updated":"2025-03-11 22:40:14.000000000","message":"Note that this does nothing to address the current failures against AWS in `test/s3api/test_versioning.py` -- I\u0027m increasingly convinced we want https://review.opendev.org/c/openstack/swift/+/942329","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca34e9354e7db3d5b53d29a6f6d80c1c4bb1ad8a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"604c66ad_5e27e2cc","updated":"2025-03-12 02:05:22.000000000","message":"recheck\n\nLooks like some errors fetching upper-constraints.txt:\n```\nERROR: Could not install packages due to an OSError: HTTPSConnectionPool(host\u003d\u0027opendev.org\u0027, port\u003d443): Max retries exceeded with url: /openstack/requirements/raw/branch/master/upper-constraints.txt (Caused by ResponseError(\u0027too many 500 error responses\u0027))\n```","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"24900bf49b6894887aff871689ce4de6343c00c0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"fe899cbe_26a2984c","updated":"2025-04-04 05:51:31.000000000","message":"Otherwise, this is looking really good. Love all the checksum_info with CHECKSUMS and CHECKSUM_HEADERS. It\u0027s really well done and alot more maintainable kudos!\n\nThere seems to be a dangling helper method in a test.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":22,"id":"c150aa1b_cbc13c6a","updated":"2025-04-16 11:49:51.000000000","message":"fixups in https://review.opendev.org/c/openstack/swift/+/947449","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"31c895dd0107d58f3c12fbfb2bca5e2b6b2b64bb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":34,"id":"213b07ac_e0b50685","updated":"2025-05-20 20:27:30.000000000","message":"recheck\n\nSome sort of hang dumping databases during the grenade job? Nothing to do with us; we don\u0027t even use mysql.","commit_id":"1c15130c9a3871283ce7ab61b526832005dc108a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b982231b3f424b4117e722ddca2e7fce5c1df1d4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":35,"id":"ea52c7f0_e7c8900b","updated":"2025-05-29 13:14:32.000000000","message":"checked the new s3 compat tests pass with boto3 \u003c1.36 and \u003e 1.36 against swift and s3\n\nwe have one TODO that should probably be addressed re POST handling","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"7e158317_ebd88abf","updated":"2025-06-25 21:10:58.000000000","message":"It\u0027s a large patch, I haven\u0027t finished reviewing yet. The functionalities looks correct to me so far, ``-1`` mainly because of two things that requires changes.\n1. I think the changes in multi_upload.py which fixes the validation of the MPU XML body should be a follow-on standalone patch.\n2. In S3request, there are two cases that when we compare ``self.bytes_received`` against ``self._expected_length``, I feel they should raise a different exception and they also need unit tests.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"87e0383c098f593058f76e8fd6e46d991b693182","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"0bcf59d6_01503a71","updated":"2025-06-18 01:17:14.000000000","message":"recheck\n\nLooks like some test-node troubles?","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":42,"id":"6a14ca16_23c0df46","updated":"2025-07-09 18:07:22.000000000","message":"We\u0027ve been carrying this (and the next in the chain) for months with good effect. There might be some follow-up that could be done (more cross-compat tests, spot-checking that error messages all come out with the same XML elements that AWS would send), but nothing that makes me worry about the correctness of the patch. We definitely *should* merge this ahead of the next upstream release; don\u0027t want operators in a position where they\u0027re writing down bytes that don\u0027t match client-sent checksums.","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bb3f4b761113d6b5f412d91ae5694b9dd61799d4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":42,"id":"1171a130_b442abdc","updated":"2025-07-02 08:13:55.000000000","message":"some tests got dup\u0027d w.r.t. https://review.opendev.org/c/openstack/swift/+/952391 merging","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"6a2a38b366e1d91a56f2f90c3f63ec89ca0cf7bc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":43,"id":"171f2375_560abe46","updated":"2025-07-15 17:30:19.000000000","message":"This patch provides the implementation of upload-time checksum validation only for the new S3 object integrity features, it\u0027s one of important patches in the efforts to support the chunked transfer with signature v4.\n\nNote that, for upload-time checksum validation, this patch has also limited its scope to not return any checksum in response headers for the PUT requests, it makes sense that this patch only does validation, let\u0027s not give user impression that their data and checksum are all stored.\nhttps://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":true,"context_lines":[{"line_number":704,"context_line":"                if req.headers[\u0027etag\u0027] !\u003d exp_etag.hexdigest():"},{"line_number":705,"context_line":"                    content_md5 \u003d req.headers[\u0027content-md5\u0027]"},{"line_number":706,"context_line":"                    raise BadDigest("},{"line_number":707,"context_line":"                        expected_digest\u003dcontent_md5"},{"line_number":708,"context_line":"                    )"},{"line_number":709,"context_line":"                # We\u0027re only interested in the body here, in the"},{"line_number":710,"context_line":"                # multipart-upload controller -- *don\u0027t* let it get"}],"source_content_type":"text/x-python","patch_set":38,"id":"538bfe7d_1fd98ce0","line":707,"updated":"2025-06-25 21:10:58.000000000","message":"okay, the only change here is to convert ``content_md5`` to ``expected_digest``. \n\nwhile this patch mainly focuses on adding support for new checksum algorithms (like CRC32,SHA1 and etc) that validate the integrity of the object data being uploaded, this change here fixes the validation of the XML body of the ``CompleteMultipartUpload`` itself, using the standard ``Content-MD5`` header. I feel this fix and related test cases go to a standalone patch as follow-on.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"028f9cdf860b8c14543146620f68fcd0d7b9a950","unresolved":false,"context_lines":[{"line_number":704,"context_line":"                if req.headers[\u0027etag\u0027] !\u003d exp_etag.hexdigest():"},{"line_number":705,"context_line":"                    content_md5 \u003d req.headers[\u0027content-md5\u0027]"},{"line_number":706,"context_line":"                    raise BadDigest("},{"line_number":707,"context_line":"                        expected_digest\u003dcontent_md5"},{"line_number":708,"context_line":"                    )"},{"line_number":709,"context_line":"                # We\u0027re only interested in the body here, in the"},{"line_number":710,"context_line":"                # multipart-upload controller -- *don\u0027t* let it get"}],"source_content_type":"text/x-python","patch_set":38,"id":"5c02d96b_92d98868","line":707,"in_reply_to":"538bfe7d_1fd98ce0","updated":"2025-06-26 19:42:58.000000000","message":"Revived https://review.opendev.org/c/openstack/swift/+/952391/","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"}],"swift/common/middleware/s3api/exception.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":92,"context_line":"        self.computed \u003d computed"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class S3InputChecksumMismatch(S3InputError):"},{"line_number":96,"context_line":"    \"\"\""},{"line_number":97,"context_line":"    Client provided a X-Amz-Checksum-* header, but it doesn\u0027t match the data."},{"line_number":98,"context_line":""}],"source_content_type":"text/x-python","patch_set":42,"id":"21dc395c_781cdf8c","line":95,"updated":"2025-07-09 18:07:22.000000000","message":"I should refresh my memory on why this one _doesn\u0027t_ track `expected`/`computed`...","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class S3InputChecksumInvalid(S3InputError):"},{"line_number":104,"context_line":"    \"\"\""},{"line_number":105,"context_line":"    Client provided a X-Amz-Checksum-* trailer, but it is not a valid format."},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    This should result in a InvalidRequest going back to the client."},{"line_number":108,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":42,"id":"a3601d91_de396468","line":105,"range":{"start_line":105,"start_character":39,"end_line":105,"end_character":46},"updated":"2025-07-09 18:07:22.000000000","message":"And I guess the idea is it\u0027s always a trailer because if it were a header we could just return the `InvalidRequest` directly and skip the whole inherit-from-`S3InputError`-which-inherits-from-`BaseException`-so-we-smash-the-stack-from-the-proxy-app-all-the-way-back-up-to-`s3api` thing...\n\nOnly not really 😕\n```\n        if checksum_headers:\n            checksum_header, b64digest \u003d list(checksum_headers.items())[0]\n            checksum_hasher \u003d _get_checksum_hasher(checksum_header)\n            try:\n                # early check on the value...\n                _validate_checksum_value(\n                    checksum_hasher, checksum_header, b64digest)\n            except S3InputChecksumInvalid as e:\n                raise InvalidRequest(\n                    \u0027Value for %s header is invalid.\u0027 % e.trailer)\n```","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class S3InputChecksumInvalid(S3InputError):"},{"line_number":104,"context_line":"    \"\"\""},{"line_number":105,"context_line":"    Client provided a X-Amz-Checksum-* trailer, but it is not a valid format."},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    This should result in a InvalidRequest going back to the client."},{"line_number":108,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":42,"id":"efe29ee6_4c8dd207","line":105,"range":{"start_line":105,"start_character":39,"end_line":105,"end_character":46},"in_reply_to":"a3601d91_de396468","updated":"2025-07-10 17:01:24.000000000","message":"shall we clarify? https://review.opendev.org/c/openstack/swift/+/954638","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"688b13834c91060e234f72fe4c7083c7df5c4a15","unresolved":false,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":"class S3InputChecksumInvalid(S3InputError):"},{"line_number":104,"context_line":"    \"\"\""},{"line_number":105,"context_line":"    Client provided a X-Amz-Checksum-* trailer, but it is not a valid format."},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"    This should result in a InvalidRequest going back to the client."},{"line_number":108,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":42,"id":"376301d1_ad8da1ef","line":105,"range":{"start_line":105,"start_character":39,"end_line":105,"end_character":46},"in_reply_to":"efe29ee6_4c8dd207","updated":"2025-07-11 09:36:17.000000000","message":"Done","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"}],"swift/common/middleware/s3api/s3api.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        self.logger \u003d get_logger("},{"line_number":301,"context_line":"            wsgi_conf, log_route\u003d\u0027s3api\u0027, statsd_tail_prefix\u003d\u0027s3api\u0027)"},{"line_number":302,"context_line":"        self.check_pipeline(wsgi_conf)"},{"line_number":303,"context_line":"        checksum.log_selected_implementation(self.logger)"},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"    def is_s3_cors_preflight(self, env):"},{"line_number":306,"context_line":"        if env[\u0027REQUEST_METHOD\u0027] !\u003d \u0027OPTIONS\u0027 or not env.get(\u0027HTTP_ORIGIN\u0027):"}],"source_content_type":"text/x-python","patch_set":43,"id":"fa0a91d7_da606752","line":303,"updated":"2025-07-15 16:10:59.000000000","message":"this will allow operators to check the logs to see which checksum implementation is being used.","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d86a23dd3990d94e10d0b5fe902ed50d0b0fc5dd","unresolved":true,"context_lines":[{"line_number":174,"context_line":"                 checksum_header, expected_checksum):"},{"line_number":175,"context_line":"        super().__init__(wsgi_input)"},{"line_number":176,"context_line":"        self._expected_length \u003d content_length"},{"line_number":177,"context_line":"        self.checksum_info \u003d CHECKSUMS_BY_HEADER[checksum_header]"},{"line_number":178,"context_line":"        if self.checksum_info is None:"},{"line_number":179,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":180,"context_line":"            # haven\u0027t sent a 100 Continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"366d152f_66738a51","line":177,"range":{"start_line":177,"start_character":29,"end_line":177,"end_character":65},"updated":"2025-03-13 17:48:10.000000000","message":"we already looked this up in install_checksumming_input - maybe we can just pass it in?","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":false,"context_lines":[{"line_number":174,"context_line":"                 checksum_header, expected_checksum):"},{"line_number":175,"context_line":"        super().__init__(wsgi_input)"},{"line_number":176,"context_line":"        self._expected_length \u003d content_length"},{"line_number":177,"context_line":"        self.checksum_info \u003d CHECKSUMS_BY_HEADER[checksum_header]"},{"line_number":178,"context_line":"        if self.checksum_info is None:"},{"line_number":179,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":180,"context_line":"            # haven\u0027t sent a 100 Continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"6addb163_40270720","line":177,"range":{"start_line":177,"start_character":29,"end_line":177,"end_character":65},"in_reply_to":"366d152f_66738a51","updated":"2025-03-17 15:57:59.000000000","message":"Done -- thanks","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d86a23dd3990d94e10d0b5fe902ed50d0b0fc5dd","unresolved":true,"context_lines":[{"line_number":175,"context_line":"        super().__init__(wsgi_input)"},{"line_number":176,"context_line":"        self._expected_length \u003d content_length"},{"line_number":177,"context_line":"        self.checksum_info \u003d CHECKSUMS_BY_HEADER[checksum_header]"},{"line_number":178,"context_line":"        if self.checksum_info is None:"},{"line_number":179,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":180,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":181,"context_line":"            self.wsgi_input.read(1)"}],"source_content_type":"text/x-python","patch_set":2,"id":"22f2259d_1e3e445b","line":178,"range":{"start_line":178,"start_character":8,"end_line":178,"end_character":38},"updated":"2025-03-13 17:48:10.000000000","message":"given that we just looked up ``CHECKSUMS_BY_HEADER[checksum_header]`` which cannot be None, then I dont think we can reach this clause","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":false,"context_lines":[{"line_number":175,"context_line":"        super().__init__(wsgi_input)"},{"line_number":176,"context_line":"        self._expected_length \u003d content_length"},{"line_number":177,"context_line":"        self.checksum_info \u003d CHECKSUMS_BY_HEADER[checksum_header]"},{"line_number":178,"context_line":"        if self.checksum_info is None:"},{"line_number":179,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":180,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":181,"context_line":"            self.wsgi_input.read(1)"}],"source_content_type":"text/x-python","patch_set":2,"id":"0a496390_7c6e188d","line":178,"range":{"start_line":178,"start_character":8,"end_line":178,"end_character":38},"in_reply_to":"22f2259d_1e3e445b","updated":"2025-03-17 15:57:59.000000000","message":"Acknowledged","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d86a23dd3990d94e10d0b5fe902ed50d0b0fc5dd","unresolved":true,"context_lines":[{"line_number":178,"context_line":"        if self.checksum_info is None:"},{"line_number":179,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":180,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":181,"context_line":"            self.wsgi_input.read(1)"},{"line_number":182,"context_line":"            # TODO: how does AWS fail?"},{"line_number":183,"context_line":"            raise InvalidRequest"},{"line_number":184,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"}],"source_content_type":"text/x-python","patch_set":2,"id":"6ea39725_75fccb85","line":181,"range":{"start_line":181,"start_character":12,"end_line":181,"end_character":35},"updated":"2025-03-13 17:48:10.000000000","message":"we ought to check we do this consistently every place we raise an exception, like earlier in ``install_checksumming_input``","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":false,"context_lines":[{"line_number":178,"context_line":"        if self.checksum_info is None:"},{"line_number":179,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":180,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":181,"context_line":"            self.wsgi_input.read(1)"},{"line_number":182,"context_line":"            # TODO: how does AWS fail?"},{"line_number":183,"context_line":"            raise InvalidRequest"},{"line_number":184,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"}],"source_content_type":"text/x-python","patch_set":2,"id":"dabe9a9e_168e182c","line":181,"range":{"start_line":181,"start_character":12,"end_line":181,"end_character":35},"in_reply_to":"6ea39725_75fccb85","updated":"2025-03-17 15:57:59.000000000","message":"Mooted -- I don\u0027t entirely remember the circumstances around me adding that `read(1)` now, but it seems to no longer be necessary.","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a5d19b4c54b20741ef78a8e2f4aefd193aa00cc7","unresolved":true,"context_lines":[{"line_number":1388,"context_line":"            checksum_headers \u003d {"},{"line_number":1389,"context_line":"                h.lower(): None"},{"line_number":1390,"context_line":"                for h in list_from_csv(self.headers.get(\u0027x-amz-trailer\u0027))"},{"line_number":1391,"context_line":"                if h.lower().startswith(\u0027x-amz-checksum-\u0027)}"},{"line_number":1392,"context_line":"        if not checksum_headers:"},{"line_number":1393,"context_line":"            if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"},{"line_number":1394,"context_line":"                raise InvalidRequest("}],"source_content_type":"text/x-python","patch_set":2,"id":"c7858106_816abe88","line":1391,"updated":"2025-03-13 17:56:11.000000000","message":"we need to validate the checksum value is supported before we get to line 1409,  by checking h.lower in CHECKSUMS_BY_HEADER somewhere around here","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"33da7c69ebcaff1b5e7b1cf8768a96fb95cea5f3","unresolved":false,"context_lines":[{"line_number":1388,"context_line":"            checksum_headers \u003d {"},{"line_number":1389,"context_line":"                h.lower(): None"},{"line_number":1390,"context_line":"                for h in list_from_csv(self.headers.get(\u0027x-amz-trailer\u0027))"},{"line_number":1391,"context_line":"                if h.lower().startswith(\u0027x-amz-checksum-\u0027)}"},{"line_number":1392,"context_line":"        if not checksum_headers:"},{"line_number":1393,"context_line":"            if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"},{"line_number":1394,"context_line":"                raise InvalidRequest("}],"source_content_type":"text/x-python","patch_set":2,"id":"94b83ef4_22dfc02e","line":1391,"in_reply_to":"c7858106_816abe88","updated":"2025-03-14 18:34:47.000000000","message":"Done","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d86a23dd3990d94e10d0b5fe902ed50d0b0fc5dd","unresolved":true,"context_lines":[{"line_number":1399,"context_line":"        if len(checksum_headers) \u003e 1:"},{"line_number":1400,"context_line":"            # Ensure we\u0027ve sent 100 Continue"},{"line_number":1401,"context_line":"            self.environ[\u0027wsgi.input\u0027].read(1)"},{"line_number":1402,"context_line":"            if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"},{"line_number":1403,"context_line":"                raise InvalidRequest(\u0027Value for x-amz-sdk-checksum-algorithm \u0027"},{"line_number":1404,"context_line":"                                     \u0027header is invalid.\u0027)"},{"line_number":1405,"context_line":"            raise InvalidRequest(\u0027Expecting a single x-amz-checksum- header. \u0027"},{"line_number":1406,"context_line":"                                 \u0027Multiple checksum Types are not allowed.\u0027)"},{"line_number":1407,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"a6202998_eefeaca3","line":1404,"range":{"start_line":1402,"start_character":12,"end_line":1404,"end_character":58},"updated":"2025-03-13 17:48:10.000000000","message":"I have a compat test I\u0027ll push in a follow-on that suggests this should not be here - multiple headers trumps algo-header mismatch","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"33da7c69ebcaff1b5e7b1cf8768a96fb95cea5f3","unresolved":false,"context_lines":[{"line_number":1399,"context_line":"        if len(checksum_headers) \u003e 1:"},{"line_number":1400,"context_line":"            # Ensure we\u0027ve sent 100 Continue"},{"line_number":1401,"context_line":"            self.environ[\u0027wsgi.input\u0027].read(1)"},{"line_number":1402,"context_line":"            if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"},{"line_number":1403,"context_line":"                raise InvalidRequest(\u0027Value for x-amz-sdk-checksum-algorithm \u0027"},{"line_number":1404,"context_line":"                                     \u0027header is invalid.\u0027)"},{"line_number":1405,"context_line":"            raise InvalidRequest(\u0027Expecting a single x-amz-checksum- header. \u0027"},{"line_number":1406,"context_line":"                                 \u0027Multiple checksum Types are not allowed.\u0027)"},{"line_number":1407,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"a51277f0_a737d9b4","line":1404,"range":{"start_line":1402,"start_character":12,"end_line":1404,"end_character":58},"in_reply_to":"a6202998_eefeaca3","updated":"2025-03-14 18:34:47.000000000","message":"Done","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"33da7c69ebcaff1b5e7b1cf8768a96fb95cea5f3","unresolved":true,"context_lines":[{"line_number":182,"context_line":"            # TODO: how does AWS fail?"},{"line_number":183,"context_line":"            raise InvalidRequest"},{"line_number":184,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"},{"line_number":185,"context_line":"        if expected_checksum is None:"},{"line_number":186,"context_line":"            # checksum should appear at end of request in trailers"},{"line_number":187,"context_line":"            self.expected_raw_checksum \u003d None"},{"line_number":188,"context_line":"        else:"},{"line_number":189,"context_line":"            try:"},{"line_number":190,"context_line":"                self.expected_raw_checksum \u003d strict_b64decode("},{"line_number":191,"context_line":"                    expected_checksum,"},{"line_number":192,"context_line":"                    exact_size\u003dself._hasher.digest_size,"},{"line_number":193,"context_line":"                )"},{"line_number":194,"context_line":"            except ValueError:"},{"line_number":195,"context_line":"                # boto3 (at least) can get into framing issues if we"},{"line_number":196,"context_line":"                # haven\u0027t sent a 100 Continue"},{"line_number":197,"context_line":"                self.wsgi_input.read(1)"},{"line_number":198,"context_line":"                raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":199,"context_line":"                                     self.checksum_info.client_header)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":202,"context_line":"        self._hasher.update(chunk)"},{"line_number":203,"context_line":"        if self.bytes_received \u003c self._expected_length:"}],"source_content_type":"text/x-python","patch_set":4,"id":"e7a63639_48974142","line":200,"range":{"start_line":185,"start_character":8,"end_line":200,"end_character":0},"updated":"2025-03-14 18:34:47.000000000","message":"This feels like very late header validation...we could this check in _install_checksumming_input_wrapper. Gets header validation in one place and avoids this class ever raising InvalidRequest - better separation of concerns perhaps.","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":false,"context_lines":[{"line_number":182,"context_line":"            # TODO: how does AWS fail?"},{"line_number":183,"context_line":"            raise InvalidRequest"},{"line_number":184,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"},{"line_number":185,"context_line":"        if expected_checksum is None:"},{"line_number":186,"context_line":"            # checksum should appear at end of request in trailers"},{"line_number":187,"context_line":"            self.expected_raw_checksum \u003d None"},{"line_number":188,"context_line":"        else:"},{"line_number":189,"context_line":"            try:"},{"line_number":190,"context_line":"                self.expected_raw_checksum \u003d strict_b64decode("},{"line_number":191,"context_line":"                    expected_checksum,"},{"line_number":192,"context_line":"                    exact_size\u003dself._hasher.digest_size,"},{"line_number":193,"context_line":"                )"},{"line_number":194,"context_line":"            except ValueError:"},{"line_number":195,"context_line":"                # boto3 (at least) can get into framing issues if we"},{"line_number":196,"context_line":"                # haven\u0027t sent a 100 Continue"},{"line_number":197,"context_line":"                self.wsgi_input.read(1)"},{"line_number":198,"context_line":"                raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":199,"context_line":"                                     self.checksum_info.client_header)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":202,"context_line":"        self._hasher.update(chunk)"},{"line_number":203,"context_line":"        if self.bytes_received \u003c self._expected_length:"}],"source_content_type":"text/x-python","patch_set":4,"id":"04c2c456_a720a99b","line":200,"range":{"start_line":185,"start_character":8,"end_line":200,"end_character":0},"in_reply_to":"e7a63639_48974142","updated":"2025-04-16 11:49:51.000000000","message":"Done","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":false,"context_lines":[{"line_number":182,"context_line":"            # TODO: how does AWS fail?"},{"line_number":183,"context_line":"            raise InvalidRequest"},{"line_number":184,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"},{"line_number":185,"context_line":"        if expected_checksum is None:"},{"line_number":186,"context_line":"            # checksum should appear at end of request in trailers"},{"line_number":187,"context_line":"            self.expected_raw_checksum \u003d None"},{"line_number":188,"context_line":"        else:"},{"line_number":189,"context_line":"            try:"},{"line_number":190,"context_line":"                self.expected_raw_checksum \u003d strict_b64decode("},{"line_number":191,"context_line":"                    expected_checksum,"},{"line_number":192,"context_line":"                    exact_size\u003dself._hasher.digest_size,"},{"line_number":193,"context_line":"                )"},{"line_number":194,"context_line":"            except ValueError:"},{"line_number":195,"context_line":"                # boto3 (at least) can get into framing issues if we"},{"line_number":196,"context_line":"                # haven\u0027t sent a 100 Continue"},{"line_number":197,"context_line":"                self.wsgi_input.read(1)"},{"line_number":198,"context_line":"                raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":199,"context_line":"                                     self.checksum_info.client_header)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":202,"context_line":"        self._hasher.update(chunk)"},{"line_number":203,"context_line":"        if self.bytes_received \u003c self._expected_length:"}],"source_content_type":"text/x-python","patch_set":4,"id":"4abb8be1_a4489e50","line":200,"range":{"start_line":185,"start_character":8,"end_line":200,"end_character":0},"in_reply_to":"e7a63639_48974142","updated":"2025-04-16 11:49:51.000000000","message":"Done","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"33da7c69ebcaff1b5e7b1cf8768a96fb95cea5f3","unresolved":true,"context_lines":[{"line_number":215,"context_line":"                except ValueError:"},{"line_number":216,"context_line":"                    # TODO: raise some flavor of S3InputError"},{"line_number":217,"context_line":"                    raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":218,"context_line":"                                         self.checksum_info.client_header)"},{"line_number":219,"context_line":"            error \u003d (self._hasher.digest() !\u003d self.expected_raw_checksum)"},{"line_number":220,"context_line":"        else:"},{"line_number":221,"context_line":"            error \u003d True"}],"source_content_type":"text/x-python","patch_set":4,"id":"82a88281_fbec50cf","line":218,"range":{"start_line":218,"start_character":41,"end_line":218,"end_character":73},"updated":"2025-03-14 18:34:47.000000000","message":"now that CRCHasher\u0027s have a ``name`` attribute which is the same as ChecksumInfo.name it feels like we could just pass a hasher into this class and get the name from that for the header. Likewise at line 226.","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                except ValueError:"},{"line_number":216,"context_line":"                    # TODO: raise some flavor of S3InputError"},{"line_number":217,"context_line":"                    raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":218,"context_line":"                                         self.checksum_info.client_header)"},{"line_number":219,"context_line":"            error \u003d (self._hasher.digest() !\u003d self.expected_raw_checksum)"},{"line_number":220,"context_line":"        else:"},{"line_number":221,"context_line":"            error \u003d True"}],"source_content_type":"text/x-python","patch_set":4,"id":"165e5746_ce8e98d8","line":218,"range":{"start_line":218,"start_character":41,"end_line":218,"end_character":73},"in_reply_to":"82a88281_fbec50cf","updated":"2025-04-16 11:49:51.000000000","message":"Done","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"33da7c69ebcaff1b5e7b1cf8768a96fb95cea5f3","unresolved":true,"context_lines":[{"line_number":1444,"context_line":"            b64digest,"},{"line_number":1445,"context_line":"        )"},{"line_number":1446,"context_line":"        self.environ[\u0027wsgi.input\u0027] \u003d checksum_input"},{"line_number":1447,"context_line":"        if b64digest:"},{"line_number":1448,"context_line":"            self.headers[checksum_info.sysmeta_header] \u003d b64digest"},{"line_number":1449,"context_line":""},{"line_number":1450,"context_line":"    def _validate_headers(self):"},{"line_number":1451,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":4,"id":"522ebf5e_12f3401a","line":1448,"range":{"start_line":1447,"start_character":8,"end_line":1448,"end_character":66},"updated":"2025-03-14 18:34:47.000000000","message":"oooh, so we *are* writing down the digest in sysmeta...but shouldn\u0027t we be encrypting it like we do the etag?\n\nDo we *need* to do this in this patch?","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":false,"context_lines":[{"line_number":1444,"context_line":"            b64digest,"},{"line_number":1445,"context_line":"        )"},{"line_number":1446,"context_line":"        self.environ[\u0027wsgi.input\u0027] \u003d checksum_input"},{"line_number":1447,"context_line":"        if b64digest:"},{"line_number":1448,"context_line":"            self.headers[checksum_info.sysmeta_header] \u003d b64digest"},{"line_number":1449,"context_line":""},{"line_number":1450,"context_line":"    def _validate_headers(self):"},{"line_number":1451,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":4,"id":"2f9e54bf_041cdbbd","line":1448,"range":{"start_line":1447,"start_character":8,"end_line":1448,"end_character":66},"in_reply_to":"522ebf5e_12f3401a","updated":"2025-03-17 15:57:59.000000000","message":"Fixed -- just an oversight. Removed the `sysmeta_header`, `listing_param_name`, and `client_listing_name` properties from `ChecksumInfo` to make sure nothing else got overlooked.","commit_id":"7dd39eb0f683381323e7e1066e420035c0f17bce"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":1295,"context_line":"        if len(trailer_list) \u003e 1:"},{"line_number":1296,"context_line":"            raise InvalidRequest("},{"line_number":1297,"context_line":"                \u0027Expecting a single x-amz-checksum- header. Multiple \u0027"},{"line_number":1298,"context_line":"                \u0027checksum Types are not allowed.\u0027)"},{"line_number":1299,"context_line":"        else:"},{"line_number":1300,"context_line":"            expected_trailers.update(trailer_list)"},{"line_number":1301,"context_line":"        streaming_input \u003d StreamingInput("}],"source_content_type":"text/x-python","patch_set":22,"id":"cf5f76ae_820b7a82","side":"PARENT","line":1298,"updated":"2025-04-16 11:49:51.000000000","message":"the validation is now done earlier in _validate_checksum_headers","commit_id":"98cb5a5ca76c800447ede159a2ea5843a7fb54a3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ef95e6c064f38a543306639c1bf5d0adb753d706","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"        if len(trailer_list) \u003e 1:"},{"line_number":1296,"context_line":"            raise InvalidRequest("},{"line_number":1297,"context_line":"                \u0027Expecting a single x-amz-checksum- header. Multiple \u0027"},{"line_number":1298,"context_line":"                \u0027checksum Types are not allowed.\u0027)"},{"line_number":1299,"context_line":"        else:"},{"line_number":1300,"context_line":"            expected_trailers.update(trailer_list)"},{"line_number":1301,"context_line":"        streaming_input \u003d StreamingInput("}],"source_content_type":"text/x-python","patch_set":22,"id":"636c4302_1716f112","side":"PARENT","line":1298,"in_reply_to":"cf5f76ae_820b7a82","updated":"2025-04-22 10:17:01.000000000","message":"Acknowledged","commit_id":"98cb5a5ca76c800447ede159a2ea5843a7fb54a3"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":1017,"context_line":"        self.access_key, self.signature \u003d self._parse_auth_info()"},{"line_number":1018,"context_line":"        self.bucket_in_host \u003d self._parse_host()"},{"line_number":1019,"context_line":"        self.container_name, self.object_name \u003d self._parse_uri()"},{"line_number":1020,"context_line":"        aws_sha256 \u003d self._validate_headers()"},{"line_number":1021,"context_line":"        aws_sha256 \u003d self.headers.get(\u0027x-amz-content-sha256\u0027)"},{"line_number":1022,"context_line":"        self.sig_checker \u003d self.sig_checker_cls(self)"},{"line_number":1023,"context_line":"        if self.method in (\u0027PUT\u0027, \u0027POST\u0027):"}],"source_content_type":"text/x-python","patch_set":22,"id":"b4695733_ecb20b72","line":1020,"range":{"start_line":1020,"start_character":8,"end_line":1020,"end_character":21},"updated":"2025-04-16 11:49:51.000000000","message":"oops, this has snuck back in","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c9c0827e7e9e5f93619a94328496896e26aa98e7","unresolved":false,"context_lines":[{"line_number":1017,"context_line":"        self.access_key, self.signature \u003d self._parse_auth_info()"},{"line_number":1018,"context_line":"        self.bucket_in_host \u003d self._parse_host()"},{"line_number":1019,"context_line":"        self.container_name, self.object_name \u003d self._parse_uri()"},{"line_number":1020,"context_line":"        aws_sha256 \u003d self._validate_headers()"},{"line_number":1021,"context_line":"        aws_sha256 \u003d self.headers.get(\u0027x-amz-content-sha256\u0027)"},{"line_number":1022,"context_line":"        self.sig_checker \u003d self.sig_checker_cls(self)"},{"line_number":1023,"context_line":"        if self.method in (\u0027PUT\u0027, \u0027POST\u0027):"}],"source_content_type":"text/x-python","patch_set":22,"id":"5c8f7317_6f93d5aa","line":1020,"range":{"start_line":1020,"start_character":8,"end_line":1020,"end_character":21},"in_reply_to":"b4695733_ecb20b72","updated":"2025-04-21 22:29:19.000000000","message":"Done","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":1548,"context_line":"        if \u0027x-amz-tagging\u0027 in self.headers:"},{"line_number":1549,"context_line":"            raise S3NotImplemented(\u0027Object tagging is not supported.\u0027)"},{"line_number":1550,"context_line":""},{"line_number":1551,"context_line":"        return aws_sha256"},{"line_number":1552,"context_line":""},{"line_number":1553,"context_line":"    @property"},{"line_number":1554,"context_line":"    def body(self):"}],"source_content_type":"text/x-python","patch_set":22,"id":"a14d7fa9_c6bf2836","line":1551,"updated":"2025-04-16 11:49:51.000000000","message":"no longer required to return this","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c9c0827e7e9e5f93619a94328496896e26aa98e7","unresolved":false,"context_lines":[{"line_number":1548,"context_line":"        if \u0027x-amz-tagging\u0027 in self.headers:"},{"line_number":1549,"context_line":"            raise S3NotImplemented(\u0027Object tagging is not supported.\u0027)"},{"line_number":1550,"context_line":""},{"line_number":1551,"context_line":"        return aws_sha256"},{"line_number":1552,"context_line":""},{"line_number":1553,"context_line":"    @property"},{"line_number":1554,"context_line":"    def body(self):"}],"source_content_type":"text/x-python","patch_set":22,"id":"27cbb207_96719ddf","line":1551,"in_reply_to":"a14d7fa9_c6bf2836","updated":"2025-04-21 22:29:19.000000000","message":"Done","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b982231b3f424b4117e722ddca2e7fce5c1df1d4","unresolved":true,"context_lines":[{"line_number":106,"context_line":"def _get_checksum_hasher(header):"},{"line_number":107,"context_line":"    try:"},{"line_number":108,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":109,"context_line":"    except NotImplementedError:"},{"line_number":110,"context_line":"        raise S3NotImplemented(\u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"997bc45d_b6fbf93f","line":109,"updated":"2025-05-29 13:14:32.000000000","message":"I wondered if we ought to add ``KeyError`` here, but we have validated that the header *is in* CHECKSUMS_BY_HEADER before calling this function (in _validate_x_amz_checksum_headers and _validate_x_amz_trailer_header)","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2faaf75e674b30730be1842f001b597d179d197a","unresolved":false,"context_lines":[{"line_number":106,"context_line":"def _get_checksum_hasher(header):"},{"line_number":107,"context_line":"    try:"},{"line_number":108,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":109,"context_line":"    except NotImplementedError:"},{"line_number":110,"context_line":"        raise S3NotImplemented(\u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"9fc98eea_082c6cef","line":109,"in_reply_to":"8932de8a_4e876e52","updated":"2025-06-12 08:04:26.000000000","message":"Done","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e48a03453a13cbcc78d163099890be9f72fdd530","unresolved":true,"context_lines":[{"line_number":106,"context_line":"def _get_checksum_hasher(header):"},{"line_number":107,"context_line":"    try:"},{"line_number":108,"context_line":"        return CHECKSUMS_BY_HEADER[header]()"},{"line_number":109,"context_line":"    except NotImplementedError:"},{"line_number":110,"context_line":"        raise S3NotImplemented(\u0027The %s algorithm is not supported.\u0027 % header)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"8932de8a_4e876e52","line":109,"in_reply_to":"997bc45d_b6fbf93f","updated":"2025-06-11 18:03:35.000000000","message":"I added the KeyError just in case here https://review.opendev.org/c/openstack/swift/+/952390","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b982231b3f424b4117e722ddca2e7fce5c1df1d4","unresolved":true,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # TODO: why are we not doing this for POSTs (e.g. MPU complete)?"},{"line_number":1072,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1073,"context_line":"                self._install_checksumming_input_wrapper("},{"line_number":1074,"context_line":"                    checksum_hasher, checksum_header, checksum_source)"}],"source_content_type":"text/x-python","patch_set":35,"id":"4ce330f4_02f3f05c","line":1071,"updated":"2025-05-29 13:14:32.000000000","message":"we ought to at least have a comment to address this","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e48a03453a13cbcc78d163099890be9f72fdd530","unresolved":true,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # TODO: why are we not doing this for POSTs (e.g. MPU complete)?"},{"line_number":1072,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1073,"context_line":"                self._install_checksumming_input_wrapper("},{"line_number":1074,"context_line":"                    checksum_hasher, checksum_header, checksum_source)"}],"source_content_type":"text/x-python","patch_set":35,"id":"ec3e89c4_5185fce5","line":1071,"in_reply_to":"4ce330f4_02f3f05c","updated":"2025-06-11 18:03:35.000000000","message":"addressed here: https://review.opendev.org/c/openstack/swift/+/952391\n\nS3 does NOT appear to check checksum of an mpu complete POST","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2faaf75e674b30730be1842f001b597d179d197a","unresolved":false,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # TODO: why are we not doing this for POSTs (e.g. MPU complete)?"},{"line_number":1072,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1073,"context_line":"                self._install_checksumming_input_wrapper("},{"line_number":1074,"context_line":"                    checksum_hasher, checksum_header, checksum_source)"}],"source_content_type":"text/x-python","patch_set":35,"id":"5cdad4d1_8674c7ff","line":1071,"in_reply_to":"ec3e89c4_5185fce5","updated":"2025-06-12 08:04:26.000000000","message":"Done","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b982231b3f424b4117e722ddca2e7fce5c1df1d4","unresolved":true,"context_lines":[{"line_number":1422,"context_line":"        # reject with length-required and we\u0027ll translate back to"},{"line_number":1423,"context_line":"        # MissingContentLength)"},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"    def _validate_x_amz_checksum_headers(self):"},{"line_number":1426,"context_line":"        checksum_headers \u003d {"},{"line_number":1427,"context_line":"            h.lower(): v"},{"line_number":1428,"context_line":"            for h, v in self.headers.items()"}],"source_content_type":"text/x-python","patch_set":35,"id":"5cade0f5_4d1921c7","line":1425,"updated":"2025-05-29 13:14:32.000000000","message":"nit: given the similar naming of this and ``_validate_x_amz_trailer_header`` we should probably add a docstring to flag that they return different types (a dict here and a list in _validate_x_amz_trailer_header)","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e48a03453a13cbcc78d163099890be9f72fdd530","unresolved":true,"context_lines":[{"line_number":1422,"context_line":"        # reject with length-required and we\u0027ll translate back to"},{"line_number":1423,"context_line":"        # MissingContentLength)"},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"    def _validate_x_amz_checksum_headers(self):"},{"line_number":1426,"context_line":"        checksum_headers \u003d {"},{"line_number":1427,"context_line":"            h.lower(): v"},{"line_number":1428,"context_line":"            for h, v in self.headers.items()"}],"source_content_type":"text/x-python","patch_set":35,"id":"6c7b1fb8_762b8790","line":1425,"in_reply_to":"5cade0f5_4d1921c7","updated":"2025-06-11 18:03:35.000000000","message":"done here https://review.opendev.org/c/openstack/swift/+/952390","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2faaf75e674b30730be1842f001b597d179d197a","unresolved":false,"context_lines":[{"line_number":1422,"context_line":"        # reject with length-required and we\u0027ll translate back to"},{"line_number":1423,"context_line":"        # MissingContentLength)"},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"    def _validate_x_amz_checksum_headers(self):"},{"line_number":1426,"context_line":"        checksum_headers \u003d {"},{"line_number":1427,"context_line":"            h.lower(): v"},{"line_number":1428,"context_line":"            for h, v in self.headers.items()"}],"source_content_type":"text/x-python","patch_set":35,"id":"a75ab53d_777191fc","line":1425,"in_reply_to":"6c7b1fb8_762b8790","updated":"2025-06-12 08:04:26.000000000","message":"Done","commit_id":"a8bde4a5399022c9da0789f395cde3822d6b6a18"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":true,"context_lines":[{"line_number":235,"context_line":"        self._checksum_header \u003d checksum_header"},{"line_number":236,"context_line":"        self._checksum_source \u003d checksum_source"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"}],"source_content_type":"text/x-python","patch_set":38,"id":"6655fe21_70cf283d","line":238,"updated":"2025-06-25 21:10:58.000000000","message":"this ``chunk`` is different from the chunks in chunked transfer, I wonder if there is a better name.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":false,"context_lines":[{"line_number":235,"context_line":"        self._checksum_header \u003d checksum_header"},{"line_number":236,"context_line":"        self._checksum_source \u003d checksum_source"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"}],"source_content_type":"text/x-python","patch_set":38,"id":"c17ddbad_bdc0d86e","line":238,"in_reply_to":"09b568e1_5185c258","updated":"2025-07-10 17:01:24.000000000","message":"Done","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2442dc0b70867680fd1b3fe026bb10cf94e522e1","unresolved":true,"context_lines":[{"line_number":235,"context_line":"        self._checksum_header \u003d checksum_header"},{"line_number":236,"context_line":"        self._checksum_source \u003d checksum_source"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"}],"source_content_type":"text/x-python","patch_set":38,"id":"09b568e1_5185c258","line":238,"in_reply_to":"1930095a_0f800011","updated":"2025-07-01 17:20:55.000000000","message":"_\\*shrug\\*_ Added comments both here and in `HashingInput`, which is in a somewhat similar position.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"028f9cdf860b8c14543146620f68fcd0d7b9a950","unresolved":true,"context_lines":[{"line_number":235,"context_line":"        self._checksum_header \u003d checksum_header"},{"line_number":236,"context_line":"        self._checksum_source \u003d checksum_source"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"}],"source_content_type":"text/x-python","patch_set":38,"id":"a231e905_de1c6caf","line":238,"in_reply_to":"6655fe21_70cf283d","updated":"2025-06-26 19:42:58.000000000","message":"This is something we\u0027re overriding from `InputProxy`. In taht context, `chunk` is just \"whatever data was read from this input.\" It\u0027s entirely separate from the `aws-chunked` stuff.\n\nMaybe renaming `ChunkReader` to `AWSChunkReader` would help?","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0faa46379162270361059ed30841d60e067c3a","unresolved":true,"context_lines":[{"line_number":235,"context_line":"        self._checksum_header \u003d checksum_header"},{"line_number":236,"context_line":"        self._checksum_source \u003d checksum_source"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"}],"source_content_type":"text/x-python","patch_set":38,"id":"1930095a_0f800011","line":238,"in_reply_to":"a231e905_de1c6caf","updated":"2025-06-27 01:53:44.000000000","message":"I feel comments should be sufficient.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":true,"context_lines":[{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"},{"line_number":242,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":243,"context_line":"            # Lazy fetch checksum value because it may have come in trailers"},{"line_number":244,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_header)"}],"source_content_type":"text/x-python","patch_set":38,"id":"0e6c9ead_1b650009","line":241,"updated":"2025-06-25 21:10:58.000000000","message":"The path checks if ``self.bytes_received \u003c self._expected_length``, and if eof is true(the connection has ended I guess?), it sets ``error \u003d True`` and proceeds to raise ``S3InputChecksumMismatch``.\n\nThe direct cause of the failure is an incomplete body, not a checksum that has been calculated and found to be incorrect, the checksum calculation was never even done. So in this case, the error returned to the user should be ``IncompleteBody``? also, this case would need the coverage in unit tests.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"028f9cdf860b8c14543146620f68fcd0d7b9a950","unresolved":true,"context_lines":[{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"},{"line_number":242,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":243,"context_line":"            # Lazy fetch checksum value because it may have come in trailers"},{"line_number":244,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_header)"}],"source_content_type":"text/x-python","patch_set":38,"id":"dd8ff540_0b66bca9","line":241,"in_reply_to":"0e6c9ead_1b650009","updated":"2025-06-26 19:42:58.000000000","message":"\u003e So in this case, the error returned to the user should be IncompleteBody?\n\nIn practice, that\u0027s exactly what happens for `aws-chunked` transfers. Since this wraps a `StreamingInput`, that\u0027s the first bit to notice and raises either `S3InputIncomplete` or `S3InputSizeError`, both of which get translated to (slightly different) `IncompleteBody` responses in `translate_read_errors`.\n\nSince this is just a belt-and-bracers thing, having `ChecksummingInput` only raise `S3InputChecksumMismatch` seemed reasonable.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"},{"line_number":242,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":243,"context_line":"            # Lazy fetch checksum value because it may have come in trailers"},{"line_number":244,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_header)"}],"source_content_type":"text/x-python","patch_set":38,"id":"51dce46b_60a25864","line":241,"in_reply_to":"21f3ecaf_e1b279df","updated":"2025-07-10 17:01:24.000000000","message":"I tried writing some functional (compat) tests to exercise both too many and too few body bytes, but found that I couldn\u0027t trigger these error clauses.\n\nIf the sender doesn\u0027t send enough bytes then some input reader is going to timeout and we won\u0027t reach this clause. We\u0027d see a client disconnected error.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":false,"context_lines":[{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"},{"line_number":242,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":243,"context_line":"            # Lazy fetch checksum value because it may have come in trailers"},{"line_number":244,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_header)"}],"source_content_type":"text/x-python","patch_set":38,"id":"9306029b_00efac20","line":241,"in_reply_to":"51dce46b_60a25864","updated":"2025-07-15 16:10:59.000000000","message":"Done","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0faa46379162270361059ed30841d60e067c3a","unresolved":true,"context_lines":[{"line_number":238,"context_line":"    def chunk_update(self, chunk, eof, *args, **kwargs):"},{"line_number":239,"context_line":"        self._checksum_hasher.update(chunk)"},{"line_number":240,"context_line":"        if self.bytes_received \u003c self._expected_length:"},{"line_number":241,"context_line":"            error \u003d eof"},{"line_number":242,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":243,"context_line":"            # Lazy fetch checksum value because it may have come in trailers"},{"line_number":244,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_header)"}],"source_content_type":"text/x-python","patch_set":38,"id":"21f3ecaf_e1b279df","line":241,"in_reply_to":"dd8ff540_0b66bca9","updated":"2025-06-27 01:53:44.000000000","message":"I wonder if different exception would cause boto3 to behave differently in this case of early terminated connection.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":true,"context_lines":[{"line_number":246,"context_line":"                self._checksum_hasher, self._checksum_header, b64digest)"},{"line_number":247,"context_line":"            error \u003d self._checksum_hasher.digest() !\u003d expected_raw_checksum"},{"line_number":248,"context_line":"        else:"},{"line_number":249,"context_line":"            error \u003d True"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        if error:"},{"line_number":252,"context_line":"            self.close()"}],"source_content_type":"text/x-python","patch_set":38,"id":"b6efd5c5_8a7fc48d","line":249,"updated":"2025-06-25 21:10:58.000000000","message":"when ``self.bytes_received \u003e self._expected_length``, this function should raise ``IncompleteBody`` also at here?\n\nAgain, we would need test case to specifically covers this \"body is too long\" scenario.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":false,"context_lines":[{"line_number":246,"context_line":"                self._checksum_hasher, self._checksum_header, b64digest)"},{"line_number":247,"context_line":"            error \u003d self._checksum_hasher.digest() !\u003d expected_raw_checksum"},{"line_number":248,"context_line":"        else:"},{"line_number":249,"context_line":"            error \u003d True"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        if error:"},{"line_number":252,"context_line":"            self.close()"}],"source_content_type":"text/x-python","patch_set":38,"id":"dc943b85_d1957bb6","line":249,"in_reply_to":"046ab5db_e89bda0f","updated":"2025-07-15 16:10:59.000000000","message":"Acknowledged","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":246,"context_line":"                self._checksum_hasher, self._checksum_header, b64digest)"},{"line_number":247,"context_line":"            error \u003d self._checksum_hasher.digest() !\u003d expected_raw_checksum"},{"line_number":248,"context_line":"        else:"},{"line_number":249,"context_line":"            error \u003d True"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        if error:"},{"line_number":252,"context_line":"            self.close()"}],"source_content_type":"text/x-python","patch_set":38,"id":"046ab5db_e89bda0f","line":249,"in_reply_to":"b6efd5c5_8a7fc48d","updated":"2025-07-10 17:01:24.000000000","message":"As I understand it, wsgi.Input will only read content-length bytes, so this input wrapper will never be fed more than content-length bytes. We could do it in a unit test, but it won\u0027t happen in real world.\n\nI wrote a compat test that shows it is ok for the client to send more than content-length bytes, so long as the checksum matches the first content-length bytes that are sent.\n\nextra test here https://review.opendev.org/c/openstack/swift/+/954640","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3fb33b18d1307911c2607d7973a50d60f69a5a46","unresolved":true,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # S3 doesn\u0027t check the checksum for at least some POSTs (e.g. MPU"},{"line_number":1072,"context_line":"            # complete) so restrict this to PUTs"},{"line_number":1073,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1074,"context_line":"                self._install_checksumming_input_wrapper("}],"source_content_type":"text/x-python","patch_set":38,"id":"277da2dc_9e264858","line":1071,"updated":"2025-06-25 21:10:58.000000000","message":"I see, it\u0027s mentioned at here.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7f44422ed9bf0847bd0243f3d8b4629ab06fbfc9","unresolved":true,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # S3 doesn\u0027t check the checksum for at least some POSTs (e.g. MPU"},{"line_number":1072,"context_line":"            # complete) so restrict this to PUTs"},{"line_number":1073,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1074,"context_line":"                self._install_checksumming_input_wrapper("}],"source_content_type":"text/x-python","patch_set":38,"id":"92f41b7f_2bb9f7bc","line":1071,"in_reply_to":"26f843dd_317f87c3","updated":"2025-07-11 13:56:02.000000000","message":"I was reminded that I had written the patch for multi-delete POSTs https://review.opendev.org/c/openstack/swift/+/952462","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0faa46379162270361059ed30841d60e067c3a","unresolved":true,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # S3 doesn\u0027t check the checksum for at least some POSTs (e.g. MPU"},{"line_number":1072,"context_line":"            # complete) so restrict this to PUTs"},{"line_number":1073,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1074,"context_line":"                self._install_checksumming_input_wrapper("}],"source_content_type":"text/x-python","patch_set":38,"id":"d6c49115_5e93f6f0","line":1071,"in_reply_to":"277da2dc_9e264858","updated":"2025-06-27 01:53:44.000000000","message":"if S3 can check the checksum for MPU complete, so this comment is not accurate then; it\u0027s just we haven\u0027t written down the checksum and are not able to do this.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2442dc0b70867680fd1b3fe026bb10cf94e522e1","unresolved":true,"context_lines":[{"line_number":1068,"context_line":"                self._install_non_streaming_input_wrapper(aws_sha256)"},{"line_number":1069,"context_line":"                checksum_source \u003d self.headers"},{"line_number":1070,"context_line":""},{"line_number":1071,"context_line":"            # S3 doesn\u0027t check the checksum for at least some POSTs (e.g. MPU"},{"line_number":1072,"context_line":"            # complete) so restrict this to PUTs"},{"line_number":1073,"context_line":"            if checksum_header and self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1074,"context_line":"                self._install_checksumming_input_wrapper("}],"source_content_type":"text/x-python","patch_set":38,"id":"26f843dd_317f87c3","line":1071,"in_reply_to":"d6c49115_5e93f6f0","updated":"2025-07-01 17:20:55.000000000","message":"Even if we wrote down the checksum, it wouldn\u0027t be appropriate to install the checksumming input wrapper, though. I\u0027ll try to clarify.","commit_id":"da04c0ad5bbf1889ccd14cb8c2de457546521cf7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":1061,"context_line":"            if _is_streaming(aws_sha256):"},{"line_number":1062,"context_line":"                if checksum_in_trailer:"},{"line_number":1063,"context_line":"                    streaming_input \u003d self._install_streaming_input_wrapper("},{"line_number":1064,"context_line":"                        aws_sha256, exp_checksum_trailer\u003dchecksum_header)"},{"line_number":1065,"context_line":"                    checksum_source \u003d streaming_input.trailers"},{"line_number":1066,"context_line":"                else:"},{"line_number":1067,"context_line":"                    self._install_streaming_input_wrapper(aws_sha256)"}],"source_content_type":"text/x-python","patch_set":42,"id":"a36a56b8_1fa55169","line":1064,"range":{"start_line":1064,"start_character":36,"end_line":1064,"end_character":72},"updated":"2025-07-09 18:07:22.000000000","message":"Reads a little funny, but eventually it makes sense enough.","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":1061,"context_line":"            if _is_streaming(aws_sha256):"},{"line_number":1062,"context_line":"                if checksum_in_trailer:"},{"line_number":1063,"context_line":"                    streaming_input \u003d self._install_streaming_input_wrapper("},{"line_number":1064,"context_line":"                        aws_sha256, exp_checksum_trailer\u003dchecksum_header)"},{"line_number":1065,"context_line":"                    checksum_source \u003d streaming_input.trailers"},{"line_number":1066,"context_line":"                else:"},{"line_number":1067,"context_line":"                    self._install_streaming_input_wrapper(aws_sha256)"}],"source_content_type":"text/x-python","patch_set":42,"id":"b9bb8c52_da01b77b","line":1064,"range":{"start_line":1064,"start_character":36,"end_line":1064,"end_character":72},"in_reply_to":"a36a56b8_1fa55169","updated":"2025-07-10 17:01:24.000000000","message":"hmmm, I remember struggling with this interface. I agree it is confusing to read. I\u0027ll give it another go.\n\nsee https://review.opendev.org/c/openstack/swift/+/954639","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"688b13834c91060e234f72fe4c7083c7df5c4a15","unresolved":false,"context_lines":[{"line_number":1061,"context_line":"            if _is_streaming(aws_sha256):"},{"line_number":1062,"context_line":"                if checksum_in_trailer:"},{"line_number":1063,"context_line":"                    streaming_input \u003d self._install_streaming_input_wrapper("},{"line_number":1064,"context_line":"                        aws_sha256, exp_checksum_trailer\u003dchecksum_header)"},{"line_number":1065,"context_line":"                    checksum_source \u003d streaming_input.trailers"},{"line_number":1066,"context_line":"                else:"},{"line_number":1067,"context_line":"                    self._install_streaming_input_wrapper(aws_sha256)"}],"source_content_type":"text/x-python","patch_set":42,"id":"6833a861_518bfb30","line":1064,"range":{"start_line":1064,"start_character":36,"end_line":1064,"end_character":72},"in_reply_to":"b9bb8c52_da01b77b","updated":"2025-07-11 09:36:17.000000000","message":"Done","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":1508,"context_line":"        _validate_checksum_header_cardinality("},{"line_number":1509,"context_line":"            len(checksum_headers) + len(checksum_trailer_headers),"},{"line_number":1510,"context_line":"            headers_and_trailer\u003dTrue"},{"line_number":1511,"context_line":"        )"},{"line_number":1512,"context_line":""},{"line_number":1513,"context_line":"        if checksum_headers:"},{"line_number":1514,"context_line":"            checksum_header, b64digest \u003d list(checksum_headers.items())[0]"}],"source_content_type":"text/x-python","patch_set":42,"id":"e9a11c6a_c7b2ca92","line":1511,"updated":"2025-07-09 18:07:22.000000000","message":"Now I vaguely want to send two headers and one trailer or one header and two trailers to AWS and see how it responds... but I don\u0027t think it *really* matters.","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0de17cc298d5b6dedb06304afb01922fb5903624","unresolved":false,"context_lines":[{"line_number":1508,"context_line":"        _validate_checksum_header_cardinality("},{"line_number":1509,"context_line":"            len(checksum_headers) + len(checksum_trailer_headers),"},{"line_number":1510,"context_line":"            headers_and_trailer\u003dTrue"},{"line_number":1511,"context_line":"        )"},{"line_number":1512,"context_line":""},{"line_number":1513,"context_line":"        if checksum_headers:"},{"line_number":1514,"context_line":"            checksum_header, b64digest \u003d list(checksum_headers.items())[0]"}],"source_content_type":"text/x-python","patch_set":42,"id":"a1f90470_8ec2b186","line":1511,"in_reply_to":"0b5b0733_f11c30dc","updated":"2025-07-11 13:50:18.000000000","message":"Sure enough! I\u0027ve forgotten what all we\u0027ve bothered to test...","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":1508,"context_line":"        _validate_checksum_header_cardinality("},{"line_number":1509,"context_line":"            len(checksum_headers) + len(checksum_trailer_headers),"},{"line_number":1510,"context_line":"            headers_and_trailer\u003dTrue"},{"line_number":1511,"context_line":"        )"},{"line_number":1512,"context_line":""},{"line_number":1513,"context_line":"        if checksum_headers:"},{"line_number":1514,"context_line":"            checksum_header, b64digest \u003d list(checksum_headers.items())[0]"}],"source_content_type":"text/x-python","patch_set":42,"id":"0b5b0733_f11c30dc","line":1511,"in_reply_to":"e9a11c6a_c7b2ca92","updated":"2025-07-10 17:01:24.000000000","message":"think we have this covered\n\n```\ntest_no_md5_good_sha_multiple_crc_in_trailer_and_header\ntest_no_md5_good_sha_multiple_crc_in_header_and_trailer\n```","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":1519,"context_line":"                    checksum_hasher, checksum_header, b64digest)"},{"line_number":1520,"context_line":"            except S3InputChecksumInvalid as e:"},{"line_number":1521,"context_line":"                raise InvalidRequest("},{"line_number":1522,"context_line":"                    \u0027Value for %s header is invalid.\u0027 % e.trailer)"},{"line_number":1523,"context_line":"            checksum_in_trailer \u003d False"},{"line_number":1524,"context_line":"        elif checksum_trailer_headers:"},{"line_number":1525,"context_line":"            checksum_header \u003d checksum_trailer_headers[0]"}],"source_content_type":"text/x-python","patch_set":42,"id":"cbad384b_a7420f0d","line":1522,"range":{"start_line":1522,"start_character":56,"end_line":1522,"end_character":65},"updated":"2025-07-09 18:07:22.000000000","message":"OK, that\u0027s a little funky, using `e.trailer` when the value came from a header...","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":1519,"context_line":"                    checksum_hasher, checksum_header, b64digest)"},{"line_number":1520,"context_line":"            except S3InputChecksumInvalid as e:"},{"line_number":1521,"context_line":"                raise InvalidRequest("},{"line_number":1522,"context_line":"                    \u0027Value for %s header is invalid.\u0027 % e.trailer)"},{"line_number":1523,"context_line":"            checksum_in_trailer \u003d False"},{"line_number":1524,"context_line":"        elif checksum_trailer_headers:"},{"line_number":1525,"context_line":"            checksum_header \u003d checksum_trailer_headers[0]"}],"source_content_type":"text/x-python","patch_set":42,"id":"d9f05d55_e88aa135","line":1522,"range":{"start_line":1522,"start_character":56,"end_line":1522,"end_character":65},"in_reply_to":"cbad384b_a7420f0d","updated":"2025-07-10 17:01:24.000000000","message":"as above, maybe we can clean this up\n\nsee https://review.opendev.org/c/openstack/swift/+/954639","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"688b13834c91060e234f72fe4c7083c7df5c4a15","unresolved":false,"context_lines":[{"line_number":1519,"context_line":"                    checksum_hasher, checksum_header, b64digest)"},{"line_number":1520,"context_line":"            except S3InputChecksumInvalid as e:"},{"line_number":1521,"context_line":"                raise InvalidRequest("},{"line_number":1522,"context_line":"                    \u0027Value for %s header is invalid.\u0027 % e.trailer)"},{"line_number":1523,"context_line":"            checksum_in_trailer \u003d False"},{"line_number":1524,"context_line":"        elif checksum_trailer_headers:"},{"line_number":1525,"context_line":"            checksum_header \u003d checksum_trailer_headers[0]"}],"source_content_type":"text/x-python","patch_set":42,"id":"2b2847fe_3f8b82d2","line":1522,"range":{"start_line":1522,"start_character":56,"end_line":1522,"end_character":65},"in_reply_to":"d9f05d55_e88aa135","updated":"2025-07-11 09:36:17.000000000","message":"Done","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":2100,"context_line":"        except S3InputChecksumMismatch as e:"},{"line_number":2101,"context_line":"            raise BadDigest("},{"line_number":2102,"context_line":"                \u0027The %s you specified did not \u0027"},{"line_number":2103,"context_line":"                \u0027match the calculated checksum.\u0027 % e.args[0])"},{"line_number":2104,"context_line":"        except S3InputChecksumInvalid as e:"},{"line_number":2105,"context_line":"            raise InvalidRequest("},{"line_number":2106,"context_line":"                \u0027Value for %s trailing header is invalid.\u0027 % e.trailer)"}],"source_content_type":"text/x-python","patch_set":42,"id":"913ead90_e50fc575","line":2103,"updated":"2025-07-09 18:07:22.000000000","message":"No expected/computed values in the error message? Cross-compat tests don\u0027t seem to check for presence *or* absence.","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":2100,"context_line":"        except S3InputChecksumMismatch as e:"},{"line_number":2101,"context_line":"            raise BadDigest("},{"line_number":2102,"context_line":"                \u0027The %s you specified did not \u0027"},{"line_number":2103,"context_line":"                \u0027match the calculated checksum.\u0027 % e.args[0])"},{"line_number":2104,"context_line":"        except S3InputChecksumInvalid as e:"},{"line_number":2105,"context_line":"            raise InvalidRequest("},{"line_number":2106,"context_line":"                \u0027Value for %s trailing header is invalid.\u0027 % e.trailer)"}],"source_content_type":"text/x-python","patch_set":42,"id":"93dd9fde_14ae24bc","line":2103,"in_reply_to":"913ead90_e50fc575","updated":"2025-07-10 17:01:24.000000000","message":"apparently not from S3 - I added assertNotIn(\u0027Expected\u0027, resp.body) to some compat tests\n\nsee https://review.opendev.org/c/openstack/swift/+/954641","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0de17cc298d5b6dedb06304afb01922fb5903624","unresolved":false,"context_lines":[{"line_number":2100,"context_line":"        except S3InputChecksumMismatch as e:"},{"line_number":2101,"context_line":"            raise BadDigest("},{"line_number":2102,"context_line":"                \u0027The %s you specified did not \u0027"},{"line_number":2103,"context_line":"                \u0027match the calculated checksum.\u0027 % e.args[0])"},{"line_number":2104,"context_line":"        except S3InputChecksumInvalid as e:"},{"line_number":2105,"context_line":"            raise InvalidRequest("},{"line_number":2106,"context_line":"                \u0027Value for %s trailing header is invalid.\u0027 % e.trailer)"}],"source_content_type":"text/x-python","patch_set":42,"id":"e2742263_477eaf75","line":2103,"in_reply_to":"93dd9fde_14ae24bc","updated":"2025-07-11 13:50:18.000000000","message":"Done","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":2103,"context_line":"                \u0027match the calculated checksum.\u0027 % e.args[0])"},{"line_number":2104,"context_line":"        except S3InputChecksumInvalid as e:"},{"line_number":2105,"context_line":"            raise InvalidRequest("},{"line_number":2106,"context_line":"                \u0027Value for %s trailing header is invalid.\u0027 % e.trailer)"},{"line_number":2107,"context_line":"        except S3InputChunkSignatureMismatch:"},{"line_number":2108,"context_line":"            raise SignatureDoesNotMatch("},{"line_number":2109,"context_line":"                **self.signature_does_not_match_kwargs())"}],"source_content_type":"text/x-python","patch_set":42,"id":"c4d93bda_3b7b300a","line":2106,"updated":"2025-07-09 18:07:22.000000000","message":"I don\u0027t think we have any cross-compat tests that hit this message.\n\nNo reflecting back the invalid value?","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":true,"context_lines":[{"line_number":2103,"context_line":"                \u0027match the calculated checksum.\u0027 % e.args[0])"},{"line_number":2104,"context_line":"        except S3InputChecksumInvalid as e:"},{"line_number":2105,"context_line":"            raise InvalidRequest("},{"line_number":2106,"context_line":"                \u0027Value for %s trailing header is invalid.\u0027 % e.trailer)"},{"line_number":2107,"context_line":"        except S3InputChunkSignatureMismatch:"},{"line_number":2108,"context_line":"            raise SignatureDoesNotMatch("},{"line_number":2109,"context_line":"                **self.signature_does_not_match_kwargs())"}],"source_content_type":"text/x-python","patch_set":42,"id":"dcb5c458_fe186362","line":2106,"in_reply_to":"c4d93bda_3b7b300a","updated":"2025-07-10 17:01:24.000000000","message":"``test_strm_unsgnd_pyld_trl_with_trailer_checksum_invalid`` hits it\n\napparently no Expected value from S3","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0de17cc298d5b6dedb06304afb01922fb5903624","unresolved":false,"context_lines":[{"line_number":2103,"context_line":"                \u0027match the calculated checksum.\u0027 % e.args[0])"},{"line_number":2104,"context_line":"        except S3InputChecksumInvalid as e:"},{"line_number":2105,"context_line":"            raise InvalidRequest("},{"line_number":2106,"context_line":"                \u0027Value for %s trailing header is invalid.\u0027 % e.trailer)"},{"line_number":2107,"context_line":"        except S3InputChunkSignatureMismatch:"},{"line_number":2108,"context_line":"            raise SignatureDoesNotMatch("},{"line_number":2109,"context_line":"                **self.signature_does_not_match_kwargs())"}],"source_content_type":"text/x-python","patch_set":42,"id":"db6811f8_bc7dbca9","line":2106,"in_reply_to":"dcb5c458_fe186362","updated":"2025-07-11 13:50:18.000000000","message":"Ah, I think I\u0027d just searched for \"trailing header\" in the tests, but the error message got split across lines so I didn\u0027t find it.","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":false,"context_lines":[{"line_number":117,"context_line":"    )"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"def _validate_checksum_header_cardinality(num_checksum_headers,"},{"line_number":121,"context_line":"                                          headers_and_trailer\u003dFalse):"},{"line_number":122,"context_line":"    if num_checksum_headers \u003e 1:"},{"line_number":123,"context_line":"        # inconsistent messaging for AWS compatibility..."}],"source_content_type":"text/x-python","patch_set":43,"id":"c8b12571_a172bdea","line":120,"updated":"2025-07-15 16:10:59.000000000","message":"those are small internal helper functions, okay to have no test cases.","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":true,"context_lines":[{"line_number":211,"context_line":"        return chunk"},{"line_number":212,"context_line":""},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"class ChecksummingInput(InputProxy):"},{"line_number":215,"context_line":"    \"\"\""},{"line_number":216,"context_line":"    wsgi.input wrapper to calculate the X-Amz-Checksum-* of the input as it\u0027s"},{"line_number":217,"context_line":"    read. The calculated value is checked against an expected value that is"}],"source_content_type":"text/x-python","patch_set":43,"id":"4796b064_07e28947","line":214,"updated":"2025-07-15 16:10:59.000000000","message":"even though this class is tested indirectly, I think we need to add dedicated test cases for it","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":true,"context_lines":[{"line_number":216,"context_line":"    wsgi.input wrapper to calculate the X-Amz-Checksum-* of the input as it\u0027s"},{"line_number":217,"context_line":"    read. The calculated value is checked against an expected value that is"},{"line_number":218,"context_line":"    sent in either the request headers or trailers. To allow for the latter,"},{"line_number":219,"context_line":"    the expected value is lazy fetched once the input has been read."},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"    :param wsgi_input: file-like object to be wrapped."},{"line_number":222,"context_line":"    :param content_length: the expected number of bytes to be read."}],"source_content_type":"text/x-python","patch_set":43,"id":"fd2df1a9_1d349331","line":219,"updated":"2025-07-15 16:10:59.000000000","message":"``ChecksummingInput`` will be used for chunked transfer, while ``HashingInput`` will be used for normal object upload without streaming, probably worth to add more comments later on","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":true,"context_lines":[{"line_number":244,"context_line":"            # Lazy fetch checksum value because it may have come in trailers"},{"line_number":245,"context_line":"            b64digest \u003d self._checksum_source.get(self._checksum_key)"},{"line_number":246,"context_line":"            try:"},{"line_number":247,"context_line":"                expected_raw_checksum \u003d _validate_checksum_value("},{"line_number":248,"context_line":"                    self._checksum_hasher, b64digest)"},{"line_number":249,"context_line":"            except ValueError:"},{"line_number":250,"context_line":"                # If the checksum value came in a header then it would have"}],"source_content_type":"text/x-python","patch_set":43,"id":"6506d450_a0e01a98","line":247,"updated":"2025-07-15 16:10:59.000000000","message":"the current patch only verifies checksums, but it seems S3 returns those calculated checksum in the response headers.\n\nthis example is from the S3 checksum doc: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html\n\n```\nExample 1 – Unsigned chunked PutObject request with a trailing CRC-32 checksum\nThe following is an example of a chunked PutObject request with a trailing CRC-32 checksum. In this example, the client uploads a 17 KB object in three unsigned chunks and appends a trailing CRC-32 checksum chunk by using the x-amz-checksum-crc32 header.\n\n\nPUT /Key+ HTTP/1.1\nHost: amzn-s3-demo-bucket\nContent-Encoding: aws-chunked\nx-amz-decoded-content-length: 17408\nx-amz-content-sha256: STREAMING-UNSIGNED-PAYLOAD-TRAILER\nx-amz-trailer: x-amz-checksum-crc32\n\n2000\\r\\n                                   // Object body chunk 1 (8192 bytes)\nobject-bytes\\r\\n\n2000\\r\\n                                   // Object body chunk 2 (8192 bytes)\nobject-bytes\\r\\n\n400\\r\\n                                    // Object body chunk 3 (1024 bytes)\nobject-bytes\\r\\n\n0\\r\\n                                      // Completion chunk\nx-amz-checksum-crc32:YABb/g\u003d\u003d\\n\\r\\n\\r\\n    // Trailer chunk (note optional \\n character)\n\\r\\n                                         // CRLF\nHere\u0027s an example response:\n\n\nHTTP/1.1 200\nETag: ETag\nx-amz-checksum-crc32: YABb/g\u003d\u003d\n```","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":true,"context_lines":[{"line_number":1493,"context_line":"        _validate_checksum_header_cardinality(len(checksum_headers))"},{"line_number":1494,"context_line":"        return checksum_headers"},{"line_number":1495,"context_line":""},{"line_number":1496,"context_line":"    def _validate_checksum_headers(self):"},{"line_number":1497,"context_line":"        \"\"\""},{"line_number":1498,"context_line":"        A checksum for the request is specified by a checksum header of the"},{"line_number":1499,"context_line":"        form:"}],"source_content_type":"text/x-python","patch_set":43,"id":"3fab8f25_431a9bf5","line":1496,"updated":"2025-07-15 16:10:59.000000000","message":"all these three new functions has the prefix ``_`` which indicates they are internal, they are tested by a lot of integration kind of test cases, but I am not sure they are complete, probably can add unit test cases to make sure all paths are covered.\n```\n_validate_x_amz_checksum_headers\n_validate_x_amz_trailer_header\n_validate_checksum_headers\n```","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"}],"swift/common/middleware/s3api/s3response.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":477,"context_line":""},{"line_number":478,"context_line":"class InvalidPart(ErrorResponse):"},{"line_number":479,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":480,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":481,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":482,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":483,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"78adf975_cac5ce69","line":480,"range":{"start_line":480,"start_character":66,"end_line":480,"end_character":68},"updated":"2025-04-16 11:49:51.000000000","message":"subtle - S3 returns an extra space. Feels like a pre-existing bug, and there\u0027s no accompanying test change.\n\nMoved to here and added tests https://review.opendev.org/c/openstack/swift/+/947434 s3api: make MPU part error response message same as S3","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c9c0827e7e9e5f93619a94328496896e26aa98e7","unresolved":false,"context_lines":[{"line_number":477,"context_line":""},{"line_number":478,"context_line":"class InvalidPart(ErrorResponse):"},{"line_number":479,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":480,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":481,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":482,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":483,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"17058515_a0602784","line":480,"range":{"start_line":480,"start_character":66,"end_line":480,"end_character":68},"in_reply_to":"78adf975_cac5ce69","updated":"2025-04-21 22:29:19.000000000","message":"Done","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":478,"context_line":"class InvalidPart(ErrorResponse):"},{"line_number":479,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":480,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":481,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":482,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"3fff93e5_f887fc6e","line":481,"range":{"start_line":481,"start_character":17,"end_line":481,"end_character":30},"updated":"2025-04-16 11:49:51.000000000","message":"less subtlely different!","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c9c0827e7e9e5f93619a94328496896e26aa98e7","unresolved":false,"context_lines":[{"line_number":478,"context_line":"class InvalidPart(ErrorResponse):"},{"line_number":479,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":480,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":481,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":482,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":483,"context_line":""},{"line_number":484,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"e40578ac_f94d07cb","line":481,"range":{"start_line":481,"start_character":17,"end_line":481,"end_character":30},"in_reply_to":"3fff93e5_f887fc6e","updated":"2025-04-21 22:29:19.000000000","message":"Done","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"}],"swift/common/utils/__init__.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":4664,"context_line":"            raise ValueError"},{"line_number":4665,"context_line":"        if base64_str(ret_val) !\u003d value:"},{"line_number":4666,"context_line":"            raise ValueError"},{"line_number":4667,"context_line":"    return ret_val"},{"line_number":4668,"context_line":""},{"line_number":4669,"context_line":""},{"line_number":4670,"context_line":"def base64_str(value):"}],"source_content_type":"text/x-python","patch_set":22,"id":"f70d64e4_e3dba721","line":4667,"updated":"2025-04-16 11:49:51.000000000","message":"I couldn\u0027t see test coverage for this change in test_utils.py","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ef95e6c064f38a543306639c1bf5d0adb753d706","unresolved":false,"context_lines":[{"line_number":4664,"context_line":"            raise ValueError"},{"line_number":4665,"context_line":"        if base64_str(ret_val) !\u003d value:"},{"line_number":4666,"context_line":"            raise ValueError"},{"line_number":4667,"context_line":"    return ret_val"},{"line_number":4668,"context_line":""},{"line_number":4669,"context_line":""},{"line_number":4670,"context_line":"def base64_str(value):"}],"source_content_type":"text/x-python","patch_set":22,"id":"95900959_966fc733","line":4667,"in_reply_to":"f70d64e4_e3dba721","updated":"2025-04-22 10:17:01.000000000","message":"Done","commit_id":"87ff58d549d34f03a71cf38f10828e3596abc7c4"}],"swift/common/utils/checksum.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8e20894bd81255ec3cc62a00ca1336e20fdf87a5","unresolved":true,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        :returns:"},{"line_number":82,"context_line":"        \"\"\""},{"line_number":83,"context_line":"        return CRCHasher(self.crc_func, self.crc)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"def crc32c_ref(data, value\u003d0):"}],"source_content_type":"text/x-python","patch_set":2,"id":"48006b3e_bbe237d2","line":83,"range":{"start_line":83,"start_character":25,"end_line":83,"end_character":48},"updated":"2025-03-12 21:01:58.000000000","message":"this needs to pass width, so width needs to be an attribute","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        :returns:"},{"line_number":82,"context_line":"        \"\"\""},{"line_number":83,"context_line":"        return CRCHasher(self.crc_func, self.crc)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"def crc32c_ref(data, value\u003d0):"}],"source_content_type":"text/x-python","patch_set":2,"id":"cffaba0b_c2aaaca6","line":83,"range":{"start_line":83,"start_character":25,"end_line":83,"end_character":48},"in_reply_to":"3727d8a3_c32acc56","updated":"2025-03-17 15:57:59.000000000","message":"Done","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"726bea4568db3f082445753be2fb6e7dc6db0eaa","unresolved":true,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        :returns:"},{"line_number":82,"context_line":"        \"\"\""},{"line_number":83,"context_line":"        return CRCHasher(self.crc_func, self.crc)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"def crc32c_ref(data, value\u003d0):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3727d8a3_c32acc56","line":83,"range":{"start_line":83,"start_character":25,"end_line":83,"end_character":48},"in_reply_to":"48006b3e_bbe237d2","updated":"2025-03-13 04:30:11.000000000","message":"Good call. Or have one of `width` or `digest_fmt` be a property, derived from the other.","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b3bd3f3d679fb8abd9d2fc92b6e096a03b07ebd5","unresolved":true,"context_lines":[{"line_number":27,"context_line":"except ImportError:"},{"line_number":28,"context_line":"    pkg_files \u003d None"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"# If isal is available system-wide, great!"},{"line_number":32,"context_line":"isal_lib \u003d ctypes.util.find_library(\u0027isal\u0027)"},{"line_number":33,"context_line":"if isal_lib is None and pkg_files is not None:"}],"source_content_type":"text/x-python","patch_set":22,"id":"77076a2b_404a6801","side":"PARENT","line":30,"updated":"2025-04-16 11:49:51.000000000","message":"I liked the whitespace - maybe this was unintentionally removed","commit_id":"98cb5a5ca76c800447ede159a2ea5843a7fb54a3"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c9c0827e7e9e5f93619a94328496896e26aa98e7","unresolved":false,"context_lines":[{"line_number":27,"context_line":"except ImportError:"},{"line_number":28,"context_line":"    pkg_files \u003d None"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"# If isal is available system-wide, great!"},{"line_number":32,"context_line":"isal_lib \u003d ctypes.util.find_library(\u0027isal\u0027)"},{"line_number":33,"context_line":"if isal_lib is None and pkg_files is not None:"}],"source_content_type":"text/x-python","patch_set":22,"id":"c693d321_b597c441","side":"PARENT","line":30,"in_reply_to":"77076a2b_404a6801","updated":"2025-04-21 22:29:19.000000000","message":"Yeah, I think that was all.","commit_id":"98cb5a5ca76c800447ede159a2ea5843a7fb54a3"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0faa46379162270361059ed30841d60e067c3a","unresolved":true,"context_lines":[{"line_number":186,"context_line":"                     initial_value\u003dinitial_value)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"def crc64nvme(data\u003dNone, initial_value\u003d0):"},{"line_number":190,"context_line":"    \u0027\u0027\u0027Stub for s3api\u0027\u0027\u0027"},{"line_number":191,"context_line":"    raise NotImplementedError"},{"line_number":192,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"e32d58ae_9b1dfa77","line":189,"updated":"2025-06-27 01:53:44.000000000","message":"from AWS doc, it seems that the latest boto3 or other s3 rust SDK will use ``CRC64NVME`` if user doesn\u0027t select any. Does that mean those users will start to see ``NotImplementedError``?\n\n```\nBecause S3 has default integrity protections, if objects are uploaded without a checksum, S3 automatically attaches the recommended full object CRC-64/NVME (CRC64NVME) checksum algorithm to the object.\nhttps://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html\n```","commit_id":"d4c26cb683be2bbdbc6e68e9f32b6bea1527f0a7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2442dc0b70867680fd1b3fe026bb10cf94e522e1","unresolved":true,"context_lines":[{"line_number":186,"context_line":"                     initial_value\u003dinitial_value)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"def crc64nvme(data\u003dNone, initial_value\u003d0):"},{"line_number":190,"context_line":"    \u0027\u0027\u0027Stub for s3api\u0027\u0027\u0027"},{"line_number":191,"context_line":"    raise NotImplementedError"},{"line_number":192,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"d9044708_f78e46ab","line":189,"in_reply_to":"e32d58ae_9b1dfa77","updated":"2025-07-01 17:20:55.000000000","message":"[Can\u0027t always trust AWS docs.](https://github.com/boto/botocore/blob/develop/botocore/httpchecksum.py#L50)\n\nAWS CLI is a little funny; if you just `pip install` it, you get the 1.x branch, which pulls in boto3/botocore and gets that CRC32 default. But if you go [following AWS\u0027s instructions](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) you\u0027ll get their 2.x branch, [which vendors all that and uses a different default](https://github.com/aws/aws-cli/blob/v2/awscli/botocore/httpchecksum.py#L37).\n\nOther SDKs are likely to be a crap-shoot, but I expect more and more of them to transition to crc64nvme by default -- so yeah, until we also merge https://review.opendev.org/c/openstack/swift/+/946141, users may get some 501s.","commit_id":"d4c26cb683be2bbdbc6e68e9f32b6bea1527f0a7"}],"test/s3api/test_input_errors.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4467034f05443f178f687c9f0d7402afa8d3f802","unresolved":true,"context_lines":[{"line_number":2343,"context_line":"                    \u0027x-amz-checksum-crc32, x-amz-checksum-sha256\u0027})"},{"line_number":2344,"context_line":"        self.assertEqual(resp.status_code, 400, resp.content)"},{"line_number":2345,"context_line":"        self.assertIn(b\u0027\u003cCode\u003eInvalidRequest\u003c/Code\u003e\u0027, resp.content)"},{"line_number":2346,"context_line":"        self.assertIn(b\u0027\u003cMessage\u003eExpecting a single x-amz-checksum- header. \u0027"},{"line_number":2347,"context_line":"                      b\u0027Multiple checksum Types are not allowed.\u003c/Message\u003e\u0027,"},{"line_number":2348,"context_line":"                      resp.content)"},{"line_number":2349,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"bfae98d7_51a397c2","line":2346,"updated":"2025-04-12 17:13:22.000000000","message":"This delta makes me think we need to update our minimum version of boto3(/botocore?)","commit_id":"1ac307f4d8caf08cf11dc78fb553b129523981b1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d850ee7a5856ed02c446366237954992c4acf83f","unresolved":false,"context_lines":[{"line_number":2343,"context_line":"                    \u0027x-amz-checksum-crc32, x-amz-checksum-sha256\u0027})"},{"line_number":2344,"context_line":"        self.assertEqual(resp.status_code, 400, resp.content)"},{"line_number":2345,"context_line":"        self.assertIn(b\u0027\u003cCode\u003eInvalidRequest\u003c/Code\u003e\u0027, resp.content)"},{"line_number":2346,"context_line":"        self.assertIn(b\u0027\u003cMessage\u003eExpecting a single x-amz-checksum- header. \u0027"},{"line_number":2347,"context_line":"                      b\u0027Multiple checksum Types are not allowed.\u003c/Message\u003e\u0027,"},{"line_number":2348,"context_line":"                      resp.content)"},{"line_number":2349,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"83e1f0a3_6c2d0cbb","line":2346,"in_reply_to":"bfae98d7_51a397c2","updated":"2025-05-13 22:53:39.000000000","message":"Done","commit_id":"1ac307f4d8caf08cf11dc78fb553b129523981b1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"36ba8119ca5b102d038e8a3d54c5d055b5d38b07","unresolved":true,"context_lines":[{"line_number":239,"context_line":"class S3SessionV2Query(S3SessionV2):"},{"line_number":240,"context_line":"    def date_to_sign(self, request):"},{"line_number":241,"context_line":"        return str(int((request[\u0027now\u0027] - EPOCH).total_seconds())"},{"line_number":242,"context_line":"                   + self.default_expiration)"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def sign_request(self, request):"},{"line_number":245,"context_line":"        bundle \u003d self.sign_v2(request)"}],"source_content_type":"text/x-python","patch_set":36,"id":"9bb62c75_39e06610","line":242,"updated":"2025-06-13 17:22:20.000000000","message":"I wasn\u0027t looking *that* closely when I squashed in https://review.opendev.org/c/openstack/swift/+/952391 -- I don\u0027t actually like this part of the change. Every other `S3Session` subclass has `date_to_sign` pull the value directly out of the request dict -- this allows callers to do things like break apart `make_request`, do some extra manipulations to the request dict, and have signing still produce a valid signature. Now, I\u0027m not sure you could sign with something other than the default expiration time...\n\nMaybe it\u0027s telling that the only places we *do* break apart `make_request` (`get_response_put_object_no_md5_no_sha_no_content_length`, `test_no_md5_good_sha_no_content_length`, the various `STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER` tests [which should probably get a helper hanging off `S3SessionV4`]) *don\u0027t* touch the request dict between `build_request` and `sign_request` -- maybe it\u0027s a crappy abstraction -- but it made sense in my head to try my best to separate building up everything we want to send as part of a request from the signing of that request.","commit_id":"bc41a2c1b51836ed50085b7398f0fe77b9a1518c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"028f9cdf860b8c14543146620f68fcd0d7b9a950","unresolved":false,"context_lines":[{"line_number":239,"context_line":"class S3SessionV2Query(S3SessionV2):"},{"line_number":240,"context_line":"    def date_to_sign(self, request):"},{"line_number":241,"context_line":"        return str(int((request[\u0027now\u0027] - EPOCH).total_seconds())"},{"line_number":242,"context_line":"                   + self.default_expiration)"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    def sign_request(self, request):"},{"line_number":245,"context_line":"        bundle \u003d self.sign_v2(request)"}],"source_content_type":"text/x-python","patch_set":36,"id":"ecbbe9d3_2bb50969","line":242,"in_reply_to":"9bb62c75_39e06610","updated":"2025-06-26 19:42:58.000000000","message":"Done","commit_id":"bc41a2c1b51836ed50085b7398f0fe77b9a1518c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"917f9c1be96b21bf66f6e1766e6d3bdac99393bd","unresolved":true,"context_lines":[{"line_number":928,"context_line":"                \u0027content-md5\u0027: _md5(TEST_BODY),"},{"line_number":929,"context_line":"                \u0027x-amz-content-sha256\u0027: _sha256(TEST_BODY),"},{"line_number":930,"context_line":"                \u0027x-amz-checksum-crc32\u0027: _crc32(b\u0027not the body\u0027)})"},{"line_number":931,"context_line":"        self.assertEqual(resp.status_code, 400, resp.content)"},{"line_number":932,"context_line":"        self.assertIn(b\u0027\u003cCode\u003eBadDigest\u003c/Code\u003e\u0027, resp.content)"},{"line_number":933,"context_line":"        self.assertIn(b\u0027\u003cMessage\u003eThe CRC32 you specified did not match the \u0027"},{"line_number":934,"context_line":"                      b\u0027calculated checksum.\u003c/Message\u003e\u0027, resp.content)"},{"line_number":935,"context_line":""},{"line_number":936,"context_line":"    def test_good_md5_bad_sha_bad_crc_header(self):"},{"line_number":937,"context_line":"        resp \u003d self.conn.make_request("}],"source_content_type":"text/x-python","patch_set":42,"id":"430881c8_13093d33","line":934,"range":{"start_line":931,"start_character":8,"end_line":934,"end_character":70},"updated":"2025-07-09 18:07:22.000000000","message":"We repeat this four times; might want to make a helper.","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"38e847cfe932f47228982fcb4f6f61a4a10ec0e7","unresolved":false,"context_lines":[{"line_number":928,"context_line":"                \u0027content-md5\u0027: _md5(TEST_BODY),"},{"line_number":929,"context_line":"                \u0027x-amz-content-sha256\u0027: _sha256(TEST_BODY),"},{"line_number":930,"context_line":"                \u0027x-amz-checksum-crc32\u0027: _crc32(b\u0027not the body\u0027)})"},{"line_number":931,"context_line":"        self.assertEqual(resp.status_code, 400, resp.content)"},{"line_number":932,"context_line":"        self.assertIn(b\u0027\u003cCode\u003eBadDigest\u003c/Code\u003e\u0027, resp.content)"},{"line_number":933,"context_line":"        self.assertIn(b\u0027\u003cMessage\u003eThe CRC32 you specified did not match the \u0027"},{"line_number":934,"context_line":"                      b\u0027calculated checksum.\u003c/Message\u003e\u0027, resp.content)"},{"line_number":935,"context_line":""},{"line_number":936,"context_line":"    def test_good_md5_bad_sha_bad_crc_header(self):"},{"line_number":937,"context_line":"        resp \u003d self.conn.make_request("}],"source_content_type":"text/x-python","patch_set":42,"id":"5afadf23_9f0adf71","line":934,"range":{"start_line":931,"start_character":8,"end_line":934,"end_character":70},"in_reply_to":"430881c8_13093d33","updated":"2025-07-10 17:01:24.000000000","message":"Done","commit_id":"ab01f3eda55be28fd0d1a065044a63181f1cf52c"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":false,"context_lines":[{"line_number":894,"context_line":"                \u0027content-md5\u0027: _md5(TEST_BODY),"},{"line_number":895,"context_line":"                \u0027x-amz-content-sha256\u0027: _sha256(TEST_BODY),"},{"line_number":896,"context_line":"                \u0027x-amz-sdk-checksum-algorithm\u0027: \u0027CRC32C\u0027,"},{"line_number":897,"context_line":"                \u0027x-amz-checksum-crc32\u0027: _crc32(TEST_BODY),"},{"line_number":898,"context_line":"            })"},{"line_number":899,"context_line":"        self.assertEqual(resp.status_code, 400, resp.content)"},{"line_number":900,"context_line":"        self.assertIn(b\u0027\u003cCode\u003eInvalidRequest\u003c/Code\u003e\u0027, resp.content)"}],"source_content_type":"text/x-python","patch_set":43,"id":"ec8e27d4_05c00db3","line":897,"updated":"2025-07-15 16:10:59.000000000","message":"I stared at this test case to find out where is the mismatch, finally found out it\u0027s ``crc32c`` versus ``crc32``","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":false,"context_lines":[{"line_number":973,"context_line":"                      b\u0027x-amz-checksum- header is invalid.\u003c/Message\u003e\u0027,"},{"line_number":974,"context_line":"                      resp.content)"},{"line_number":975,"context_line":""},{"line_number":976,"context_line":"    def test_no_md5_good_sha_multiple_crc_in_headers(self):"},{"line_number":977,"context_line":"        resp \u003d self.conn.make_request("},{"line_number":978,"context_line":"            self.bucket_name,"},{"line_number":979,"context_line":"            \u0027bad-checksum\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"f85079c2_dc3eed52","line":976,"updated":"2025-07-15 16:10:59.000000000","message":"I don\u0027t see a case in this file to verify that crc64nvme checksums are not yet supported, but that\u0027s okay since we are going to support that in the follow-up!","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":true,"context_lines":[{"line_number":2574,"context_line":"                      b\u0027Multiple checksum Types are not allowed.\u003c/Message\u003e\u0027,"},{"line_number":2575,"context_line":"                      resp.content)"},{"line_number":2576,"context_line":""},{"line_number":2577,"context_line":"    def test_strm_unsgnd_pyld_trl_multiple_trailers_unsupported(self):"},{"line_number":2578,"context_line":"        chunked_body \u003d b\u0027\u0027.join("},{"line_number":2579,"context_line":"            b\u0027%x\\r\\n%s\\r\\n\u0027 % (len(chunk), chunk)"},{"line_number":2580,"context_line":"            for chunk in [TEST_BODY, b\u0027\u0027])[:-2]"}],"source_content_type":"text/x-python","patch_set":43,"id":"cf38541f_b1f4530c","line":2577,"updated":"2025-07-15 16:10:59.000000000","message":"a lot of those test cases only diff in the input trailer name/value and the test assertion, probably in future someone could implement a template test function with input parameters of different test conditions and expected results.","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"}],"test/s3api/test_object_checksums.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cc0a0782f469707b49c4d9a0a59a313387ac488e","unresolved":true,"context_lines":[{"line_number":316,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":317,"context_line":"        self.assertEqual("},{"line_number":318,"context_line":"            resp[\u0027Error\u0027][\u0027Message\u0027],"},{"line_number":319,"context_line":"            \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def assert_invalid(self, resp):"},{"line_number":322,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"f4735501_0a1f69ca","line":319,"updated":"2025-03-11 22:40:14.000000000","message":"Fails on AWS with `Expecting a single x-amz-checksum- header` -- presumably because boto3 (now?) sends ChecksumCRC32 in headers and ChecksumSHA1 in trailers? Might need to use our own client to test this scenario.","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a17cc91c40ba1d419fcb76ba8662e7899e2bd395","unresolved":false,"context_lines":[{"line_number":316,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":317,"context_line":"        self.assertEqual("},{"line_number":318,"context_line":"            resp[\u0027Error\u0027][\u0027Message\u0027],"},{"line_number":319,"context_line":"            \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def assert_invalid(self, resp):"},{"line_number":322,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"650da4a4_b419ca6f","line":319,"in_reply_to":"220adff3_40a838d7","updated":"2025-05-20 19:11:19.000000000","message":"Split the test expectations based on boto version.","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"8cf829e534270485e4f4d8d5e5cb79f9373300b7","unresolved":true,"context_lines":[{"line_number":316,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":317,"context_line":"        self.assertEqual("},{"line_number":318,"context_line":"            resp[\u0027Error\u0027][\u0027Message\u0027],"},{"line_number":319,"context_line":"            \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def assert_invalid(self, resp):"},{"line_number":322,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"220adff3_40a838d7","line":319,"in_reply_to":"2f0bf0f1_7eb362a7","updated":"2025-05-14 04:22:24.000000000","message":"Soounds like we need to drop support for py37 ;)","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa18c9f53e80a840f0cdd97be22718aada874069","unresolved":true,"context_lines":[{"line_number":316,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":317,"context_line":"        self.assertEqual("},{"line_number":318,"context_line":"            resp[\u0027Error\u0027][\u0027Message\u0027],"},{"line_number":319,"context_line":"            \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def assert_invalid(self, resp):"},{"line_number":322,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"e9632816_2acd05c5","line":319,"in_reply_to":"abb5879b_816151ba","updated":"2025-05-12 14:49:43.000000000","message":"Fails with Swift in same way with boto3\u003c1.36\n```AssertionError: \u0027Expecting a single x-amz-checksum- header\u0027 !\u003d \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027```","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d850ee7a5856ed02c446366237954992c4acf83f","unresolved":true,"context_lines":[{"line_number":316,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":317,"context_line":"        self.assertEqual("},{"line_number":318,"context_line":"            resp[\u0027Error\u0027][\u0027Message\u0027],"},{"line_number":319,"context_line":"            \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def assert_invalid(self, resp):"},{"line_number":322,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"2f0bf0f1_7eb362a7","line":319,"in_reply_to":"e9632816_2acd05c5","updated":"2025-05-13 22:53:39.000000000","message":"Updated `test-requirements.txt` -- but that demonstrated that boto3 1.36.0 requires py38+ :-(","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":true,"context_lines":[{"line_number":316,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":317,"context_line":"        self.assertEqual("},{"line_number":318,"context_line":"            resp[\u0027Error\u0027][\u0027Message\u0027],"},{"line_number":319,"context_line":"            \u0027Value for x-amz-sdk-checksum-algorithm header is invalid.\u0027)"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def assert_invalid(self, resp):"},{"line_number":322,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"abb5879b_816151ba","line":319,"in_reply_to":"f4735501_0a1f69ca","updated":"2025-03-17 15:57:59.000000000","message":"We likely also need to update our minimum-supported boto3/botocore version in `test-requirements.txt`...","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cc0a0782f469707b49c4d9a0a59a313387ac488e","unresolved":true,"context_lines":[{"line_number":446,"context_line":"        items \u003d [o for o in list_objects_resp[\u0027Contents\u0027]"},{"line_number":447,"context_line":"                 if o[\u0027Key\u0027] \u003d\u003d obj_name]"},{"line_number":448,"context_line":"        self.assertEqual(len(items), 1, items)"},{"line_number":449,"context_line":"        self.assertNotIn(\u0027ChecksumAlgorithm\u0027, items[0])"},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"    def test_mpu_upload_part_multi_checksum(self):"},{"line_number":452,"context_line":"        obj_name \u003d self.create_name(\u0027multi-checksum-mpu\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f65ee90_3f458dfb","line":449,"updated":"2025-03-11 22:40:14.000000000","message":"Fails on AWS! Despite the HEAD with `X-Amz-Checksum-Mode: ENABLED` not having it, listings now have CRC64NVME!\n\nI hate chasing an API we have no control over.","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1154d3ac7c93390458bf52201c7a0972809a7ad1","unresolved":false,"context_lines":[{"line_number":446,"context_line":"        items \u003d [o for o in list_objects_resp[\u0027Contents\u0027]"},{"line_number":447,"context_line":"                 if o[\u0027Key\u0027] \u003d\u003d obj_name]"},{"line_number":448,"context_line":"        self.assertEqual(len(items), 1, items)"},{"line_number":449,"context_line":"        self.assertNotIn(\u0027ChecksumAlgorithm\u0027, items[0])"},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"    def test_mpu_upload_part_multi_checksum(self):"},{"line_number":452,"context_line":"        obj_name \u003d self.create_name(\u0027multi-checksum-mpu\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"c7b3d1bc_5a302e25","line":449,"in_reply_to":"3f65ee90_3f458dfb","updated":"2025-03-17 15:57:59.000000000","message":"Done","commit_id":"d0a805570aed2afdf69590f1f73e8dcdb4aac3d9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"24900bf49b6894887aff871689ce4de6343c00c0","unresolved":true,"context_lines":[{"line_number":215,"context_line":"        )"},{"line_number":216,"context_line":"        self.assertEqual(200, complete_mpu_resp["},{"line_number":217,"context_line":"            \u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":218,"context_line":"        # TODO: AWS includes the checksum in the response, but Swift doesn\u0027t"},{"line_number":219,"context_line":"        # self.assertIn(\u0027Checksum\u0027 + self.ALGORITHM, complete_mpu_resp)"},{"line_number":220,"context_line":"        # self.assertEqual(complete_mpu_resp[\u0027Checksum\u0027 + self.ALGORITHM][-2:],"},{"line_number":221,"context_line":"        #                  \u0027-1\u0027)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class TestObjectChecksumCRC32(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":12,"id":"30623e5f_0547479a","line":221,"range":{"start_line":218,"start_character":7,"end_line":221,"end_character":32},"updated":"2025-04-04 05:51:31.000000000","message":"Dangling todo and commented out code doesn\u0027t look great. But this can always be tackled in a follow up. At least it\u0027s here to remind us.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d850ee7a5856ed02c446366237954992c4acf83f","unresolved":true,"context_lines":[{"line_number":215,"context_line":"        )"},{"line_number":216,"context_line":"        self.assertEqual(200, complete_mpu_resp["},{"line_number":217,"context_line":"            \u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":218,"context_line":"        # TODO: AWS includes the checksum in the response, but Swift doesn\u0027t"},{"line_number":219,"context_line":"        # self.assertIn(\u0027Checksum\u0027 + self.ALGORITHM, complete_mpu_resp)"},{"line_number":220,"context_line":"        # self.assertEqual(complete_mpu_resp[\u0027Checksum\u0027 + self.ALGORITHM][-2:],"},{"line_number":221,"context_line":"        #                  \u0027-1\u0027)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class TestObjectChecksumCRC32(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a0f4084_9ca3a8e3","line":221,"range":{"start_line":218,"start_character":7,"end_line":221,"end_character":32},"in_reply_to":"053d8ab6_0e24e28d","updated":"2025-05-13 22:53:39.000000000","message":"Removed.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e4291b36fafcf79ac7eacb5cee3c5229838f7a43","unresolved":true,"context_lines":[{"line_number":215,"context_line":"        )"},{"line_number":216,"context_line":"        self.assertEqual(200, complete_mpu_resp["},{"line_number":217,"context_line":"            \u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":218,"context_line":"        # TODO: AWS includes the checksum in the response, but Swift doesn\u0027t"},{"line_number":219,"context_line":"        # self.assertIn(\u0027Checksum\u0027 + self.ALGORITHM, complete_mpu_resp)"},{"line_number":220,"context_line":"        # self.assertEqual(complete_mpu_resp[\u0027Checksum\u0027 + self.ALGORITHM][-2:],"},{"line_number":221,"context_line":"        #                  \u0027-1\u0027)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class TestObjectChecksumCRC32(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":12,"id":"8f32f838_4df152fe","line":221,"range":{"start_line":218,"start_character":7,"end_line":221,"end_character":32},"in_reply_to":"30623e5f_0547479a","updated":"2025-04-10 15:41:52.000000000","message":"I agree TODO\u0027s don\u0027t look great but this is a genuine further feature work TODO rather than \"this patch isn\u0027t finished\". IIUC we need to start persisting metadata w.r.t. the checksum algorithm in order to become s3api compliant in this respect, and I guess Tim (or whoever) wants a reminder to make the assertion here.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e48a03453a13cbcc78d163099890be9f72fdd530","unresolved":false,"context_lines":[{"line_number":215,"context_line":"        )"},{"line_number":216,"context_line":"        self.assertEqual(200, complete_mpu_resp["},{"line_number":217,"context_line":"            \u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":218,"context_line":"        # TODO: AWS includes the checksum in the response, but Swift doesn\u0027t"},{"line_number":219,"context_line":"        # self.assertIn(\u0027Checksum\u0027 + self.ALGORITHM, complete_mpu_resp)"},{"line_number":220,"context_line":"        # self.assertEqual(complete_mpu_resp[\u0027Checksum\u0027 + self.ALGORITHM][-2:],"},{"line_number":221,"context_line":"        #                  \u0027-1\u0027)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class TestObjectChecksumCRC32(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":12,"id":"0d9d85f5_23990a7c","line":221,"range":{"start_line":218,"start_character":7,"end_line":221,"end_character":32},"in_reply_to":"5a0f4084_9ca3a8e3","updated":"2025-06-11 18:03:35.000000000","message":"Done","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa18c9f53e80a840f0cdd97be22718aada874069","unresolved":true,"context_lines":[{"line_number":215,"context_line":"        )"},{"line_number":216,"context_line":"        self.assertEqual(200, complete_mpu_resp["},{"line_number":217,"context_line":"            \u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":218,"context_line":"        # TODO: AWS includes the checksum in the response, but Swift doesn\u0027t"},{"line_number":219,"context_line":"        # self.assertIn(\u0027Checksum\u0027 + self.ALGORITHM, complete_mpu_resp)"},{"line_number":220,"context_line":"        # self.assertEqual(complete_mpu_resp[\u0027Checksum\u0027 + self.ALGORITHM][-2:],"},{"line_number":221,"context_line":"        #                  \u0027-1\u0027)"},{"line_number":222,"context_line":""},{"line_number":223,"context_line":""},{"line_number":224,"context_line":"class TestObjectChecksumCRC32(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":12,"id":"053d8ab6_0e24e28d","line":221,"range":{"start_line":218,"start_character":7,"end_line":221,"end_character":32},"in_reply_to":"8f32f838_4df152fe","updated":"2025-05-12 14:49:43.000000000","message":"An alternative would be to write a test that makes these assertions but skips, as a reminder that we have a compatibility gap?","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"24900bf49b6894887aff871689ce4de6343c00c0","unresolved":true,"context_lines":[{"line_number":462,"context_line":"        })"},{"line_number":463,"context_line":"        # You\u0027d think we ought to be able to validate \u0026 store both..."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _upload_parts(self, base_name, part_numbers):"},{"line_number":466,"context_line":"        obj_name \u003d self.create_name(base_name)"},{"line_number":467,"context_line":"        create_mpu_resp \u003d self.client.create_multipart_upload("},{"line_number":468,"context_line":"            Bucket\u003dself.bucket_name, Key\u003dobj_name,"}],"source_content_type":"text/x-python","patch_set":12,"id":"a033b836_853828a8","line":465,"updated":"2025-04-04 05:51:31.000000000","message":"I don\u0027t see this helper method being used anywhere. Or maybe I just missed it?","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4f247dd166c45c4c5335c037a752683f68b9e195","unresolved":false,"context_lines":[{"line_number":462,"context_line":"        })"},{"line_number":463,"context_line":"        # You\u0027d think we ought to be able to validate \u0026 store both..."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _upload_parts(self, base_name, part_numbers):"},{"line_number":466,"context_line":"        obj_name \u003d self.create_name(base_name)"},{"line_number":467,"context_line":"        create_mpu_resp \u003d self.client.create_multipart_upload("},{"line_number":468,"context_line":"            Bucket\u003dself.bucket_name, Key\u003dobj_name,"}],"source_content_type":"text/x-python","patch_set":12,"id":"53f4f32d_576b883a","line":465,"in_reply_to":"127a1f00_1c029eff","updated":"2025-05-12 18:36:14.000000000","message":"It came from https://review.opendev.org/c/openstack/swift/+/909802 -- when we flipped the order of the chain and ruled out writing down the checksums as out-of-scope, the handful of tests that used it got dropped (because they relied on the writing-down).\n\nThanks for cleaning it up, Alistair.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f565c707e0d768c90d88011abe1ae80f4a2c30a1","unresolved":true,"context_lines":[{"line_number":462,"context_line":"        })"},{"line_number":463,"context_line":"        # You\u0027d think we ought to be able to validate \u0026 store both..."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _upload_parts(self, base_name, part_numbers):"},{"line_number":466,"context_line":"        obj_name \u003d self.create_name(base_name)"},{"line_number":467,"context_line":"        create_mpu_resp \u003d self.client.create_multipart_upload("},{"line_number":468,"context_line":"            Bucket\u003dself.bucket_name, Key\u003dobj_name,"}],"source_content_type":"text/x-python","patch_set":12,"id":"9680a507_d42cf355","line":465,"in_reply_to":"1d1c401a_12b78ef9","updated":"2025-05-12 08:59:54.000000000","message":"bump? i wanna get these things a merg\u0027n.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa18c9f53e80a840f0cdd97be22718aada874069","unresolved":false,"context_lines":[{"line_number":462,"context_line":"        })"},{"line_number":463,"context_line":"        # You\u0027d think we ought to be able to validate \u0026 store both..."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _upload_parts(self, base_name, part_numbers):"},{"line_number":466,"context_line":"        obj_name \u003d self.create_name(base_name)"},{"line_number":467,"context_line":"        create_mpu_resp \u003d self.client.create_multipart_upload("},{"line_number":468,"context_line":"            Bucket\u003dself.bucket_name, Key\u003dobj_name,"}],"source_content_type":"text/x-python","patch_set":12,"id":"127a1f00_1c029eff","line":465,"in_reply_to":"9680a507_d42cf355","updated":"2025-05-12 14:49:43.000000000","message":"Done","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e4291b36fafcf79ac7eacb5cee3c5229838f7a43","unresolved":true,"context_lines":[{"line_number":462,"context_line":"        })"},{"line_number":463,"context_line":"        # You\u0027d think we ought to be able to validate \u0026 store both..."},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _upload_parts(self, base_name, part_numbers):"},{"line_number":466,"context_line":"        obj_name \u003d self.create_name(base_name)"},{"line_number":467,"context_line":"        create_mpu_resp \u003d self.client.create_multipart_upload("},{"line_number":468,"context_line":"            Bucket\u003dself.bucket_name, Key\u003dobj_name,"}],"source_content_type":"text/x-python","patch_set":12,"id":"1d1c401a_12b78ef9","line":465,"in_reply_to":"a033b836_853828a8","updated":"2025-04-10 15:41:52.000000000","message":"hmmm, maybe it gets used in a follow-on. I\u0027m going to leave it (and your comment) until we track it down. But agree it shouldn\u0027t merge as is.","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4467034f05443f178f687c9f0d7402afa8d3f802","unresolved":true,"context_lines":[{"line_number":246,"context_line":"    @classmethod"},{"line_number":247,"context_line":"    def setUpClass(cls):"},{"line_number":248,"context_line":"        # reminder to add these tests in future"},{"line_number":249,"context_line":"        raise SkipTest(\u0027Swift does not support crc64nvme\u0027)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"class TestObjectChecksumSHA1(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":17,"id":"55afc0db_17f6a02c","line":249,"updated":"2025-04-12 17:13:22.000000000","message":"Just axe this until the next patch where we add support.","commit_id":"7fe0d81ed7c0a701cf4d8f5281f9ce90b8cf31a3"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2e70a462f2119fb8ed0a9fb04096a93fd3b8ecbf","unresolved":false,"context_lines":[{"line_number":246,"context_line":"    @classmethod"},{"line_number":247,"context_line":"    def setUpClass(cls):"},{"line_number":248,"context_line":"        # reminder to add these tests in future"},{"line_number":249,"context_line":"        raise SkipTest(\u0027Swift does not support crc64nvme\u0027)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"class TestObjectChecksumSHA1(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":17,"id":"a2020cb8_a8b62471","line":249,"in_reply_to":"55afc0db_17f6a02c","updated":"2025-04-14 03:55:58.000000000","message":"Done","commit_id":"7fe0d81ed7c0a701cf4d8f5281f9ce90b8cf31a3"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"efc09ccd7cd1dff882edb2c0a7e6879931bfc2d9","unresolved":true,"context_lines":[{"line_number":29,"context_line":"    return tuple(int(x) for x in botocore.__version__.split(\u0027.\u0027)) \u003e\u003d version"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class ObjectChecksumMixin(object):"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    @classmethod"},{"line_number":35,"context_line":"    def setUpClass(cls):"}],"source_content_type":"text/x-python","patch_set":43,"id":"5d8daf69_a5c593e9","line":32,"updated":"2025-07-15 16:10:59.000000000","message":"Very good test coverages for s3 client ``put_object``. probably we are missing ``copy_object``, since it uses PUT and we will support checksum validation during object copy operations as well with this patch.","commit_id":"be56c1e25822a23a6f6ad30d190782a395f3149f"}],"test/unit/common/middleware/s3api/test_s3request.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b9e715fb42ce3df167ab4e93c412ac07a7e1a008","unresolved":true,"context_lines":[{"line_number":1743,"context_line":"                         sigv4_req.environ[\u0027wsgi.input\u0027].read())"},{"line_number":1744,"context_line":""},{"line_number":1745,"context_line":"    @patch.object(S3Request, \u0027_validate_dates\u0027, lambda *a: None)"},{"line_number":1746,"context_line":"    def test_sig_v4_strm_unsgnd_pyld_trl_checksum_hdr_sha1_mismatch(self):"},{"line_number":1747,"context_line":"        body \u003d \u0027a\\r\\nabcdefghij\\r\\n\u0027 \\"},{"line_number":1748,"context_line":"               \u0027a\\r\\nklmnopqrst\\r\\n\u0027 \\"},{"line_number":1749,"context_line":"               \u00277\\r\\nuvwxyz\\n\\r\\n\u0027 \\"}],"source_content_type":"text/x-python","patch_set":12,"id":"97da0ebc_50bb8ba9","line":1746,"range":{"start_line":1746,"start_character":54,"end_line":1746,"end_character":58},"updated":"2025-04-03 05:00:00.000000000","message":"Are we trying to be exhaustive here? Should we add cases for `sha256` (and `crc64nvme`, if we keep it for this patch), too? Or just have our cross-compat tests cover them, since they want to be exhaustive anyway?","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b078e0f1d5524cd0b808d4354e535016906f6451","unresolved":false,"context_lines":[{"line_number":1743,"context_line":"                         sigv4_req.environ[\u0027wsgi.input\u0027].read())"},{"line_number":1744,"context_line":""},{"line_number":1745,"context_line":"    @patch.object(S3Request, \u0027_validate_dates\u0027, lambda *a: None)"},{"line_number":1746,"context_line":"    def test_sig_v4_strm_unsgnd_pyld_trl_checksum_hdr_sha1_mismatch(self):"},{"line_number":1747,"context_line":"        body \u003d \u0027a\\r\\nabcdefghij\\r\\n\u0027 \\"},{"line_number":1748,"context_line":"               \u0027a\\r\\nklmnopqrst\\r\\n\u0027 \\"},{"line_number":1749,"context_line":"               \u00277\\r\\nuvwxyz\\n\\r\\n\u0027 \\"}],"source_content_type":"text/x-python","patch_set":12,"id":"83aa5c74_f2416f07","line":1746,"range":{"start_line":1746,"start_character":54,"end_line":1746,"end_character":58},"in_reply_to":"1fd57cb8_ac6299f7","updated":"2025-04-22 10:11:55.000000000","message":"Acknowledged","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"97546fa435e6f813bf0649499707724b06cfc790","unresolved":true,"context_lines":[{"line_number":1743,"context_line":"                         sigv4_req.environ[\u0027wsgi.input\u0027].read())"},{"line_number":1744,"context_line":""},{"line_number":1745,"context_line":"    @patch.object(S3Request, \u0027_validate_dates\u0027, lambda *a: None)"},{"line_number":1746,"context_line":"    def test_sig_v4_strm_unsgnd_pyld_trl_checksum_hdr_sha1_mismatch(self):"},{"line_number":1747,"context_line":"        body \u003d \u0027a\\r\\nabcdefghij\\r\\n\u0027 \\"},{"line_number":1748,"context_line":"               \u0027a\\r\\nklmnopqrst\\r\\n\u0027 \\"},{"line_number":1749,"context_line":"               \u00277\\r\\nuvwxyz\\n\\r\\n\u0027 \\"}],"source_content_type":"text/x-python","patch_set":12,"id":"1fd57cb8_ac6299f7","line":1746,"range":{"start_line":1746,"start_character":54,"end_line":1746,"end_character":58},"in_reply_to":"97da0ebc_50bb8ba9","updated":"2025-04-03 08:32:56.000000000","message":"we already had sha256 cases covered (lines 1626-1665) and crc64nvme coming in squashable patches\n\nI\u0027m not claiming to be exhaustive but I\u0027ll add unit tests when I find a gap because they are easier for debugging","commit_id":"99e76c7056ca7b591a70bb20b574fb6d3cb757fd"}]}
