)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ad06d4c2b5bbcf6912af589e3f94049cc23c8f22","unresolved":true,"context_lines":[{"line_number":20,"context_line":"request body has matched the supplied checksum. Return the checksum on"},{"line_number":21,"context_line":"PUT responses, and on whole-object GET/HEAD responses when the client"},{"line_number":22,"context_line":"requests x-amz-checksum-mode: ENABLED. Return checksum metadata on"},{"line_number":23,"context_line":"CopyObject requests aswell."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"For objects with versioning enabled, this patch adds the ability for"},{"line_number":26,"context_line":"footer callbacks to be automatically passed onto the hidden container"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"f6979cbe_f245fcf2","line":23,"updated":"2026-07-16 16:10:33.000000000","message":"s/aswell/as well","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c63ac75b45a4aee449aacd462f259b27b1d1b1c8","unresolved":false,"context_lines":[{"line_number":20,"context_line":"request body has matched the supplied checksum. Return the checksum on"},{"line_number":21,"context_line":"PUT responses, and on whole-object GET/HEAD responses when the client"},{"line_number":22,"context_line":"requests x-amz-checksum-mode: ENABLED. Return checksum metadata on"},{"line_number":23,"context_line":"CopyObject requests aswell."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"For objects with versioning enabled, this patch adds the ability for"},{"line_number":26,"context_line":"footer callbacks to be automatically passed onto the hidden container"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"cec86e92_75b03ac0","line":23,"in_reply_to":"f6979cbe_f245fcf2","updated":"2026-07-16 18:34:49.000000000","message":"Done","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ad06d4c2b5bbcf6912af589e3f94049cc23c8f22","unresolved":true,"context_lines":[{"line_number":33,"context_line":"AWS S3 upload checksum behavior:"},{"line_number":34,"context_line":"https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity-upload.html"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"APIImpact"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Change-Id: Ie957413640289c458db35c6e65dbdc0e71652322"},{"line_number":39,"context_line":"Signed-off-by: Nathaniel Martes \u003cnmartes@NVIDIA.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"942d84ba_2b62f613","line":36,"updated":"2026-07-16 16:10:33.000000000","message":"what are those ``APIImpact``?","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c63ac75b45a4aee449aacd462f259b27b1d1b1c8","unresolved":false,"context_lines":[{"line_number":33,"context_line":"AWS S3 upload checksum behavior:"},{"line_number":34,"context_line":"https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity-upload.html"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"APIImpact"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Change-Id: Ie957413640289c458db35c6e65dbdc0e71652322"},{"line_number":39,"context_line":"Signed-off-by: Nathaniel Martes \u003cnmartes@NVIDIA.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"f4f7d19d_e696337c","line":36,"in_reply_to":"942d84ba_2b62f613","updated":"2026-07-16 18:34:49.000000000","message":"I\u0027ve updated the commit message to denote what is changes to the API since new response headers are emitted.","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"629ce0d8b7dbd1e1ff4e6bfff96e31ef5e09ae86","unresolved":false,"context_lines":[{"line_number":33,"context_line":"AWS S3 upload checksum behavior:"},{"line_number":34,"context_line":"https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity-upload.html"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"APIImpact"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Change-Id: Ie957413640289c458db35c6e65dbdc0e71652322"},{"line_number":39,"context_line":"Signed-off-by: Nathaniel Martes \u003cnmartes@NVIDIA.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"f93070bf_ad75cf3e","line":36,"in_reply_to":"f4f7d19d_e696337c","updated":"2026-07-16 18:37:46.000000000","message":"https://docs.openstack.org/contributors/common/git.html\nThe following footers are optional; however, their use is recommended if they are applicable to the patch:\n\nThe APIImpact footer contains a comment about why the change impacts a public HTTP API. Put APIImpact on a line by itself. Use this footer to indicate that the patch impacts a public HTTP API. When this footer is included in a commit message, the API_Working_Group can use it to help find relevant reviews.","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ad06d4c2b5bbcf6912af589e3f94049cc23c8f22","unresolved":true,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"APIImpact"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Change-Id: Ie957413640289c458db35c6e65dbdc0e71652322"},{"line_number":39,"context_line":"Signed-off-by: Nathaniel Martes \u003cnmartes@NVIDIA.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"9239885b_441a9606","line":38,"updated":"2026-07-16 16:10:33.000000000","message":"if Codex/Claude was used, please add ``Assisted-By: \u003ctool-name\u003e [model-version]`` per Openstack requirement: https://docs.openstack.org/cinder/latest/contributor/commit-messages.html","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c63ac75b45a4aee449aacd462f259b27b1d1b1c8","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"APIImpact"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"Change-Id: Ie957413640289c458db35c6e65dbdc0e71652322"},{"line_number":39,"context_line":"Signed-off-by: Nathaniel Martes \u003cnmartes@NVIDIA.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"777284f8_d7e00697","line":38,"in_reply_to":"9239885b_441a9606","updated":"2026-07-16 18:34:49.000000000","message":"Done!","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"4bbdbae3676bc264ae5f4fbf4ad6b3137ccac062","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"2c37decb_46de0dc6","updated":"2026-06-09 13:53:56.000000000","message":"Looks pretty good to me, but please see my inline comment.","commit_id":"1b912f91b63174a730697c8c0591ba2e8581a2c0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ab7abaf22dffecc0c9b790425b172643fc4ed89f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"9a3824fc_0296bed9","updated":"2026-06-17 23:30:17.000000000","message":"I mentioned it over on https://review.opendev.org/c/openstack/swift/+/993193 but I think it\u0027d be better to get the MD5 and SHA512 support into a separate patch. Certainly, as things stand, it\u0027s unfortunate that it isn\u0027t called out in *any* of the commit messages.","commit_id":"769d4f8b5ecd3672b9964697e0388e29916ec731"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"cfeefb4a_44c877af","updated":"2026-06-17 00:00:40.000000000","message":"sorry I didn\u0027t get further on this; FWIW all my initial attempts at agent assisted review of this change were VERY positive.  I think this tells us some important information:\n\n1) the commit message is good!  we know what we\u0027re doing and why\n2) the change works!  we store checksums in sysmeta - we return them on reads; that\u0027s huge!\n3) it\u0027s well tested!  I mean, it would probably be appropriate to add some s3api/functests - but for translating sysmeta headers the `status, headers, body \u003d self.call_s3api(req)` style unitests are actually really great.\n\nAs I worked my way through the diff I found some patterns that may not be blockers - but in aggregate may add up to some important material improvements to maintainability that might make these 700 new lines \"better\"\n\nThere was also some \"issue\" with noqa usedforsecurity md5 that kept popping up and I haven\u0027t had a chance to look into:\n\n```\n# Orchestrator Summary: Gerrit 991516 PS12\n\nChange: https://review.opendev.org/c/openstack/swift/+/991516\nTitle: s3api: User Checksum Persistence for Full Object Uploads\nPatch set: 12\nRef: refs/changes/16/991516/12\nCommit: 769d4f8b5ecd3672b9964697e0388e29916ec731\nParent: bab1688e2c91cb9866c714ee77bb8c45f6885e7b\nSlot: vsaio-1\n\nRecommendation: -1\n\n## Finding\n\n`swift/common/middleware/s3api/s3request.py:110` newly accepts\n`x-amz-checksum-md5` by mapping it to Swift\u0027s `md5` helper, but\n`_get_checksum_hasher()` calls that helper without `usedforsecurity\u003dFalse`.\nSwift\u0027s helper defaults to `usedforsecurity\u003dTrue` in\n`swift/common/utils/base.py:32-39`, unlike existing integrity-MD5 callers\nsuch as `S3Request.check_md5()`.\n\nConcrete failure path: on a Python/OpenSSL build that rejects MD5 for security\nuse, an S3 PUT with `x-amz-checksum-md5` reaches\n`S3Request.__init__() -\u003e _validate_checksum_headers() -\u003e\n_get_checksum_hasher(\u0027x-amz-checksum-md5\u0027)`. The MD5 constructor exception is\nnot caught by `_get_checksum_hasher()`, so S3API\u0027s top-level exception handler\nreturns `500 InternalError` before the object PUT reaches Swift.\n\nAcceptance condition: either use a non-security MD5 wrapper, e.g.\n`lambda: md5(usedforsecurity\u003dFalse)`, with focused coverage for MD5 checksum\nvalidation and persistence, or remove `x-amz-checksum-md5` from the supported\nchecksum table until it can be supported deliberately.\n\n## Non-Blocking Notes\n\n- The main CRC/SHA full-object checksum persistence path is coherent and has\n  direct unit coverage for successful PUT persistence, mismatch\n  non-persistence, copy exclusion, GET/HEAD checksum-mode gating, range/304\n  suppression, and sysmeta-to-response translation.\n- Algorithm-surface tests for `sha512` and known-unsupported `xxhash*` entries\n  would make the broadened checksum table easier to maintain.\n- I downgraded the defensive worker\u0027s duplicate byte-normalization concern in\n  `_remember_checksum()` to a cleanup note. It is unreachable from the current\n  production caller but does not create a concrete bad outcome.\n\n```\n\n... so I\u0027m posting what I have and I\u0027ll keep on it!","commit_id":"769d4f8b5ecd3672b9964697e0388e29916ec731"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ab7abaf22dffecc0c9b790425b172643fc4ed89f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"a4de6471_4447829e","in_reply_to":"cfeefb4a_44c877af","updated":"2026-06-17 23:30:17.000000000","message":"\u003e There was also some \"issue\" with noqa usedforsecurity md5 that kept popping up and I haven\u0027t had a chance to look into\n\nYeah, it\u0027s telling you that this isn\u0027t going to work on a FIPS-enabled system. We have in-process func tests that run on that config (look for the `-fips` suffix on the jobs); we should probably make sure there\u0027s at least one test under `test/func` that exercises MD5 as s3api checksum.","commit_id":"769d4f8b5ecd3672b9964697e0388e29916ec731"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":25,"id":"849f0a47_c1b11de8","updated":"2026-06-30 23:51:02.000000000","message":"I wanted to push up what I got; honestly I have made enough time to actually PLAY with this change to say if I think it should merge or not - so i\u0027m only posting the stuff I\u0027ve seen/found that I would want to look at more.  Sorry.\n\n```\n# Nits\n\n- `swift/common/middleware/s3api/s3request.py:1637`: the\n  `get_checksum_headers` docstring could state that it returns `{}` before the\n  checksum has been fully validated.\n- `swift/common/middleware/s3api/s3response.py:130`: the helper docstring\n  could say it decides whether stored checksum sysmeta should be exposed as S3\n  checksum headers.\n- `test/unit/common/middleware/s3api/test_s3request.py:1662`: typo,\n  \"since no header to provided\" should be \"since no checksum header was\n  provided.\"\n```","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dc717074059fd84f9cbc4ab9e9f3082744ed1dc2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"36aa56f1_bb2823c1","updated":"2026-07-02 15:09:37.000000000","message":"I may be wrong but voting -1 to ensure the concern about versioning is flagged up","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ad06d4c2b5bbcf6912af589e3f94049cc23c8f22","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":37,"id":"e0bd347d_fdc606c8","updated":"2026-07-16 16:10:33.000000000","message":"this patch says \"User Checksum Persistence for Full Object Uploads\", but it covers MPU segment PUT accidentally, see my comments and test case.","commit_id":"7c52b631f5b0ff7385ebb9d6b8945fdb3d6d9617"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c63ac75b45a4aee449aacd462f259b27b1d1b1c8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":37,"id":"84904a26_0ec979f6","in_reply_to":"467c1451_0840eb35","updated":"2026-07-16 18:34:49.000000000","message":"Sqaushed in https://review.opendev.org/c/openstack/swift/+/991516/38\nThanks!","commit_id":"7c52b631f5b0ff7385ebb9d6b8945fdb3d6d9617"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7ad9e8b55c6873a10482f48c6587338886f49421","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":37,"id":"467c1451_0840eb35","in_reply_to":"e0bd347d_fdc606c8","updated":"2026-07-16 17:02:11.000000000","message":"see test case and proposed fix at: https://review.opendev.org/c/openstack/swift/+/997623","commit_id":"7c52b631f5b0ff7385ebb9d6b8945fdb3d6d9617"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"eab4f2f634742a340710f8822161b2dccaf0e242","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":39,"id":"693c5bd7_e70f8c2e","updated":"2026-07-16 19:13:12.000000000","message":"Added handling for case when POST ?delete` checksum callbacks can pollute versioned delete markers.\n\nThanks Clay and Codex!","commit_id":"66562ca79f57f52f34cc17487020652b4611f619"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":44,"id":"22747d86_8d3ecc43","updated":"2026-07-22 01:29:15.000000000","message":"The core design is sound and good implementation in general, ``-1`` because two edge cases identified for CopyObject.","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"615fc81b531b3893be515c6974fbc9cc0a47a743","unresolved":false,"context_lines":[{"line_number":66,"context_line":"import time"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"from swift.common import constraints"},{"line_number":69,"context_line":"from swift.common.swob import Range, bytes_to_wsgi, normalize_etag, \\"},{"line_number":70,"context_line":"    wsgi_quote, wsgi_to_str, parse_date_header"},{"line_number":71,"context_line":"from swift.common.utils import json, public, reiterate, md5"},{"line_number":72,"context_line":"from swift.common.utils.timestamp import Timestamp, NormalTimestamp"}],"source_content_type":"text/x-python","patch_set":37,"id":"632416d5_04a1267f","line":69,"updated":"2026-07-16 16:54:52.000000000","message":"pep8: F401 \u0027swift.common.swob.parse_date_header\u0027 imported but unused","commit_id":"7c52b631f5b0ff7385ebb9d6b8945fdb3d6d9617"}],"swift/common/middleware/s3api/controllers/obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":41,"context_line":"    def _purge_checksum_response_headers(self, resp):"},{"line_number":42,"context_line":"        for key in list(resp.headers):"},{"line_number":43,"context_line":"            if key.lower().startswith(\u0027x-amz-checksum-\u0027):"},{"line_number":44,"context_line":"                del resp.headers[key]"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def _gen_head_range_resp(self, req_range, resp):"},{"line_number":47,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":11,"id":"c8de5409_1df34d52","line":44,"updated":"2026-06-17 00:00:40.000000000","message":"it seems like most of the `x-amz-checksum` prefix stuff in s3request was buried on the request object - somewhat strange to see the object controller manipulating the `resp` object\u0027s headers directly instead of through an interface that encapsulates the checksum knowledge between the s3request and s3response objects.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    def _purge_checksum_response_headers(self, resp):"},{"line_number":42,"context_line":"        for key in list(resp.headers):"},{"line_number":43,"context_line":"            if key.lower().startswith(\u0027x-amz-checksum-\u0027):"},{"line_number":44,"context_line":"                del resp.headers[key]"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def _gen_head_range_resp(self, req_range, resp):"},{"line_number":47,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":11,"id":"e784ab0e_871deb67","line":44,"in_reply_to":"c8de5409_1df34d52","updated":"2026-06-22 23:53:33.000000000","message":"I agree, these headers should instead only be manipulated in `S3Request` or `S3Response`","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":98,"context_line":"                \u0027object_versioning\u0027 not in get_swift_info():"},{"line_number":99,"context_line":"            raise S3NotImplemented()"},{"line_number":100,"context_line":"        part_number \u003d req.validate_part_number(check_max\u003dFalse)"},{"line_number":101,"context_line":"        checksum_mode_enabled \u003d req.checksum_mode_enabled()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"        query \u003d {}"},{"line_number":104,"context_line":"        if version_id is not None:"}],"source_content_type":"text/x-python","patch_set":11,"id":"40439eb9_3aa08440","line":101,"updated":"2026-06-17 00:00:40.000000000","message":"\u003e how many new abstractions have we added to the req class?\n\nturns out quite a few - and there was some pre-existing once you have to know too!\n\n\u003e what\u0027s the difference between `has_checksum_to_validate` and `checksum_mode_enabled`?\n\nstrangely I read s3request diff and I still don\u0027t know the answer to this question - I\u0027d have to study it.  I think since this is a GET request the \"x-amz-checksum-mode: enabled\" header just says if you want your response to include the extra stored checksum metadata or not.\n\ni.e. GET doesn\u0027t supply a \"checksum_to_validate\" but the way it spells \"checksum_mode_enabled\" is the same as PUT (and just has a different semantic meaning)","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                \u0027object_versioning\u0027 not in get_swift_info():"},{"line_number":99,"context_line":"            raise S3NotImplemented()"},{"line_number":100,"context_line":"        part_number \u003d req.validate_part_number(check_max\u003dFalse)"},{"line_number":101,"context_line":"        checksum_mode_enabled \u003d req.checksum_mode_enabled()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"        query \u003d {}"},{"line_number":104,"context_line":"        if version_id is not None:"}],"source_content_type":"text/x-python","patch_set":11,"id":"5197247f_6711f7d4","line":101,"in_reply_to":"40439eb9_3aa08440","updated":"2026-06-22 23:53:33.000000000","message":"\u003e I think since this is a GET request the \"x-amz-checksum-mode: enabled\" header just says if you want your response to include the extra stored checksum metadata or not.\n\nYea that\u0027s correct, and `has_checksum_to_validate` is true when the request includes a client-supplied checksum that Swift is going to validate against the request body\n\nI think it could be more clear if the variable `has_checksum_to_validate` is changed to `validates_client_checksum` to denote the difference that we are getting something from the client to verify and change `checksum_mode_enabled` to `has_checksum_mode_header` to denote that we search for some request header.\n\nWhat would be even better would be if the controller didn\u0027t deal with the checksum mode at all since it is a `x-amz-checksum` type of header meaning it should be validated just like the other `x-amz-checksum` headers (like `x-amz-sdk-checksum-algorithm` and `x-amz-checksum-type` are in the `S3Request` object","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":140,"context_line":"            if \u0027response-\u0027 + key in req.params:"},{"line_number":141,"context_line":"                resp.headers[key] \u003d req.params[\u0027response-\u0027 + key]"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        if not (checksum_mode_enabled and resp.status_int \u003d\u003d HTTP_OK):"},{"line_number":144,"context_line":"            self._purge_checksum_response_headers(resp)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        return resp"}],"source_content_type":"text/x-python","patch_set":11,"id":"5af30fb4_fbb63333","line":143,"updated":"2026-06-17 00:00:40.000000000","message":"on L141 we\u0027re using req.params\n\nI think the confusing part of \"why are we doing the `checksum_mode_enabled \u003d req.checksum_mode_enabled()` some 40 lines away\" is the `InvalidRequest` side-effect.\n\nI think:\n\n```\nchecksum_mode_enabled \u003d self.validate_checksum_mode_header()\n```\n\nwould be more obvious.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":140,"context_line":"            if \u0027response-\u0027 + key in req.params:"},{"line_number":141,"context_line":"                resp.headers[key] \u003d req.params[\u0027response-\u0027 + key]"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        if not (checksum_mode_enabled and resp.status_int \u003d\u003d HTTP_OK):"},{"line_number":144,"context_line":"            self._purge_checksum_response_headers(resp)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        return resp"}],"source_content_type":"text/x-python","patch_set":11,"id":"5c7f1c30_55e139b6","line":143,"in_reply_to":"5af30fb4_fbb63333","updated":"2026-06-22 23:53:33.000000000","message":"I agree with this, though see comment #101 about moving validation logic to `S3Request`","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":141,"context_line":"                resp.headers[key] \u003d req.params[\u0027response-\u0027 + key]"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        if not (checksum_mode_enabled and resp.status_int \u003d\u003d HTTP_OK):"},{"line_number":144,"context_line":"            self._purge_checksum_response_headers(resp)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        return resp"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"eb8ebf9a_dd0b8797","line":144,"updated":"2026-06-17 00:00:40.000000000","message":"why do we have to *purge* sysmeta - can we just \"only translate sysmeta into user-namespace if user requests them\"","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":141,"context_line":"                resp.headers[key] \u003d req.params[\u0027response-\u0027 + key]"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"        if not (checksum_mode_enabled and resp.status_int \u003d\u003d HTTP_OK):"},{"line_number":144,"context_line":"            self._purge_checksum_response_headers(resp)"},{"line_number":145,"context_line":""},{"line_number":146,"context_line":"        return resp"},{"line_number":147,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"0d6502d7_755d814c","line":144,"in_reply_to":"eb8ebf9a_dd0b8797","updated":"2026-06-22 23:53:33.000000000","message":"We can wrap the logic from `S3Response` to only add the headers if the request needs the headers. Something like:\n```python\n        checksum_header \u003d s3_sysmeta_headers.get(\n            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027))\n        checksum_value \u003d s3_sysmeta_headers.get(\n            sysmeta_header(\u0027object\u0027, \u0027checksum-value\u0027))\n        checksum_type \u003d s3_sysmeta_headers.get(\n            sysmeta_header(\u0027object\u0027, \u0027checksum-type\u0027))\n        if (checksum_header and checksum_value and\n                self._request_needs_checksum_response_headers()):\n            headers[checksum_header] \u003d checksum_value\n            if checksum_type:\n                headers[\u0027x-amz-checksum-type\u0027] \u003d checksum_type\n```","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":156,"context_line":"            req_range \u003d req.headers[\u0027range\u0027]"},{"line_number":157,"context_line":"            resp \u003d self._gen_head_range_resp(req_range, resp)"},{"line_number":158,"context_line":"            if resp.status_int !\u003d HTTP_OK:"},{"line_number":159,"context_line":"                self._purge_checksum_response_headers(resp)"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        return resp"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"169b8975_67244a50","line":159,"updated":"2026-06-17 00:00:40.000000000","message":"are we adding the headers back in again in `_gen_head_range_resp` or just being overly defensive?  I supposed it\u0027s possible - and now I\u0027d have to look.\n\nBecause if there\u0027s a diff hunk here that when reverted doesn\u0027t cause tests to blow up there\u0027s two possible changes you could make:\n\n1) add a test that shows why the hunk is needed\n2) remove the un-needed hunk\n\nIf we\u0027re sprinkling \"if isinstance(bytes)\" and \"if status in (400, 500): remove_headers()\" all over the code \"just in case\" we\u0027re not doing ourselves a favor.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":156,"context_line":"            req_range \u003d req.headers[\u0027range\u0027]"},{"line_number":157,"context_line":"            resp \u003d self._gen_head_range_resp(req_range, resp)"},{"line_number":158,"context_line":"            if resp.status_int !\u003d HTTP_OK:"},{"line_number":159,"context_line":"                self._purge_checksum_response_headers(resp)"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        return resp"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"facda1cf_c6e74e06","line":159,"in_reply_to":"169b8975_67244a50","updated":"2026-06-22 23:53:33.000000000","message":"What AWS does:\n```bash\njohn@doe:~$ printf \u0027hello\u0027 \u003e /tmp/s3-checksum-body\njohn@doe:~$ aws s3api put-object \\\n  --bucket s3checksumtest \\\n  --key checksum-head-range-test \\\n  --body /tmp/s3-checksum-body \\\n  --checksum-algorithm CRC32\n{\n    \"ETag\": \"\\\"5d41402abc4b2a76b9719d911017c592\\\"\",\n    \"ChecksumCRC32\": \"NhCmhg\u003d\u003d\",\n    \"ChecksumType\": \"FULL_OBJECT\",\n    \"ServerSideEncryption\": \"AES256\"\n}\njohn@doe:~$ aws s3api head-object \\\n  --bucket s3checksumtest \\\n  --key checksum-head-range-test \\\n  --checksum-mode ENABLED\n{\n    \"AcceptRanges\": \"bytes\",\n    \"LastModified\": \"2026-06-22T21:09:20+00:00\",\n    \"ContentLength\": 5,\n    \"ChecksumCRC32\": \"NhCmhg\u003d\u003d\",\n    \"ChecksumType\": \"FULL_OBJECT\",\n    \"ETag\": \"\\\"5d41402abc4b2a76b9719d911017c592\\\"\",\n    \"ContentType\": \"binary/octet-stream\",\n    \"ServerSideEncryption\": \"AES256\",\n    \"Metadata\": {}\n}\njohn@doe:~$ aws s3api head-object \\\n  --bucket s3checksumtest \\\n  --key checksum-head-range-test \\\n  --checksum-mode ENABLED \\\n  --range bytes\u003d0-3\n{\n    \"AcceptRanges\": \"bytes\",\n    \"LastModified\": \"2026-06-22T21:09:20+00:00\",\n    \"ContentLength\": 4,\n    \"ETag\": \"\\\"5d41402abc4b2a76b9719d911017c592\\\"\",\n    \"ContentType\": \"binary/octet-stream\",\n    \"ContentRange\": \"bytes 0-3/5\",\n    \"ServerSideEncryption\": \"AES256\",\n    \"Metadata\": {}\n}\n\n```\n\nTLDR:\nWe should remove the hunk since logic to add the checksum headers will be in `S3Response`\n\nThe Not TLDR:\nIf an AWS client performs a request that represents a full object (full HEAD or GET request),then it omits the checksum. We should follow this so we should omit the headers and add a test to denote the behavior. Thankfully, some test do exist! Though, they use `purge`, but i\u0027ll change them to `omit` for clarity.\n\nThere is an edge case that when a user makes a range request, but the range is just the same as the full object, then we still need to include the header.\n\n```bash\njohn@doe:~$ aws s3api head-object   --bucket s3checksumtest   --key checksum-head-range-test   --checksum-mode ENABLED   --range bytes\u003d0-4\n{\n    \"AcceptRanges\": \"bytes\",\n    \"LastModified\": \"2026-06-22T21:09:20+00:00\",\n    \"ContentLength\": 5,\n    \"ChecksumCRC32\": \"NhCmhg\u003d\u003d\",\n    \"ChecksumType\": \"FULL_OBJECT\",\n    \"ETag\": \"\\\"5d41402abc4b2a76b9719d911017c592\\\"\",\n    \"ContentType\": \"binary/octet-stream\",\n    \"ContentRange\": \"bytes 0-4/5\",\n    \"ServerSideEncryption\": \"AES256\",\n    \"Metadata\": {}\n}\n```\n\nBut to handle this we would have to add a check (like a regex) in `S3Response` to parse the `ContentRange` field which may be not needed to such a small piece","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":187,"context_line":"        if not is_copy_request and req.has_checksum_to_validate():"},{"line_number":188,"context_line":"            req.persist_checksum_sysmeta_after_validation()"},{"line_number":189,"context_line":"        resp \u003d req.get_response(self.app)"},{"line_number":190,"context_line":"        if not is_copy_request and req.has_checksum_to_validate():"},{"line_number":191,"context_line":"            # Swift does not echo newly persisted sysmeta headers on PUT, so"},{"line_number":192,"context_line":"            # inject the checksum response headers after validation succeeds."},{"line_number":193,"context_line":"            # GET/HEAD responses use the stored sysmeta echoed from Swift."}],"source_content_type":"text/x-python","patch_set":11,"id":"69344dc6_1cd8593b","line":190,"updated":"2026-06-17 00:00:40.000000000","message":"the double `if not is_copy and req.has_checksum` around the `get_response` looks dumb","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":187,"context_line":"        if not is_copy_request and req.has_checksum_to_validate():"},{"line_number":188,"context_line":"            req.persist_checksum_sysmeta_after_validation()"},{"line_number":189,"context_line":"        resp \u003d req.get_response(self.app)"},{"line_number":190,"context_line":"        if not is_copy_request and req.has_checksum_to_validate():"},{"line_number":191,"context_line":"            # Swift does not echo newly persisted sysmeta headers on PUT, so"},{"line_number":192,"context_line":"            # inject the checksum response headers after validation succeeds."},{"line_number":193,"context_line":"            # GET/HEAD responses use the stored sysmeta echoed from Swift."}],"source_content_type":"text/x-python","patch_set":11,"id":"0b80ff04_1a1bffb9","line":190,"in_reply_to":"69344dc6_1cd8593b","updated":"2026-06-22 23:53:33.000000000","message":"Acknowledged","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":true,"context_lines":[{"line_number":160,"context_line":"        return self.GETorHEAD(req)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    @public"},{"line_number":163,"context_line":"    def PUT(self, req):"},{"line_number":164,"context_line":"        \"\"\""},{"line_number":165,"context_line":"        Handle PUT Object and PUT Object (Copy) request"},{"line_number":166,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":44,"id":"edb683f2_c26a0f86","line":163,"updated":"2026-07-22 01:29:15.000000000","message":"during offline discussions, @nmartes@NVIDIA.com has identified one gap in his ObjectCopy implementation: CopyObject silently ignores ``x-amz-checksum-algorithm``:\n\nChecksum-value parsing deliberately excludes that header at s3request.py:1501, but the CopyObject controller never handles it. With a CRC32 source and ``X-Amz-Checksum-Algorithm: SHA256``, it would be a 200 response: stored the source CRC32 metadata, returned ChecksumCRC32 checksum, instead of recomputed SHA256.\n\nand he found AWS specifies that CopyObject preserves the source algorithm by default but allows the caller to select a different one. AWS CopyObject documentation (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html)\n\nI think it\u0027s okay to not implement re-computation using the requested algorithm, but we should reject the header if it\u0027s not supported. Silently succeeding with a contradictory checksum is unsafe for clients relying on integrity metadata. please also add corresponding test cases.","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"dcdffadc6ca94a0293e01d1a238d2025cb8c8078","unresolved":true,"context_lines":[{"line_number":160,"context_line":"        return self.GETorHEAD(req)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":"    @public"},{"line_number":163,"context_line":"    def PUT(self, req):"},{"line_number":164,"context_line":"        \"\"\""},{"line_number":165,"context_line":"        Handle PUT Object and PUT Object (Copy) request"},{"line_number":166,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":44,"id":"634fcaa7_38dd240a","line":163,"in_reply_to":"edb683f2_c26a0f86","updated":"2026-07-22 15:41:10.000000000","message":"I think we also should reject the header, silent success is not a good thing","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":true,"context_lines":[{"line_number":171,"context_line":"            raise InvalidArgument(\u0027x-amz-copy-source-range\u0027,"},{"line_number":172,"context_line":"                                  req.headers[\u0027X-Amz-Copy-Source-Range\u0027],"},{"line_number":173,"context_line":"                                  \u0027Illegal copy header\u0027)"},{"line_number":174,"context_line":"        source_resp \u003d req.check_copy_source(self.app)"},{"line_number":175,"context_line":"        if not req.headers.get(\u0027Content-Type\u0027):"},{"line_number":176,"context_line":"            # can\u0027t setdefault because it can be None for some reason"},{"line_number":177,"context_line":"            req.headers[\u0027Content-Type\u0027] \u003d \u0027binary/octet-stream\u0027"}],"source_content_type":"text/x-python","patch_set":44,"id":"5a931c41_61ad5202","line":174,"updated":"2026-07-22 01:29:15.000000000","message":"``check_copy_source(self.app)`` issues a HEAD on the source object and returns the S3Response as source_resp. this return value is now captured and passed downstream","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":true,"context_lines":[{"line_number":175,"context_line":"        if not req.headers.get(\u0027Content-Type\u0027):"},{"line_number":176,"context_line":"            # can\u0027t setdefault because it can be None for some reason"},{"line_number":177,"context_line":"            req.headers[\u0027Content-Type\u0027] \u003d \u0027binary/octet-stream\u0027"},{"line_number":178,"context_line":"        resp \u003d req.get_response(self.app)"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":181,"context_line":"            resp.append_copy_resp_body(\u0027CopyObjectResult\u0027, source_resp)"}],"source_content_type":"text/x-python","patch_set":44,"id":"4e2e6e23_95122e28","line":178,"updated":"2026-07-22 01:29:15.000000000","message":"Swift\u0027s native copy semantics copy the source\u0027s object sysmeta (including the s3api checksum-header/checksum-value/checksum-type sysmeta) onto the destination, so persistence on the destination is inherited, not recomputed.","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"395f0a8a568a5c66fa59f18010db4a119a5790b8","unresolved":false,"context_lines":[{"line_number":95,"context_line":"SIGV4_CHUNK_MIN_SIZE \u003d 8192"},{"line_number":96,"context_line":"SERVICE \u003d \u0027s3\u0027  # useful for mocking out in tests"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"def _unsupported_checksum_hasher():"},{"line_number":99,"context_line":"    raise NotImplementedError"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"CHECKSUMS_BY_HEADER \u003d {"}],"source_content_type":"text/x-python","patch_set":8,"id":"b6c25b43_02895c1a","line":98,"updated":"2026-06-06 01:13:09.000000000","message":"pep8: E302 expected 2 blank lines, found 1","commit_id":"8fd44112727ae3feb953f47db6258bfdb3bdea93"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"395f0a8a568a5c66fa59f18010db4a119a5790b8","unresolved":false,"context_lines":[{"line_number":98,"context_line":"def _unsupported_checksum_hasher():"},{"line_number":99,"context_line":"    raise NotImplementedError"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"CHECKSUMS_BY_HEADER \u003d {"},{"line_number":102,"context_line":"    \u0027x-amz-checksum-crc32\u0027: checksum.crc32,"},{"line_number":103,"context_line":"    \u0027x-amz-checksum-crc32c\u0027: checksum.crc32c,"},{"line_number":104,"context_line":"    \u0027x-amz-checksum-crc64nvme\u0027: checksum.crc64nvme,"}],"source_content_type":"text/x-python","patch_set":8,"id":"bfb86ac0_83c85aff","line":101,"updated":"2026-06-06 01:13:09.000000000","message":"pep8: E305 expected 2 blank lines after class or function definition, found 1","commit_id":"8fd44112727ae3feb953f47db6258bfdb3bdea93"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"4bbdbae3676bc264ae5f4fbf4ad6b3137ccac062","unresolved":true,"context_lines":[{"line_number":1634,"context_line":"        if not self._validated_checksum:"},{"line_number":1635,"context_line":"            return {}"},{"line_number":1636,"context_line":"        return {"},{"line_number":1637,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-algorithm\u0027):"},{"line_number":1638,"context_line":"                self._validated_checksum[\u0027algorithm\u0027],"},{"line_number":1639,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027):"},{"line_number":1640,"context_line":"                self._validated_checksum[\u0027header\u0027],"}],"source_content_type":"text/x-python","patch_set":9,"id":"334a44c1_0502dacd","line":1637,"range":{"start_line":1637,"start_character":0,"end_line":1637,"end_character":2},"updated":"2026-06-09 13:53:56.000000000","message":"Looks like checksum-algorithm is not used all (besides tests)?","commit_id":"1b912f91b63174a730697c8c0591ba2e8581a2c0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"0d571b4df2708f1562275eb3b627118848e50cc9","unresolved":false,"context_lines":[{"line_number":1634,"context_line":"        if not self._validated_checksum:"},{"line_number":1635,"context_line":"            return {}"},{"line_number":1636,"context_line":"        return {"},{"line_number":1637,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-algorithm\u0027):"},{"line_number":1638,"context_line":"                self._validated_checksum[\u0027algorithm\u0027],"},{"line_number":1639,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027):"},{"line_number":1640,"context_line":"                self._validated_checksum[\u0027header\u0027],"}],"source_content_type":"text/x-python","patch_set":9,"id":"a83bb27d_dda91008","line":1637,"range":{"start_line":1637,"start_character":0,"end_line":1637,"end_character":2},"in_reply_to":"285b80e2_cc0774ab","updated":"2026-06-09 21:31:57.000000000","message":"Marked as resolved.","commit_id":"1b912f91b63174a730697c8c0591ba2e8581a2c0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"5acdcd2383da4b3101cf924578bc2ebc5bbd0a16","unresolved":true,"context_lines":[{"line_number":1634,"context_line":"        if not self._validated_checksum:"},{"line_number":1635,"context_line":"            return {}"},{"line_number":1636,"context_line":"        return {"},{"line_number":1637,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-algorithm\u0027):"},{"line_number":1638,"context_line":"                self._validated_checksum[\u0027algorithm\u0027],"},{"line_number":1639,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027):"},{"line_number":1640,"context_line":"                self._validated_checksum[\u0027header\u0027],"}],"source_content_type":"text/x-python","patch_set":9,"id":"285b80e2_cc0774ab","line":1637,"range":{"start_line":1637,"start_character":0,"end_line":1637,"end_character":2},"in_reply_to":"334a44c1_0502dacd","updated":"2026-06-09 18:05:19.000000000","message":"Yes this is true, we COULD infer the algorithm from the checksum-header, but checksum-algorithm is some algorithm that Swift provides so if for whatever reason we need to recompute/revalidate the checksum of this object, we can pull this header and just compare it too known checksum functions and use the `.name` field that belongs to them.\n\nBut since this really ins\u0027t needed, we can probably just discard this.","commit_id":"1b912f91b63174a730697c8c0591ba2e8581a2c0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1149,"context_line":"                verify_checksum \u003d False"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"            if checksum_key and verify_checksum:"},{"line_number":1152,"context_line":"                self._checksum_to_validate \u003d True"},{"line_number":1153,"context_line":"                self._install_checksumming_input_wrapper("},{"line_number":1154,"context_line":"                    checksum_hasher, checksum_key, checksum_source)"},{"line_number":1155,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"15633d3f_bc6a3131","line":1152,"updated":"2026-06-17 00:00:40.000000000","message":"I don\u0027t LOVE this state tracking cache - I feel like there could be a subtle bug where header\u0027s on a request object get mutated and this gets out of sync\n\nI wonder if we could keep the state on the ChecksumingInputWrapper - because any call to `wsgi.input.read()` forever taints the state of the request object by consuming the bytes from the network there\u0027s \"no going back\" once you read from .input - so up until then you could in-theory still install some checksum headers into the request object\u0027s header dict - but once you read .input either you\u0027re going to capture/calculate every chunk from read or not\n\nSo in the end asking `wsgi.input.what_was_the_matching_checksum_if_any()` un-conditionally in the updater_footers callback would be the least ambigous.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":1149,"context_line":"                verify_checksum \u003d False"},{"line_number":1150,"context_line":""},{"line_number":1151,"context_line":"            if checksum_key and verify_checksum:"},{"line_number":1152,"context_line":"                self._checksum_to_validate \u003d True"},{"line_number":1153,"context_line":"                self._install_checksumming_input_wrapper("},{"line_number":1154,"context_line":"                    checksum_hasher, checksum_key, checksum_source)"},{"line_number":1155,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fcca363d_45526904","line":1152,"in_reply_to":"15633d3f_bc6a3131","updated":"2026-06-22 23:53:33.000000000","message":"I agree with this and it makes the code cleaner to keep them together.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1628,"context_line":"            \u0027algorithm\u0027: checksum_hash_func.name,"},{"line_number":1629,"context_line":"            \u0027header\u0027: header,"},{"line_number":1630,"context_line":"            \u0027value\u0027: value,"},{"line_number":1631,"context_line":"        }"},{"line_number":1632,"context_line":""},{"line_number":1633,"context_line":"    def _checksum_sysmeta_headers(self, checksum_type):"},{"line_number":1634,"context_line":"        if not self._validated_checksum:"}],"source_content_type":"text/x-python","patch_set":11,"id":"228088a5_3077d0a3","line":1631,"updated":"2026-06-17 00:00:40.000000000","message":"so we pass the input wrapper a callback so that it can update a backref on the request object... I don\u0027t *love* this design, but it might just be the \"least worse\" option given the current abstraction boundaries and code flow.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":1628,"context_line":"            \u0027algorithm\u0027: checksum_hash_func.name,"},{"line_number":1629,"context_line":"            \u0027header\u0027: header,"},{"line_number":1630,"context_line":"            \u0027value\u0027: value,"},{"line_number":1631,"context_line":"        }"},{"line_number":1632,"context_line":""},{"line_number":1633,"context_line":"    def _checksum_sysmeta_headers(self, checksum_type):"},{"line_number":1634,"context_line":"        if not self._validated_checksum:"}],"source_content_type":"text/x-python","patch_set":11,"id":"3566162a_cb3e6f27","line":1631,"in_reply_to":"228088a5_3077d0a3","updated":"2026-06-22 23:53:33.000000000","message":"Instead, if we keep the checksum state tied to `wsgi.input` (like the comment on L1152 says), then we can get rid of the callback function","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1643,"context_line":"        }"},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"    def has_checksum_to_validate(self):"},{"line_number":1646,"context_line":"        return self._checksum_to_validate"},{"line_number":1647,"context_line":""},{"line_number":1648,"context_line":"    def checksum_mode_enabled(self):"},{"line_number":1649,"context_line":"        checksum_mode \u003d self.headers.get(\u0027x-amz-checksum-mode\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"55c4c58b_e6357d25","line":1646,"updated":"2026-06-17 00:00:40.000000000","message":"this seems like some pretty thin redirection - it\u0027s not helpful to grow two new abstractions/concepts that do the same thing.\n\nIf you want `req.checksum_to_validate` to be private/read-only the correct python-ism is `@property` for the public attribute that has the same name:\n\n```\n@property\ndef checksum_to_validate(self):\n    return self._checksum_to_validate\n```\n\nbut honestly I\u0027m not sure that the whole property shouldn\u0027t \"just\" be a read-only view over ~`_validate_checksum_headers`\n\nIt would be best if we could try and localize the access/validation of checksum metadata on write requests somewhere rather than having disparate methods relying on state captured during `__init__` staying consistent with the request objects header values across possible mutation as the object is pass around the various controllers.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":1643,"context_line":"        }"},{"line_number":1644,"context_line":""},{"line_number":1645,"context_line":"    def has_checksum_to_validate(self):"},{"line_number":1646,"context_line":"        return self._checksum_to_validate"},{"line_number":1647,"context_line":""},{"line_number":1648,"context_line":"    def checksum_mode_enabled(self):"},{"line_number":1649,"context_line":"        checksum_mode \u003d self.headers.get(\u0027x-amz-checksum-mode\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"0225c0c7_4e9a1026","line":1646,"in_reply_to":"55c4c58b_e6357d25","updated":"2026-06-22 23:53:33.000000000","message":"Acknowledged","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1650,"context_line":"        if checksum_mode is None:"},{"line_number":1651,"context_line":"            return False"},{"line_number":1652,"context_line":"        if checksum_mode !\u003d \u0027ENABLED\u0027:"},{"line_number":1653,"context_line":"            raise InvalidArgument(\u0027x-amz-checksum-mode\u0027, checksum_mode)"},{"line_number":1654,"context_line":"        return True"},{"line_number":1655,"context_line":""},{"line_number":1656,"context_line":"    def get_checksum_headers("}],"source_content_type":"text/x-python","patch_set":11,"id":"eebaebae_4cd9e885","line":1653,"updated":"2026-06-17 00:00:40.000000000","message":"this seems like a pretty decent \"read-only-view over specific contextual headers\" - once we\u0027ve established this sort of abstraction on the review object the \"smell\" becomes anyone ever looking at or setting `x-amx-checksum-mode` in headers directly.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":1650,"context_line":"        if checksum_mode is None:"},{"line_number":1651,"context_line":"            return False"},{"line_number":1652,"context_line":"        if checksum_mode !\u003d \u0027ENABLED\u0027:"},{"line_number":1653,"context_line":"            raise InvalidArgument(\u0027x-amz-checksum-mode\u0027, checksum_mode)"},{"line_number":1654,"context_line":"        return True"},{"line_number":1655,"context_line":""},{"line_number":1656,"context_line":"    def get_checksum_headers("}],"source_content_type":"text/x-python","patch_set":11,"id":"bbab7459_c6daf4e8","line":1653,"in_reply_to":"eebaebae_4cd9e885","updated":"2026-06-22 23:53:33.000000000","message":"Acknowledged","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1654,"context_line":"        return True"},{"line_number":1655,"context_line":""},{"line_number":1656,"context_line":"    def get_checksum_headers("},{"line_number":1657,"context_line":"            self, checksum_type\u003dCHECKSUM_TYPE_FULL_OBJECT):"},{"line_number":1658,"context_line":"        \"\"\""},{"line_number":1659,"context_line":"        Get the checksum headers tied to the current request."},{"line_number":1660,"context_line":"        :param checksum_type: The type of checksum to add to the response."}],"source_content_type":"text/x-python","patch_set":11,"id":"89933b6f_dce61392","line":1657,"updated":"2026-06-17 00:00:40.000000000","message":"anytime I see a kwarg my natural response is to question:\n\n1) does ANYONE call this method w/ or w/o this parm\n2) do real callers in code that matters (not tests) *actually* sometimes call this method w/ AND w/o specifying this value\n3) should they?\n\n^ so you might notice a new method starting life with a \"optional\" kwarg generates a LOT of review work; better to create methods with the inputs they require and use them as prescribed.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":1654,"context_line":"        return True"},{"line_number":1655,"context_line":""},{"line_number":1656,"context_line":"    def get_checksum_headers("},{"line_number":1657,"context_line":"            self, checksum_type\u003dCHECKSUM_TYPE_FULL_OBJECT):"},{"line_number":1658,"context_line":"        \"\"\""},{"line_number":1659,"context_line":"        Get the checksum headers tied to the current request."},{"line_number":1660,"context_line":"        :param checksum_type: The type of checksum to add to the response."}],"source_content_type":"text/x-python","patch_set":11,"id":"74d15a38_626f4022","line":1657,"in_reply_to":"89933b6f_dce61392","updated":"2026-06-22 23:53:33.000000000","message":"After looking at this again, it does seem that there are only every 3 cases for the type\n- FULL_OBJECT\n- COMPOSITE\n- Something else (which would only be passed in make fake callers)\n\nWe can move this function to not have an optional param.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1672,"context_line":"            self, checksum_type\u003dCHECKSUM_TYPE_FULL_OBJECT):"},{"line_number":1673,"context_line":"        \"\"\""},{"line_number":1674,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1675,"context_line":"        If validation fails, no checksum sysmeta will exist."},{"line_number":1676,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1677,"context_line":"        \"\"\""},{"line_number":1678,"context_line":"        if not self._checksum_to_validate:"}],"source_content_type":"text/x-python","patch_set":11,"id":"c7bca516_07804eb2","line":1675,"updated":"2026-06-17 00:00:40.000000000","message":"\"if validation fails\" - we probably should have returned an error and this method will never be called, right?\n\nThis reads like \"if validation fails we ignore the checksum headers\"","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":1672,"context_line":"            self, checksum_type\u003dCHECKSUM_TYPE_FULL_OBJECT):"},{"line_number":1673,"context_line":"        \"\"\""},{"line_number":1674,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1675,"context_line":"        If validation fails, no checksum sysmeta will exist."},{"line_number":1676,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1677,"context_line":"        \"\"\""},{"line_number":1678,"context_line":"        if not self._checksum_to_validate:"}],"source_content_type":"text/x-python","patch_set":11,"id":"6e8c3d7a_377a87f6","line":1675,"in_reply_to":"696efd46_af145b79","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"131d8f7d48d3706c83b284c01816578a6c7582b8","unresolved":true,"context_lines":[{"line_number":1672,"context_line":"            self, checksum_type\u003dCHECKSUM_TYPE_FULL_OBJECT):"},{"line_number":1673,"context_line":"        \"\"\""},{"line_number":1674,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1675,"context_line":"        If validation fails, no checksum sysmeta will exist."},{"line_number":1676,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1677,"context_line":"        \"\"\""},{"line_number":1678,"context_line":"        if not self._checksum_to_validate:"}],"source_content_type":"text/x-python","patch_set":11,"id":"5d508367_b1d7aba5","line":1675,"in_reply_to":"6e8c3d7a_377a87f6","updated":"2026-07-01 21:29:39.000000000","message":"Marked as unresolved.","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":true,"context_lines":[{"line_number":1672,"context_line":"            self, checksum_type\u003dCHECKSUM_TYPE_FULL_OBJECT):"},{"line_number":1673,"context_line":"        \"\"\""},{"line_number":1674,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1675,"context_line":"        If validation fails, no checksum sysmeta will exist."},{"line_number":1676,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1677,"context_line":"        \"\"\""},{"line_number":1678,"context_line":"        if not self._checksum_to_validate:"}],"source_content_type":"text/x-python","patch_set":11,"id":"696efd46_af145b79","line":1675,"in_reply_to":"c7bca516_07804eb2","updated":"2026-06-22 23:53:33.000000000","message":"You are right, if validation fails we do ignore the checksum headers. If validation fails, an error is already thrown by ChecksummingInput:\n```python\n        if error:\n            self.close()\n            # Since we don\u0027t return the last chunk, the PUT never completes\n            raise S3InputChecksumMismatch(self._checksum_hasher.name.upper())\n```\n\nSo if we throw an error in `persist_checksum_sysmeta_after_validation`, it would be strange I think","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1675,"context_line":"        If validation fails, no checksum sysmeta will exist."},{"line_number":1676,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1677,"context_line":"        \"\"\""},{"line_number":1678,"context_line":"        if not self._checksum_to_validate:"},{"line_number":1679,"context_line":"            return"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        original_callback \u003d self.environ.get(\u0027swift.callback.update_footers\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"a8cddddf_beac21cd","line":1678,"updated":"2026-06-17 00:00:40.000000000","message":"so this is saying that if a user doesn\u0027t specify the checksum to validate no footer update gets installed - I think this would have to change if we ever start doing NVME64-by-default-unless-otherwise-specified the way that s3api does.\n\n^ and that\u0027s ok, most of the time it\u0027s better to code to the current contract","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"405a8558d9c1ef4d0c8b2790830714740780840d","unresolved":false,"context_lines":[{"line_number":1675,"context_line":"        If validation fails, no checksum sysmeta will exist."},{"line_number":1676,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1677,"context_line":"        \"\"\""},{"line_number":1678,"context_line":"        if not self._checksum_to_validate:"},{"line_number":1679,"context_line":"            return"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        original_callback \u003d self.environ.get(\u0027swift.callback.update_footers\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"e39d675d_811208d8","line":1678,"in_reply_to":"a8cddddf_beac21cd","updated":"2026-06-22 23:53:33.000000000","message":"I think what would be done in that moment would be on checksum header validation, we swap empty `x-amz-checksum-*` headers with `x-amz-checksum-crc64nvme` and logic would play out normally","commit_id":"80c64b1e4c6cf0ce59cb27d0459e77718a1a730f"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"5651e7237d467f58af2443e5cd31812613edcf7f","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    S3InputMalformedTrailer, S3InputMissingSecret, \\"},{"line_number":67,"context_line":"    S3InputSHA256Mismatch, S3InputChecksumMismatch, \\"},{"line_number":68,"context_line":"    S3InputChecksumTrailerInvalid"},{"line_number":69,"context_line":"from swift.common.middleware.s3api.utils import utf8encode, \\"},{"line_number":70,"context_line":"    S3Timestamp, mktime, MULTIUPLOAD_SUFFIX, CHECKSUM_TYPE_FULL_OBJECT"},{"line_number":71,"context_line":"from swift.common.middleware.s3api.subresource import decode_acl, encode_acl"},{"line_number":72,"context_line":"from swift.common.middleware.s3api.utils import sysmeta_header, \\"}],"source_content_type":"text/x-python","patch_set":13,"id":"7d405ed5_b8c0e37c","line":69,"updated":"2026-06-23 01:01:52.000000000","message":"pep8: F401 \u0027swift.common.middleware.s3api.utils.CHECKSUM_TYPE_FULL_OBJECT\u0027 imported but unused","commit_id":"76ae43392dcc96ed1bcfdd57c7a7bfc58fb48cfe"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":1618,"context_line":""},{"line_number":1619,"context_line":"    def _checksum_sysmeta_headers(self, checksum, checksum_type):"},{"line_number":1620,"context_line":"        if not checksum:"},{"line_number":1621,"context_line":"            return {}"},{"line_number":1622,"context_line":"        return {"},{"line_number":1623,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027):"},{"line_number":1624,"context_line":"                checksum[\u0027header\u0027],"}],"source_content_type":"text/x-python","patch_set":25,"id":"a4d2a2f8_d3639dae","line":1621,"updated":"2026-06-30 23:51:02.000000000","message":"I\u0027ve been trying to get my agents to find and call out this sort of stuff:\n\n```\n## 2. `_checksum_sysmeta_headers()` has an unreachable falsey-checksum branch\n\nFile/line: `swift/common/middleware/s3api/s3request.py:1619`\n\nConcrete failure path:\n\n`_checksum_sysmeta_headers()` starts with `if not checksum: return {}`. The\nonly production caller is the nested `update_footers()` callback in\n`persist_checksum_sysmeta_after_validation()`, and that caller already checks\n`if checksum:` before calling the helper. The worker found no real caller that\npasses `None`, `{}`, or another falsey value into this helper.\n\nWhy it matters:\n\nThis is duplicated defensive behavior in the persistence path for the new\nstored object metadata. The worker classified it as a blocking defensive\ncontract issue because the branch tolerates a state the implementation does\nnot produce and no focused test proves.\n\nAcceptance condition:\n\nRemove the falsey branch and keep the reachability decision in the caller. If\nfalsey checksums are intended input, add a real caller/state and focused test\nfor that exact state.\n```\n\nwhat do yo think!?","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":true,"context_lines":[{"line_number":1618,"context_line":""},{"line_number":1619,"context_line":"    def _checksum_sysmeta_headers(self, checksum, checksum_type):"},{"line_number":1620,"context_line":"        if not checksum:"},{"line_number":1621,"context_line":"            return {}"},{"line_number":1622,"context_line":"        return {"},{"line_number":1623,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027):"},{"line_number":1624,"context_line":"                checksum[\u0027header\u0027],"}],"source_content_type":"text/x-python","patch_set":25,"id":"e35b3f21_94e97859","line":1621,"in_reply_to":"a4d2a2f8_d3639dae","updated":"2026-07-01 17:11:33.000000000","message":"I agree with this since we don\u0027t have a production caller doing the checksum for us already","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":1618,"context_line":""},{"line_number":1619,"context_line":"    def _checksum_sysmeta_headers(self, checksum, checksum_type):"},{"line_number":1620,"context_line":"        if not checksum:"},{"line_number":1621,"context_line":"            return {}"},{"line_number":1622,"context_line":"        return {"},{"line_number":1623,"context_line":"            sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027):"},{"line_number":1624,"context_line":"                checksum[\u0027header\u0027],"}],"source_content_type":"text/x-python","patch_set":25,"id":"3aaff24b_5cc0032c","line":1621,"in_reply_to":"e35b3f21_94e97859","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":1651,"context_line":"    def persist_checksum_sysmeta_after_validation(self, checksum_type):"},{"line_number":1652,"context_line":"        \"\"\""},{"line_number":1653,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1654,"context_line":"        If validation fails, we will ignore checksum headers and"},{"line_number":1655,"context_line":"        no checksum sysmeta will exist."},{"line_number":1656,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1657,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":25,"id":"5dac1986_da2bdabd","line":1654,"updated":"2026-06-30 23:51:02.000000000","message":"so it\u0027s not \"we will ignore\" it\u0027s \"this method relies on another part of the system to ensure correctness\" - that\u0027s not \"ignore\" that\u0027s \"spooky action at distance\" but called out in a docstring as a scary sounding failure mode.\n\n```\nYes, that docstring is misleading if read literally.\n\nThe code does not ignore a failed checksum and write the object without\nchecksum sysmeta. On mismatch,\ninstances/vsaio-2/swift/swift/common/middleware/s3api/s3request.py:289 closes\nthe input and raises S3InputChecksumMismatch;\ninstances/vsaio-2/swift/swift/common/middleware/s3api/s3request.py:2235 maps\nthat to BadDigest. The controller never gets a successful response from\nreq.get_response().\n\nThe test confirms the intended behavior:\ninstances/vsaio-2/swift/test/unit/common/middleware/s3api/test_obj.py:1305\nexpects 400 BadDigest, no checksum response headers, and\ninstances/vsaio-2/swift/test/unit/common/middleware/s3api/ test_obj.py:1310\nasserts the object was not uploaded.\n\nBetter wording would be:\n\nIf checksum validation fails, the PUT fails before a matching checksum is\nrecorded, so no checksum sysmeta is persisted.\n\nSo: behavior looks correct; the docstring wording is sloppy enough to comment\non.\n```","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":true,"context_lines":[{"line_number":1651,"context_line":"    def persist_checksum_sysmeta_after_validation(self, checksum_type):"},{"line_number":1652,"context_line":"        \"\"\""},{"line_number":1653,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1654,"context_line":"        If validation fails, we will ignore checksum headers and"},{"line_number":1655,"context_line":"        no checksum sysmeta will exist."},{"line_number":1656,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1657,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":25,"id":"cb52c2bf_0a713595","line":1654,"in_reply_to":"5dac1986_da2bdabd","updated":"2026-07-01 17:11:33.000000000","message":"I think this comment is much better.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":1651,"context_line":"    def persist_checksum_sysmeta_after_validation(self, checksum_type):"},{"line_number":1652,"context_line":"        \"\"\""},{"line_number":1653,"context_line":"        Install a callback to persist checksum sysmeta after validation."},{"line_number":1654,"context_line":"        If validation fails, we will ignore checksum headers and"},{"line_number":1655,"context_line":"        no checksum sysmeta will exist."},{"line_number":1656,"context_line":"        :param checksum_type: The type of checksum to persist."},{"line_number":1657,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":25,"id":"bcb2b6b2_5b82d198","line":1654,"in_reply_to":"cb52c2bf_0a713595","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":1665,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1666,"context_line":"                    checksum, checksum_type))"},{"line_number":1667,"context_line":""},{"line_number":1668,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1669,"context_line":""},{"line_number":1670,"context_line":"    def _validate_headers(self):"},{"line_number":1671,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":25,"id":"20fa3637_1faf8666","line":1668,"updated":"2026-06-30 23:51:02.000000000","message":"I\u0027m really worried I may have steered you wrong in a previous review, the existence of this environ key is the trigger to force the object controller in MIME PUT mode - which has some implications for replicated PUTs with precomputed checksum header values:\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/proxy/controllers/obj.py#L1089\n\n```\n## 1. Checksum-free S3 PUTs now require metadata-footer backend support\n\nFile/line:\n\n- `swift/common/middleware/s3api/controllers/obj.py:176-178`\n- `swift/common/middleware/s3api/s3request.py:1658-1668`\n- `swift/proxy/controllers/obj.py:1088-1097`\n- `swift/proxy/controllers/obj.py:2103-2121`\n\nConcrete failure path:\n\nAn ordinary non-copy S3 object PUT with no `x-amz-checksum-*` header and no\nchecksum trailer reaches `ObjectController.PUT`. The patch calls\n`req.persist_checksum_sysmeta_after_validation(CHECKSUM_TYPE_FULL_OBJECT)` for\nevery non-copy PUT, even when `_validate_checksum_headers()` found no checksum\ninput. That helper unconditionally sets\n`environ[\u0027swift.callback.update_footers\u0027]`.\n\nThe Swift subrequest copies that environ into the proxy request. In the\nreplicated proxy path, `_make_putter()` selects `MIMEPutter` solely because\n`swift.callback.update_footers` exists. `MIMEPutter.connect()` then sends\n`X-Backend-Obj-Metadata-Footer: yes` and raises `FooterNotSupported()` when the\nobject server 100-continue response does not include\n`X-Obj-Metadata-Footer: yes`. If too few putters connect, `_check_min_conn()`\nreturns `HTTPServiceUnavailable`. So a checksum-free S3 PUT can fail as 503\nbefore sending the object body, despite no client use of the new checksum\nfeature.\n\nWhy it matters:\n\nThis broadens the backend compatibility contract for ordinary S3 PUTs. Existing\nproxy tests at `test/unit/proxy/controllers/test_obj.py:1630-1704` define\nno-footer PUTs as regular `Putter` requests with no\n`X-Backend-Obj-Metadata-Footer`, no MIME boundary, and no multiphase header.\nThe new s3api no-checksum test verifies no checksum sysmeta or response\nheaders, but it does not assert that the Swift subrequest avoids the footer\ncallback or the proxy metadata-footer path.\n\nAcceptance condition:\n\nDo not install `swift.callback.update_footers` for non-copy S3 PUTs unless the\nrequest actually has a checksum header or checksum trailer that can be\nvalidated and persisted. Add focused evidence that no-checksum S3 PUTs keep the\nregular proxy PUT path, while checksum header/trailer PUTs still use footers\nand persist checksum sysmeta only after successful validation.\n```\n\n^ FWIW this analysis is over-emphasizing old swifts that might not have been upgraded to support the x-backend-obj-metadata-footer: yes continue header - the real issue is the request structure wrapping performance implication; which maybe isn\u0027t THAT big of deal - but it\u0027s un-necessary overhead that may be easy enough to avoid by only installing the callback when we need it","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":true,"context_lines":[{"line_number":1665,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1666,"context_line":"                    checksum, checksum_type))"},{"line_number":1667,"context_line":""},{"line_number":1668,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1669,"context_line":""},{"line_number":1670,"context_line":"    def _validate_headers(self):"},{"line_number":1671,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":25,"id":"64ae7cda_708cc640","line":1668,"in_reply_to":"20fa3637_1faf8666","updated":"2026-07-01 17:11:33.000000000","message":"I agree that would not needed overhead. A small fix we could have would be to update the call in the s3api object controller #176\n```\nif not is_copy_request and req.has_checksum_to_validate():\n    req.persist_checksum_sysmeta_after_validation(CHECKSUM_TYPE_FULL_OBJECT)\n```\n\nAnd have some function maybe something like:\n```\ndef has_checksum_to_validate(self):\n    return hasattr(self.environ[\u0027wsgi.input\u0027], \u0027get_matching_checksum\u0027)\n```\n\nThough this would mean if the caller does not use `req.has_checksum_to_validate()` before calling `req.persist_checksum_sysmeta_after_validation`, then we could be in for some trouble. I think to avoid this possibility, we make `persist_checksum_sysmeta_after_validation` a private function so that we don\u0027t have the chance for a caller to put a footer call without proper checking.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":1665,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1666,"context_line":"                    checksum, checksum_type))"},{"line_number":1667,"context_line":""},{"line_number":1668,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1669,"context_line":""},{"line_number":1670,"context_line":"    def _validate_headers(self):"},{"line_number":1671,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":25,"id":"09a9a580_e5f345c9","line":1668,"in_reply_to":"64ae7cda_708cc640","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dc717074059fd84f9cbc4ab9e9f3082744ed1dc2","unresolved":true,"context_lines":[{"line_number":1678,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1679,"context_line":"                    checksum, checksum_type))"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def _validate_headers(self):"},{"line_number":1684,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":28,"id":"2dbe95ba_708cc89a","line":1681,"updated":"2026-07-02 15:09:37.000000000","message":"I don\u0027t think this callback gets copied to subrequests https://github.com/openstack/swift/blob/ae4186bdb64c83455278010c6f965353ea126ff6/swift/common/wsgi.py#L1326 which is significant if versioning is enabled because the actual data is PUT to a versions container using a subrequest https://github.com/openstack/swift/blob/master/swift/common/middleware/versioned_writes/object_versioning.py#L317, so I think the checksum sysmeta would not get appended to footers in that case.\n\nTim\u0027s original patch had some workaround for this is in versioning https://review.opendev.org/c/openstack/swift/+/909801/47/swift/common/middleware/versioned_writes/object_versioning.py \n\nI\u0027d suggest adding a functional and/or s3 compat test for checksum persistence with versioning and seeing what the outcome is.","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"526990f301132aba4070cbe796ae24a64db09f2d","unresolved":true,"context_lines":[{"line_number":1678,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1679,"context_line":"                    checksum, checksum_type))"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def _validate_headers(self):"},{"line_number":1684,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":28,"id":"31b68a83_987edf96","line":1681,"in_reply_to":"2dbe95ba_708cc89a","updated":"2026-07-02 16:19:37.000000000","message":"update: Tim\u0027s patch had some changes in test/s3api/test_versioning.py","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"1041019dbf834d57a83318a0127cec6276b07cc6","unresolved":true,"context_lines":[{"line_number":1678,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1679,"context_line":"                    checksum, checksum_type))"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def _validate_headers(self):"},{"line_number":1684,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":28,"id":"530c7d71_53ca58b3","line":1681,"in_reply_to":"31b68a83_987edf96","updated":"2026-07-06 15:43:25.000000000","message":"I added the changes from the [original patch](https://review.opendev.org/c/openstack/swift/+/909801/47/swift/common/middleware/versioned_writes/object_versioning.py), with tests to match. Though, I\u0027m not really sure what would be a better solution to adding listing metadata for s3 checksums besides overriding a header from the container listing information. And we also don\u0027t have systags either...","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"a40b971fe5d1b4ef1a45005fd0fe6c1e3590169f","unresolved":true,"context_lines":[{"line_number":1678,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1679,"context_line":"                    checksum, checksum_type))"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def _validate_headers(self):"},{"line_number":1684,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":28,"id":"9a123851_7c33cbf1","line":1681,"in_reply_to":"50f23bed_04148f5d","updated":"2026-07-06 19:45:40.000000000","message":"Disregard listing information, will stay out of scope.","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"a85a057a7923a4db91dab91b78b8b3b3a0771d2f","unresolved":true,"context_lines":[{"line_number":1678,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1679,"context_line":"                    checksum, checksum_type))"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def _validate_headers(self):"},{"line_number":1684,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":28,"id":"50f23bed_04148f5d","line":1681,"in_reply_to":"530c7d71_53ca58b3","updated":"2026-07-06 15:55:49.000000000","message":"See https://review.opendev.org/c/openstack/swift/+/991516/32/swift/common/middleware/versioned_writes/object_versioning.py#333","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"d0f906201eaffe9201bdc63f40b5d6498c6cfa0e","unresolved":false,"context_lines":[{"line_number":1678,"context_line":"                footers.update(self._checksum_sysmeta_headers("},{"line_number":1679,"context_line":"                    checksum, checksum_type))"},{"line_number":1680,"context_line":""},{"line_number":1681,"context_line":"        self.environ[\u0027swift.callback.update_footers\u0027] \u003d update_footers"},{"line_number":1682,"context_line":""},{"line_number":1683,"context_line":"    def _validate_headers(self):"},{"line_number":1684,"context_line":"        if \u0027CONTENT_LENGTH\u0027 in self.environ:"}],"source_content_type":"text/x-python","patch_set":28,"id":"a63ef1e1_ae7fae53","line":1681,"in_reply_to":"9a123851_7c33cbf1","updated":"2026-07-07 16:38:18.000000000","message":"Resolved","commit_id":"0fbac0e5da2ff369d647373f88f15c4404244143"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ad06d4c2b5bbcf6912af589e3f94049cc23c8f22","unresolved":true,"context_lines":[{"line_number":1143,"context_line":"                    checksum_hasher, checksum_key, checksum_source)"},{"line_number":1144,"context_line":"                if self.method in (\u0027PUT\u0027, \u0027POST\u0027) and \\"},{"line_number":1145,"context_line":"                        \u0027X-Amz-Copy-Source\u0027 not in self.headers:"},{"line_number":1146,"context_line":"                    self._persist_checksum_metadata_after_validation("},{"line_number":1147,"context_line":"                        self._checksum_type_for_request_sysmeta())"},{"line_number":1148,"context_line":""},{"line_number":1149,"context_line":"        # Lock in string-to-sign now, before we start messing with query params"}],"source_content_type":"text/x-python","patch_set":36,"id":"e020dffa_cab94c8c","line":1146,"updated":"2026-07-16 16:10:33.000000000","message":"same here, MPU UploadPart ``PUT ?partNumber\u003dN\u0026uploadId\u003dX`` with a per-part ``x-amz-checksum-* header`` is a PUT with no copy source, so MPU UploadPart will persist ``checksum-type: FULL_OBJECT`` as sysmeta on the segment object.","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c63ac75b45a4aee449aacd462f259b27b1d1b1c8","unresolved":false,"context_lines":[{"line_number":1143,"context_line":"                    checksum_hasher, checksum_key, checksum_source)"},{"line_number":1144,"context_line":"                if self.method in (\u0027PUT\u0027, \u0027POST\u0027) and \\"},{"line_number":1145,"context_line":"                        \u0027X-Amz-Copy-Source\u0027 not in self.headers:"},{"line_number":1146,"context_line":"                    self._persist_checksum_metadata_after_validation("},{"line_number":1147,"context_line":"                        self._checksum_type_for_request_sysmeta())"},{"line_number":1148,"context_line":""},{"line_number":1149,"context_line":"        # Lock in string-to-sign now, before we start messing with query params"}],"source_content_type":"text/x-python","patch_set":36,"id":"039c22c8_47b74e83","line":1146,"in_reply_to":"e020dffa_cab94c8c","updated":"2026-07-16 18:34:49.000000000","message":"Acknowledged","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ad06d4c2b5bbcf6912af589e3f94049cc23c8f22","unresolved":true,"context_lines":[{"line_number":2332,"context_line":"            # GET/HEAD responses use the stored sysmeta echoed from Swift."},{"line_number":2333,"context_line":"            if method in (\u0027PUT\u0027, \u0027POST\u0027) and \\"},{"line_number":2334,"context_line":"                    \u0027X-Amz-Copy-Source\u0027 not in self.headers:"},{"line_number":2335,"context_line":"                resp.headers.update(self._checksum_response_headers("},{"line_number":2336,"context_line":"                    self._checksum_type_for_request_sysmeta()))"},{"line_number":2337,"context_line":"            return resp"},{"line_number":2338,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"0a370994_2027f5dc","line":2335,"updated":"2026-07-16 16:10:33.000000000","message":"A MPU UploadPart ``PUT ?partNumber\u003dN\u0026uploadId\u003dX`` with a per-part ``x-amz-checksum-*`` header is a PUT with no copy source, so it slips through and MPU UploadPart will end up see ``x-amz-checksum-type: FULL_OBJECT`` in the response.\n\nFor MPU, the type (FULL_OBJECT/COMPOSITE) is a whole-object/MPU-level concept, not a per-part one.","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"c63ac75b45a4aee449aacd462f259b27b1d1b1c8","unresolved":false,"context_lines":[{"line_number":2332,"context_line":"            # GET/HEAD responses use the stored sysmeta echoed from Swift."},{"line_number":2333,"context_line":"            if method in (\u0027PUT\u0027, \u0027POST\u0027) and \\"},{"line_number":2334,"context_line":"                    \u0027X-Amz-Copy-Source\u0027 not in self.headers:"},{"line_number":2335,"context_line":"                resp.headers.update(self._checksum_response_headers("},{"line_number":2336,"context_line":"                    self._checksum_type_for_request_sysmeta()))"},{"line_number":2337,"context_line":"            return resp"},{"line_number":2338,"context_line":""}],"source_content_type":"text/x-python","patch_set":36,"id":"b2a2cadc_90c361aa","line":2335,"in_reply_to":"0a370994_2027f5dc","updated":"2026-07-16 18:34:49.000000000","message":"I agree with this, thanks for catching it! The changes from https://review.opendev.org/c/openstack/swift/+/997623 fix this and I\u0027ll make sure to update expected behavior in child patches.","commit_id":"199dd9f5d03dbdbea27c712d055eedb709ef83d0"}],"swift/common/middleware/s3api/s3response.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":133,"context_line":"        checksum response headers"},{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        if self.request is None:"},{"line_number":136,"context_line":"            return False"},{"line_number":137,"context_line":"        if self.request.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":138,"context_line":"            return True"},{"line_number":139,"context_line":"        if self.request.method in (\u0027GET\u0027, \u0027HEAD\u0027):"}],"source_content_type":"text/x-python","patch_set":25,"id":"358e71db_2e2993df","line":136,"updated":"2026-06-30 23:51:02.000000000","message":"when is this branch true 🤯","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":true,"context_lines":[{"line_number":133,"context_line":"        checksum response headers"},{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        if self.request is None:"},{"line_number":136,"context_line":"            return False"},{"line_number":137,"context_line":"        if self.request.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":138,"context_line":"            return True"},{"line_number":139,"context_line":"        if self.request.method in (\u0027GET\u0027, \u0027HEAD\u0027):"}],"source_content_type":"text/x-python","patch_set":25,"id":"8adedea1_9025db59","line":136,"in_reply_to":"358e71db_2e2993df","updated":"2026-07-01 17:11:33.000000000","message":"Probably never 😅","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":133,"context_line":"        checksum response headers"},{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        if self.request is None:"},{"line_number":136,"context_line":"            return False"},{"line_number":137,"context_line":"        if self.request.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":138,"context_line":"            return True"},{"line_number":139,"context_line":"        if self.request.method in (\u0027GET\u0027, \u0027HEAD\u0027):"}],"source_content_type":"text/x-python","patch_set":25,"id":"8a9dd51d_c3d85b35","line":136,"in_reply_to":"8adedea1_9025db59","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":216,"context_line":"        if (checksum_header and checksum_value and"},{"line_number":217,"context_line":"                self._req_needs_checksum_response_headers()):"},{"line_number":218,"context_line":"            headers[checksum_header] \u003d checksum_value"},{"line_number":219,"context_line":"            if checksum_type:"},{"line_number":220,"context_line":"                headers[\u0027x-amz-checksum-type\u0027] \u003d checksum_type"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"        self.headers \u003d headers"}],"source_content_type":"text/x-python","patch_set":25,"id":"e6d455ad_febb7362","line":219,"updated":"2026-06-30 23:51:02.000000000","message":"yeah I don\u0027t like this branch either - i wonder what your agent would come up with if you plug this acceptance condition in:\n\n```\n## 3. Missing `checksum-type` fallback has no producer state\n\nFile/line: `swift/common/middleware/s3api/s3response.py:219`\n\nConcrete failure path:\n\n`S3Response` emits the stored checksum algorithm/value when\n`checksum-header` and `checksum-value` exist, but only adds\n`x-amz-checksum-type` under `if checksum_type:`. The patch\u0027s writer,\n`S3Request._checksum_sysmeta_headers()`, always writes `checksum-header`,\n`checksum-value`, and `checksum-type` together. The worker found no migration,\ncompatibility, disk, or proxy state that produces only header+value while\nomitting type.\n\nWhy it matters:\n\nThe current branch would silently return an S3 checksum header without\n`x-amz-checksum-type` for an unproven partial metadata shape. That is a new\nwire-format fallback without a named producer or test.\n\nAcceptance condition:\n\nRequire `checksum-type` in the response emission condition, or drop the whole\nchecksum response header set when any member of the persisted sysmeta triplet\nis missing. If the partial state is intentional, name the producer and add a\nfocused test for header+value without type.\n```","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":216,"context_line":"        if (checksum_header and checksum_value and"},{"line_number":217,"context_line":"                self._req_needs_checksum_response_headers()):"},{"line_number":218,"context_line":"            headers[checksum_header] \u003d checksum_value"},{"line_number":219,"context_line":"            if checksum_type:"},{"line_number":220,"context_line":"                headers[\u0027x-amz-checksum-type\u0027] \u003d checksum_type"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"        self.headers \u003d headers"}],"source_content_type":"text/x-python","patch_set":25,"id":"273056d6_2e19119f","line":219,"in_reply_to":"d6916808_8d166605","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":true,"context_lines":[{"line_number":216,"context_line":"        if (checksum_header and checksum_value and"},{"line_number":217,"context_line":"                self._req_needs_checksum_response_headers()):"},{"line_number":218,"context_line":"            headers[checksum_header] \u003d checksum_value"},{"line_number":219,"context_line":"            if checksum_type:"},{"line_number":220,"context_line":"                headers[\u0027x-amz-checksum-type\u0027] \u003d checksum_type"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"        self.headers \u003d headers"}],"source_content_type":"text/x-python","patch_set":25,"id":"d6916808_8d166605","line":219,"in_reply_to":"e6d455ad_febb7362","updated":"2026-07-01 17:11:33.000000000","message":"The reason for the `if checksum_type` is because there is a case where a object should not have `x-amz-checksum-type` in its response, and that case is in MPU segments.\n\nTake for instance the response from AWS\n```\n$ aws s3api list-parts --bucket foo --key bar --upload-id abc\n{\n    \"Parts\": [\n        {\n            \"PartNumber\": 1,\n            \"LastModified\": \"2026-07-01T15:53:25+00:00\",\n            \"ETag\": \"\\\"88da5ba4952665e7a2bf1cf6c4c17602\\\"\",\n            \"Size\": 5092,\n            \"ChecksumCRC32\": \"0iUFow\u003d\u003d\"\n        },\n        {\n            \"PartNumber\": 2,\n            \"LastModified\": \"2026-07-01T15:53:35+00:00\",\n            \"ETag\": \"\\\"88da5ba4952665e7a2bf1cf6c4c17602\\\"\",\n            \"Size\": 5092,\n            \"ChecksumCRC32\": \"0iUFow\u003d\u003d\"\n        }\n    ],\n    \"ChecksumAlgorithm\": \"CRC32\",\n    \"StorageClass\": \"STANDARD\",\n    \"ChecksumType\": \"COMPOSITE\"\n}\n```\n\nFor MPU segments, they don\u0027t store the type since the type belongs to the MPU itself and children follow it.\nThough, since this patch does not include a feature, we should move it to the MPU patch in 993193: s3api: User Checksum Persistence on MPUs | https://review.opendev.org/c/openstack/swift/+/993193","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":true,"context_lines":[{"line_number":261,"context_line":"        SubElement(elem, \u0027ETag\u0027).text \u003d \u0027\"%s\"\u0027 % self.etag"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"        if result_elem_name \u003d\u003d \u0027CopyObjectResult\u0027:"},{"line_number":264,"context_line":"            checksum_header \u003d source_resp.sysmeta_headers.get("},{"line_number":265,"context_line":"                sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027))"},{"line_number":266,"context_line":"            checksum_value \u003d source_resp.sysmeta_headers.get("},{"line_number":267,"context_line":"                sysmeta_header(\u0027object\u0027, \u0027checksum-value\u0027))"}],"source_content_type":"text/x-python","patch_set":44,"id":"72d20016_08bd15fa","line":264,"updated":"2026-07-22 01:29:15.000000000","message":"this ``source_resp`` is the earlier HEAD response before the server side copy actually happens, so a concurrent source overwrite can therefore make the XML report the old checksum while the destination contains the new object.\n\nif an unversioned source changes between those requests(HEAD and the actual COPY), Swift returns checksum A while the destination contains data and checksum B. so copy middleware will do something like this:\n      - Preliminary HEAD: CRC32/OLD\n      - (object overwritten with SHA256/NEW)\n      - Actual copy GET: SHA256/NEW\n      - Destination sysmeta: SHA256/NEW\n      - Returned XML: CRC32/OLD\n\nThe final copy response already contains metadata from the actual GET. ``append_copy_resp_body`` should use checksum fields from ``self.sysmeta_headers`` which is the final response, not ``source_resp``. and also please add a race test for this scenario.","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"dcdffadc6ca94a0293e01d1a238d2025cb8c8078","unresolved":true,"context_lines":[{"line_number":261,"context_line":"        SubElement(elem, \u0027ETag\u0027).text \u003d \u0027\"%s\"\u0027 % self.etag"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"        if result_elem_name \u003d\u003d \u0027CopyObjectResult\u0027:"},{"line_number":264,"context_line":"            checksum_header \u003d source_resp.sysmeta_headers.get("},{"line_number":265,"context_line":"                sysmeta_header(\u0027object\u0027, \u0027checksum-header\u0027))"},{"line_number":266,"context_line":"            checksum_value \u003d source_resp.sysmeta_headers.get("},{"line_number":267,"context_line":"                sysmeta_header(\u0027object\u0027, \u0027checksum-value\u0027))"}],"source_content_type":"text/x-python","patch_set":44,"id":"99104b39_5069543c","line":264,"in_reply_to":"72d20016_08bd15fa","updated":"2026-07-22 15:41:10.000000000","message":"Thanks for catching this! Will fix!","commit_id":"a8773ec5f0453328a6b1afa9b1d0bd1a0872ba52"}],"swift/common/middleware/s3api/utils.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"0193c45bce1320a5f7108f88acf9f8e953c3094c","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    \u0027x-amz-checksum-sha1\u0027: \u0027ChecksumSHA1\u0027,"},{"line_number":37,"context_line":"    \u0027x-amz-checksum-sha256\u0027: \u0027ChecksumSHA256\u0027,"},{"line_number":38,"context_line":"}"},{"line_number":39,"context_line":"def sysmeta_prefix(resource):"},{"line_number":40,"context_line":"    \"\"\""},{"line_number":41,"context_line":"    Returns the system metadata prefix for given resource type."},{"line_number":42,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":34,"id":"84c7b66d_d4de8210","line":39,"updated":"2026-07-06 21:03:38.000000000","message":"pep8: E302 expected 2 blank lines, found 0","commit_id":"0008d249866a14cdc23cb557c5dba15a95825daf"}],"swift/common/middleware/versioned_writes/object_versioning.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"c55c01169ccef422262ebff3f06ec31303f18011","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        close_if_possible(put_req.environ[\u0027wsgi.input\u0027])"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":""},{"line_number":356,"context_line":"        # check for footers that may have been written"},{"line_number":357,"context_line":"        put_footers \u003d HeaderKeyDict()"},{"line_number":358,"context_line":"        if incoming_footer_callback:"},{"line_number":359,"context_line":"            # NB: *Don\u0027t* use the callback currently installed in"}],"source_content_type":"text/x-python","patch_set":32,"id":"15b496ad_d914019b","line":356,"updated":"2026-07-06 17:15:10.000000000","message":"pep8: E303 too many blank lines (2)","commit_id":"a1c0e141d70061a05925747991205d39385afd54"}],"test/s3api/test_object_checksums.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"0193c45bce1320a5f7108f88acf9f8e953c3094c","unresolved":false,"context_lines":[{"line_number":374,"context_line":"    EXPECTED \u003d \u0027y/Q5Jg\u003d\u003d\u0027"},{"line_number":375,"context_line":"    INVALID \u003d \u0027y/Q5Jh\u003d\u003d\u0027"},{"line_number":376,"context_line":"    BAD \u003d \u0027z/Q5Jg\u003d\u003d\u0027"},{"line_number":377,"context_line":"    CHECKSUM_FUNC \u003d staticmethod(crc32)"},{"line_number":378,"context_line":""},{"line_number":379,"context_line":""},{"line_number":380,"context_line":"class TestObjectChecksumCRC32C(ObjectChecksumMixin, BaseS3TestCaseWithBucket):"}],"source_content_type":"text/x-python","patch_set":34,"id":"285feadb_abc18d00","line":377,"updated":"2026-07-06 21:03:38.000000000","message":"pep8: F821 undefined name \u0027crc32\u0027","commit_id":"0008d249866a14cdc23cb557c5dba15a95825daf"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"0193c45bce1320a5f7108f88acf9f8e953c3094c","unresolved":false,"context_lines":[{"line_number":401,"context_line":"    EXPECTED \u003d \u0027rosUhgp5mIg\u003d\u0027"},{"line_number":402,"context_line":"    INVALID \u003d \u0027rosUhgp5mIh\u003d\u0027"},{"line_number":403,"context_line":"    BAD \u003d \u0027sosUhgp5mIg\u003d\u0027"},{"line_number":404,"context_line":"    CHECKSUM_FUNC \u003d staticmethod(crc64nvme)"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    @classmethod"},{"line_number":407,"context_line":"    def setUpClass(cls):"}],"source_content_type":"text/x-python","patch_set":34,"id":"4fe7f7a3_b8e22479","line":404,"updated":"2026-07-06 21:03:38.000000000","message":"pep8: F821 undefined name \u0027crc64nvme\u0027","commit_id":"0008d249866a14cdc23cb557c5dba15a95825daf"}],"test/unit/common/middleware/s3api/test_multi_delete.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":true,"context_lines":[{"line_number":179,"context_line":""},{"line_number":180,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":181,"context_line":"        self.assertEqual(status.split()[0], \u0027200\u0027)"},{"line_number":182,"context_line":"        self.assertNotIn(\u0027swift.callback.update_footers\u0027, req.environ)"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        delete_call \u003d self.swift.call_list[-1]"},{"line_number":185,"context_line":"        self.assertEqual(\u0027DELETE\u0027, delete_call.method)"}],"source_content_type":"text/x-python","patch_set":39,"id":"e66306b6_1d272099","line":182,"updated":"2026-07-22 01:29:15.000000000","message":"make sure those headers won\u0027t be in the response\n```\n        self.assertNotIn(\u0027x-amz-checksum-crc32\u0027, headers)\n        self.assertNotIn(\u0027x-amz-checksum-type\u0027, headers)\n```","commit_id":"66562ca79f57f52f34cc17487020652b4611f619"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1b9240f1edcf1e70caa4d562c1d3882c51b7e0d2","unresolved":true,"context_lines":[{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        delete_call \u003d self.swift.call_list[-1]"},{"line_number":185,"context_line":"        self.assertEqual(\u0027DELETE\u0027, delete_call.method)"},{"line_number":186,"context_line":"        self.assertNotIn(\u0027swift.callback.update_footers\u0027, delete_call.env)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def test_object_multi_DELETE(self):"},{"line_number":189,"context_line":"        self.swift.register(\u0027DELETE\u0027, \u0027/v1/AUTH_test/bucket/Key1\u0027,"}],"source_content_type":"text/x-python","patch_set":39,"id":"d8a30c2d_ab127c9e","line":186,"updated":"2026-07-22 01:29:15.000000000","message":"and those sysmeta won\u0027t be stored.\n```\n        for key in (\u0027X-Object-Sysmeta-S3Api-Checksum-Header\u0027,\n                    \u0027X-Object-Sysmeta-S3Api-Checksum-Value\u0027,\n                    \u0027X-Object-Sysmeta-S3Api-Checksum-Type\u0027):\n            self.assertNotIn(key, call.headers)\n            self.assertNotIn(key, call.footers)\n```","commit_id":"66562ca79f57f52f34cc17487020652b4611f619"}],"test/unit/common/middleware/s3api/test_obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fa53a0e6a29b2fdff32cda213fec6fdc0fbdc11f","unresolved":true,"context_lines":[{"line_number":1155,"context_line":""},{"line_number":1156,"context_line":"    def assert_no_checksum_sysmeta(self, headers):"},{"line_number":1157,"context_line":"        for name in (\u0027checksum-header\u0027, \u0027checksum-value\u0027, \u0027checksum-type\u0027):"},{"line_number":1158,"context_line":"            self.assertNotIn(sysmeta_header(\u0027object\u0027, name), headers)"},{"line_number":1159,"context_line":""},{"line_number":1160,"context_line":"    def assert_no_checksum_response_headers(self, headers):"},{"line_number":1161,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-crc32\u0027, headers)"}],"source_content_type":"text/x-python","patch_set":12,"id":"f97fba9f_b2cff286","line":1158,"updated":"2026-06-17 00:00:40.000000000","message":"I don\u0027t *generally* like assert helpers; they\u0027re not *BAD* for DRYing out test code but there\u0027s something really wonderful about a test that asserts on a literal right in your face:\n\n\n```\nself.assertEqual(swift_api_subrequest.headers, {\n  \u0027X-Object-Sysmeta-S3api-Checksum-Value\u0027: b64_checksum,\n  \u0027X-Object-Sysmeta-S3api-Checksum-Header\u0027: \u0027x-amz-checksum-32\u0027,\n  \u0027X-Object-Sysmeta-S3api-Checksum-type\u0027: \u0027CRC32\u0027,\n})\n```\n\n^ or, you know... whatever they are - like I can\u0027t tell what they *actually* are from reading these tests through all their helper layers.","commit_id":"769d4f8b5ecd3672b9964697e0388e29916ec731"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"0a359a676c868b8dd65838ee775d6748771e164b","unresolved":false,"context_lines":[{"line_number":1155,"context_line":""},{"line_number":1156,"context_line":"    def assert_no_checksum_sysmeta(self, headers):"},{"line_number":1157,"context_line":"        for name in (\u0027checksum-header\u0027, \u0027checksum-value\u0027, \u0027checksum-type\u0027):"},{"line_number":1158,"context_line":"            self.assertNotIn(sysmeta_header(\u0027object\u0027, name), headers)"},{"line_number":1159,"context_line":""},{"line_number":1160,"context_line":"    def assert_no_checksum_response_headers(self, headers):"},{"line_number":1161,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-crc32\u0027, headers)"}],"source_content_type":"text/x-python","patch_set":12,"id":"ef5a28b3_c59a3a93","line":1158,"in_reply_to":"f97fba9f_b2cff286","updated":"2026-06-23 15:33:33.000000000","message":"Acknowledged","commit_id":"769d4f8b5ecd3672b9964697e0388e29916ec731"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":163,"context_line":"            if method \u003d\u003d \u0027GET\u0027:"},{"line_number":164,"context_line":"                self.assertEqual(self.object_body, body)"},{"line_number":165,"context_line":"            else:"},{"line_number":166,"context_line":"                self.assertEqual(b\u0027\u0027, body)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def test_object_GET_checksum_mode_enabled_range_omits_checksum_headers("},{"line_number":169,"context_line":"            self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"be56d06c_f1c69152","line":166,"updated":"2026-06-30 23:51:02.000000000","message":"`for method in (GET, ...): if method \u003d\u003d \u0027GET\u0027`\n\n^ this is anti-pattern, it\u0027s clearly testing two things there\u0027s no good reason for them to be in the same test and you can *tell* because there\u0027s actually two different assertion branches - what are you going to add POST to the list above?  with that repsonse not have a body?  what maintaince value does writing this test provide besides making it harder for reviewers to read.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"ec8aee0b04cea073a2d649b94af43388a17ee16d","unresolved":false,"context_lines":[{"line_number":163,"context_line":"            if method \u003d\u003d \u0027GET\u0027:"},{"line_number":164,"context_line":"                self.assertEqual(self.object_body, body)"},{"line_number":165,"context_line":"            else:"},{"line_number":166,"context_line":"                self.assertEqual(b\u0027\u0027, body)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def test_object_GET_checksum_mode_enabled_range_omits_checksum_headers("},{"line_number":169,"context_line":"            self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"5ffdca4e_bcdcf17b","line":166,"in_reply_to":"bc0e2c18_0b1c13f1","updated":"2026-07-01 21:29:08.000000000","message":"Marked as resolved.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":true,"context_lines":[{"line_number":163,"context_line":"            if method \u003d\u003d \u0027GET\u0027:"},{"line_number":164,"context_line":"                self.assertEqual(self.object_body, body)"},{"line_number":165,"context_line":"            else:"},{"line_number":166,"context_line":"                self.assertEqual(b\u0027\u0027, body)"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    def test_object_GET_checksum_mode_enabled_range_omits_checksum_headers("},{"line_number":169,"context_line":"            self):"}],"source_content_type":"text/x-python","patch_set":25,"id":"bc0e2c18_0b1c13f1","line":166,"in_reply_to":"be56d06c_f1c69152","updated":"2026-07-01 17:11:33.000000000","message":"I agree here, since this test is not really going to be changed, and for ease of reading for reviewers, I\u0027ll move this to two verbose tests","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":192,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-crc32\u0027, headers)"},{"line_number":193,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-type\u0027, headers)"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"    def test_object_HEAD_checksum_mode_enabled_range_omits_checksum_headers("},{"line_number":196,"context_line":"            self):"},{"line_number":197,"context_line":"        swift_headers \u003d dict(self.response_headers)"},{"line_number":198,"context_line":"        swift_headers.update({"}],"source_content_type":"text/x-python","patch_set":25,"id":"56b4694d_f642a5cc","line":195,"updated":"2026-06-30 23:51:02.000000000","message":"haha, look here we got it right!","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":false,"context_lines":[{"line_number":192,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-crc32\u0027, headers)"},{"line_number":193,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-type\u0027, headers)"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"    def test_object_HEAD_checksum_mode_enabled_range_omits_checksum_headers("},{"line_number":196,"context_line":"            self):"},{"line_number":197,"context_line":"        swift_headers \u003d dict(self.response_headers)"},{"line_number":198,"context_line":"        swift_headers.update({"}],"source_content_type":"text/x-python","patch_set":25,"id":"69498986_f503f475","line":195,"in_reply_to":"56b4694d_f642a5cc","updated":"2026-07-01 17:11:33.000000000","message":"Acknowledged","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2820ddfe96856511be725ab4866ad6f49713e8ba","unresolved":true,"context_lines":[{"line_number":220,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-type\u0027, headers)"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def test_object_GETorHEAD_checksum_mode_part_number_omits_checksum("},{"line_number":223,"context_line":"            self):"},{"line_number":224,"context_line":"        for method in (\u0027GET\u0027, \u0027HEAD\u0027):"},{"line_number":225,"context_line":"            swift_headers \u003d dict(self.response_headers)"},{"line_number":226,"context_line":"            swift_headers.update({"}],"source_content_type":"text/x-python","patch_set":25,"id":"9d71c454_160654db","line":223,"updated":"2026-06-30 23:51:02.000000000","message":"I could imagine a test setup that explores a variety of request params for a given consistent set of mocked sysmeta, or this style of straight and to the point named behiavor style tests\n\nI\u0027m less enthused about a hybrid approach that sometimes uses loops to combine concepts and sometimes uses seperate tests for keep assertions linear.","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"4a96b7f886c3f087a097ab1861605102c01d88ba","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        self.assertNotIn(\u0027x-amz-checksum-type\u0027, headers)"},{"line_number":221,"context_line":""},{"line_number":222,"context_line":"    def test_object_GETorHEAD_checksum_mode_part_number_omits_checksum("},{"line_number":223,"context_line":"            self):"},{"line_number":224,"context_line":"        for method in (\u0027GET\u0027, \u0027HEAD\u0027):"},{"line_number":225,"context_line":"            swift_headers \u003d dict(self.response_headers)"},{"line_number":226,"context_line":"            swift_headers.update({"}],"source_content_type":"text/x-python","patch_set":25,"id":"81cf7d8a_7dd3f297","line":223,"in_reply_to":"9d71c454_160654db","updated":"2026-07-01 17:11:33.000000000","message":"Acknowledged","commit_id":"fb609cd4cb20e962b204d16db02534529b4a04b1"}]}
