)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d836740727dbd08be61d6b2f848506781b9bcbdd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"52a21c75_71fe1880","updated":"2024-03-05 22:59:44.000000000","message":"recheck\n\nI don\u0027t understand this failure: the parent has passing probe tests, but this one has *reliably* failed the same signals tests: https://zuul.opendev.org/t/openstack/builds?job_name\u003dswift-probetests-centos-8-stream\u0026project\u003dopenstack%2Fswift\u0026change\u003d909801\n\nYet this patch only touches s3api! Only one probe test touches that API, and it\u0027s not the test that fails!","commit_id":"c76ec71c3ec97d1f9890b37c9d0d82df8edeacc7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4046976ea72eb92741a6324f843ef4437cc73be0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"e5f4d7c6_18bc6ed4","updated":"2024-03-21 02:39:33.000000000","message":"recheck\n\nIt\u0027s a long shot, but now that https://review.opendev.org/c/openstack/swift/+/886654 merged, we *might* get different probe test results.","commit_id":"164252d6716e408215688c31afa5ebb06d6d246f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4a4bfdc52bbea15a1b98efefce00a3228592285c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"32d32606_28df0114","updated":"2024-08-26 15:45:49.000000000","message":"recheck","commit_id":"1d2cfb45ce9007f08fe9263fa9de7f5efd75cf07"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":23,"id":"4632faa3_3fac2431","updated":"2024-09-19 04:05:12.000000000","message":"Yeah looks really good just some questions inline before I up my vote 😊","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0f541f74961c730b0489eef48528df8a9f2c2319","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":23,"id":"8d37eea5_eb18fab3","updated":"2024-09-19 04:07:47.000000000","message":"hmm, there is a convention downstream to use a +1 as a maybe we could carry it.. which I don\u0027t tend to use... but to not confust people. I\u0027ll -1 to just get answers to my question or comments (although none are blockers).","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"23e3c8e84745568961c2aa7c6efbb4ed75c5c5de","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"3f1c9f03_4988987c","updated":"2024-10-03 15:13:44.000000000","message":"LGTM","commit_id":"79c60c8f04da7649a5959646877b587a28fb52f6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c354795d8046f6ee70bcc8cbb67fe2af03f2431f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":28,"id":"b53b7e2b_2a2494dd","updated":"2024-10-02 15:37:07.000000000","message":"recheck","commit_id":"79c60c8f04da7649a5959646877b587a28fb52f6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"251824def997435b575884223cbf7c00622054ff","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"e86b78f8_09fbf2c5","updated":"2024-10-09 15:43:06.000000000","message":"We will have to address the test failures but apart from that you have incorporated everything else i asked.","commit_id":"d6194628d0cc0188e9039a5b89c1e056b1f14d5d"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"763bc2bbc2c6fe7ac41666dbbd5350b0280ca5c1","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":29,"id":"793f8a9b_82edd57a","in_reply_to":"0b4dc457_ba55022e","updated":"2024-10-15 21:01:05.000000000","message":"I was able to replicate the test failure once i have `s3_acls` enabled, crzy see following test output below:\n\n```\ntest/functional/s3api/test_bucket.py: 12 warnings\n  /vagrant/python-swiftclient/swiftclient/client.py:461: DeprecationWarning: HTTPResponse.getheader() is deprecated and will be removed in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).\n    return _decode_header(old_getheader(\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d short test summary info \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nFAILED test/functional/s3api/test_bucket.py::TestS3ApiBucket::test_bucket_invalid_method_error - AssertionError: \u0027SignatureDoesNotMatch\u0027 !\u003d \u0027MethodNotAllowed\u0027\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d 1 failed, 57 warnings in 1.00s \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n```\n\nIt might be worth giving a heads-up to our users that when they decide to use sigv4 streaming that they do not use `s3_acls` since i know for a fact that some people do use it!!\n\nShould there be a doc update regarding the same ?","commit_id":"d6194628d0cc0188e9039a5b89c1e056b1f14d5d"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"04eca628ac84e6f0e2543dd798f0c9e3211f86ec","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":29,"id":"5355d9e2_e2a5a92e","in_reply_to":"5f360977_13e81a8b","updated":"2024-10-25 20:27:54.000000000","message":"Done","commit_id":"d6194628d0cc0188e9039a5b89c1e056b1f14d5d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1c61f7a2af28ab33832c06fce8962e0773cc9566","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":29,"id":"5f360977_13e81a8b","in_reply_to":"793f8a9b_82edd57a","updated":"2024-10-15 22:01:32.000000000","message":"It seems unrelated to this change, though -- it\u0027s just highlighted by the new desire to install `awscrt` in dev environments.\n\nWe found a newly-discovered (but likely long-present) difference when you\u0027re _already sending a bad method_. I put up https://review.opendev.org/c/openstack/swift/+/932236 to at least resolve it slightly more consistently, but it seems like a corner case that\u0027s further out of the way than most users would stumble, or we would\u0027ve heard about it by now.","commit_id":"d6194628d0cc0188e9039a5b89c1e056b1f14d5d"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6b4f1f01dbf8a240c133d47d8bf8802cf0c244c2","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":29,"id":"0b4dc457_ba55022e","in_reply_to":"e86b78f8_09fbf2c5","updated":"2024-10-09 20:29:12.000000000","message":"This is so weird that i cannot seem to replicate the test failure in my laptop:\n```\npython --version\nPython 3.8.18\n(venv) ashnair@ashnair-mlt swift % pytest test/functional/s3api/test_bucket.py::TestS3ApiBucket::test_bucket_invalid_method_error\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d test session starts \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nplatform darwin -- Python 3.8.18, pytest-8.1.1, pluggy-1.5.0 -- /Users/ashnair/vagrant-swift-all-in-one/swift/venv/bin/python\ncachedir: .pytest_cache\nrootdir: /Users/ashnair/vagrant-swift-all-in-one/swift\nconfigfile: tox.ini\nplugins: cov-5.0.0\ncollected 1 item                                                                                                                                                                                                                                                                             \n\ntest/functional/s3api/test_bucket.py::TestS3ApiBucket::test_bucket_invalid_method_error PASSED                                                                                                                                                                                         [100%]\n\n```\n\nKindly lmk if you had more success with the same","commit_id":"d6194628d0cc0188e9039a5b89c1e056b1f14d5d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1c61f7a2af28ab33832c06fce8962e0773cc9566","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":31,"id":"ee39d4d1_7f4ed5f6","updated":"2024-10-15 22:01:32.000000000","message":"So there\u0027s still one big open question for this and the next patch: Do we want to have alternate-checksums as a first-class Swift feature *first*, then have s3api use it? Or go this route and have it s3api-only (at least to start)?\n\nIs there some viable middle-ground where we maintain the integrity guarantees on PUT but skip writing it down? Or is that too close to the worst of both worlds?","commit_id":"ee0c1a1da16f6c6386341275fba9f14129061080"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"eb515172ad353d02dad236e91a95bffcd4d23ae6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":33,"id":"abecc39d_ed3581b2","updated":"2024-11-06 20:57:11.000000000","message":"@nairashwin952013@gmail.com I majorly reworked `test/s3api/test_object_checksums.py` in an effort to\n\n1. make things more readable and\n2. have each test (mainly) test one operation.\n\nSee what you think as an alternative to the refactoring going on in https://review.opendev.org/c/openstack/swift/+/931223","commit_id":"ecd7b9e05e07cc9c148469ab5fbe77771a44ce12"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"68c79a7ac69267cfa5b759815d180f228bd88fee","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":34,"id":"80851d4d_b6619c0e","updated":"2024-11-08 16:35:40.000000000","message":"Can we also add this [change](https://review.opendev.org/c/openstack/swift/+/931223/10/test/unit/common/middleware/s3api/test_multi_upload.py) from the refactor patch? It will increase coverage in our unit-test","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bcbbac457078d15cac950265726cf3bbf6606696","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":34,"id":"9c556d05_7edf9ca6","updated":"2024-11-07 00:42:47.000000000","message":"recheck\n\nprobe test hang","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"152653a360c88ec6f287c78bdc76bccefadd1931","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":34,"id":"b5b15fa0_e9e99fe2","in_reply_to":"6bf547e9_fe0f73e3","updated":"2024-12-02 21:50:26.000000000","message":"Done","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7986f51ba65404eb1e54c7d1e81a23f19e06dfd0","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":34,"id":"6bf547e9_fe0f73e3","in_reply_to":"80851d4d_b6619c0e","updated":"2024-11-08 20:54:38.000000000","message":"That\u0027s the main thing we still want from that patch, right? Your new assertion passes on master, too, so I was thinking we could pare down your patch to just the \"drive-by\" and resubmit it independently -- I think we could merge it faster that way, and it feels pretty separate from the rest of this change.","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":35,"id":"4f0ee9e4_56ca6f6e","updated":"2024-12-17 03:56:58.000000000","message":"I\u0027m almost ready to +2 this one too. Just a small issue where we use a sysmeta header helper function and then a few lines later don\u0027t. Feels like we should.\n\nSo basically a very very weak -1 and really only being nitpicky 😊","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0b3be5410111a7258f168ced3fb86942f96572b5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":35,"id":"7165350a_8fd8d61e","updated":"2024-12-17 05:17:30.000000000","message":"Looking great though!\n\n```\nvagrant@saio7:~$ aws  s3 mb s3://bucket\nmake_bucket: bucket\nvagrant@saio7:~$ aws s3api put-object  --bucket bucket --key put_a_bunch_many_accounts.sh --checksum-algorithm SHA256 --body put_a_bunch_many_accounts.sh\n{\n    \"ETag\": \"\\\"549a8d12efa1a4dbf53573adaac64cb7\\\"\"\n}\nvagrant@saio7:~$ find /srv/ -name \"*.data\"\n/srv/node2/sdb2/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\n/srv/node3/sdb3/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\n/srv/node4/sdb4/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\nvagrant@saio7:~$ swift-object-info /srv/node2/sdb2/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\nPath: /AUTH_test/bucket/put_a_bunch_many_accounts.sh\n  Account: AUTH_test\n  Container: bucket\n  Object: put_a_bunch_many_accounts.sh\n  Object hash: ced3985d1ad7908a3ae78c9e4af68921\nContent-Type: binary/octet-stream\nTimestamp: 2024-12-17T05:10:13.866370 (1734412213.86637)\nSystem Metadata:\n  X-Object-Sysmeta-Container-Update-Override-Etag: 549a8d12efa1a4dbf53573adaac64cb7; s3_sha256\u003dc44r+ftD3+C+MCgNg2IXSlPhKAd3r2WkofRhTUl0Beg\u003d\n  X-Object-Sysmeta-S3Api-Checksum-Sha256: c44r+ftD3+C+MCgNg2IXSlPhKAd3r2WkofRhTUl0Beg\u003d\n...\nvagrant@saio7:~$ aws s3api put-object --checksum-sha256 c44r+ftD3+C+MCgNg2IXSlPhKAd3r2WkofRhTUl0Beg\u003d --bucket bucket --key put_a_bunch_many_accounts.sh2 --checksum-algorithm SHA256 --body put_a_bunch_many_accounts.sh\n{\n    \"ETag\": \"\\\"549a8d12efa1a4dbf53573adaac64cb7\\\"\"\n}\nvagrant@saio7:~$ find /srv/ -name \"*.data\"\n/srv/node1/sdb1/objects/577/ab6/9047ee01494fb0bc41b682eb884ebab6/1734412293.50926.data\n/srv/node2/sdb2/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\n/srv/node3/sdb3/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\n/srv/node3/sdb3/objects/577/ab6/9047ee01494fb0bc41b682eb884ebab6/1734412293.50926.data\n/srv/node4/sdb4/objects/827/921/ced3985d1ad7908a3ae78c9e4af68921/1734412213.86637.data\n/srv/node4/sdb4/objects/577/ab6/9047ee01494fb0bc41b682eb884ebab6/1734412293.50926.data\nvagrant@saio7:~$ swift-object-\nswift-object-auditor        swift-object-expirer        swift-object-info           swift-object-reconstructor  swift-object-relinker       swift-object-replicator     swift-object-server         swift-object-updater        \nvagrant@saio7:~$ swift-object-info /srv/node1/sdb1/objects/577/ab6/9047ee01494fb0bc41b682eb884ebab6/1734412293.50926.data\nPath: /AUTH_test/bucket/put_a_bunch_many_accounts.sh2\n  Account: AUTH_test\n  Container: bucket\n  Object: put_a_bunch_many_accounts.sh2\n  Object hash: 9047ee01494fb0bc41b682eb884ebab6\nContent-Type: binary/octet-stream\nTimestamp: 2024-12-17T05:11:33.509260 (1734412293.50926)\nSystem Metadata:\n  X-Object-Sysmeta-Container-Update-Override-Etag: 549a8d12efa1a4dbf53573adaac64cb7; s3_sha256\u003dc44r+ftD3+C+MCgNg2IXSlPhKAd3r2WkofRhTUl0Beg\u003d\n  X-Object-Sysmeta-S3Api-Checksum-Sha256: c44r+ftD3+C+MCgNg2IXSlPhKAd3r2WkofRhTUl0Beg\u003d\nTransient System Metadata:\n  No metadata found\nUser Metadata:\n  No metadata found\nOther Metadata:\n  No metadata found\nETag: 549a8d12efa1a4dbf53573adaac64cb7 (valid)\nContent-Length: 391 (valid)\nPartition\t577\nHash     \t9047ee01494fb0bc41b682eb884ebab6\n...\n```","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d7e6c391b3f3d953d3622e928951a57da88bb533","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":35,"id":"19ab2ff0_de9fece4","updated":"2024-11-25 18:20:43.000000000","message":"recheck","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b783a9c86b566e5d7fb1c31e406d9675ecfdb07f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":36,"id":"55f7289a_ffc067f3","updated":"2024-12-17 22:27:41.000000000","message":"This is looking great!","commit_id":"1fa4a325fb17f5bc3f90f7068c499528d9202660"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"8af2700da5768ee24b4670eedf8c0fe573f9b289","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"c519ca2e_323e5efb","updated":"2024-12-18 02:13:14.000000000","message":"Now everything should be good from a zull POV","commit_id":"45e396a4696d3e93b359c53dfe02ec65d31a87cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":40,"id":"27b39ef4_c540f1ca","updated":"2025-01-20 18:48:15.000000000","message":"IMHO this needs way more unit test coverage.\n\nI think I grok it though - there\u0027s some new checksum header validation; a checksum handler gets installed in S3Request; S3Response needs to add a header. And we get support for the checksums 😊\n\nIt would be great if the proxy and middlewares could be more coordinated about calculating the md5 to save us some cycles.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"198aa9356a8f22046cd3838726b4a72be0eebf6a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":41,"id":"e152c533_0a43a237","updated":"2025-01-22 14:58:19.000000000","message":"recheck\n\nthe py312 job failed to post results; the other failed job is non-voting","commit_id":"9fb91818710ded3d1f501a00ba5037511eafd703"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":45,"id":"b7323981_d45e9a0f","updated":"2025-02-21 15:31:58.000000000","message":"@Tim some suggestions here https://review.opendev.org/c/openstack/swift/+/942464","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"}],"swift/common/middleware/s3api/controllers/bucket.py":[{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":313,"context_line":"                # quote-wrap."},{"line_number":314,"context_line":"            SubElement(contents, \u0027ETag\u0027).text \u003d etag"},{"line_number":315,"context_line":"            SubElement(contents, \u0027Size\u0027).text \u003d str(o[\u0027bytes\u0027])"},{"line_number":316,"context_line":"            for chksum in (\u0027crc32\u0027, \u0027crc32c\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":317,"context_line":"                if \u0027s3_\u0027 + chksum in o:"},{"line_number":318,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":319,"context_line":"                        chksum.upper()"}],"source_content_type":"text/x-python","patch_set":26,"id":"607234b0_1fce1aae","line":316,"updated":"2024-09-27 18:59:47.000000000","message":"Can we use a map for the checksum algorithms to their corresponding keys in \"o\" and then iterate over the dictionary items (its nice that im remembering my algirthms class)? The dict approach probably uses slightly less memory but it might be negligible, it makes the code more readable though with something like:\n\n```\n# Dictionary mapping checksum algorithms to their corresponding keys\nchecksums \u003d {\n    \u0027crc32\u0027: \u0027s3_crc32\u0027,\n    \u0027crc32c\u0027: \u0027s3_crc32c\u0027,\n    \u0027sha1\u0027: \u0027s3_sha1\u0027,\n    \u0027sha256\u0027: \u0027s3_sha256\u0027\n}\n\n```\n\nand then iterate over the keys:\n```\nfor chksum, key in checksums.items():\n    if key in o:\n        SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d chksum.upper()\n\nif fetch_owner or listing_type !\u003d \u0027version-2\u0027:\n    owner \u003d SubElement(contents, \u0027Owner\u0027)\n    SubElement(owner, \u0027ID\u0027).text \u003d req.user_id\n    SubElement(owner, \u0027DisplayName\u0027).text \u003d req.user_id\nif contents.tag !\u003d \u0027DeleteMarker\u0027:\n    SubElement(contents, \u0027StorageClass\u0027).text \u003d \u0027STANDARD\u0027\n```\n\nBoth approaches have O(n\u003d4) complexity sicne we have only 4 algorithms","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"73205651696a9e9239ad262ef5f8240c94a09736","unresolved":false,"context_lines":[{"line_number":313,"context_line":"                # quote-wrap."},{"line_number":314,"context_line":"            SubElement(contents, \u0027ETag\u0027).text \u003d etag"},{"line_number":315,"context_line":"            SubElement(contents, \u0027Size\u0027).text \u003d str(o[\u0027bytes\u0027])"},{"line_number":316,"context_line":"            for chksum in (\u0027crc32\u0027, \u0027crc32c\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":317,"context_line":"                if \u0027s3_\u0027 + chksum in o:"},{"line_number":318,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":319,"context_line":"                        chksum.upper()"}],"source_content_type":"text/x-python","patch_set":26,"id":"6dda9803_56a8ce2b","line":316,"in_reply_to":"607234b0_1fce1aae","updated":"2024-09-27 23:23:29.000000000","message":"Good idea! Especially by the next patch, I start repeating these lists and lookups a bunch; pulling them out to a dict made it way better.","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":316,"context_line":"            for chksum in (\u0027crc32\u0027, \u0027crc32c\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":317,"context_line":"                if \u0027s3_\u0027 + chksum in o:"},{"line_number":318,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":319,"context_line":"                        chksum.upper()"},{"line_number":320,"context_line":"        if fetch_owner or listing_type !\u003d \u0027version-2\u0027:"},{"line_number":321,"context_line":"            owner \u003d SubElement(contents, \u0027Owner\u0027)"},{"line_number":322,"context_line":"            SubElement(owner, \u0027ID\u0027).text \u003d req.user_id"}],"source_content_type":"text/x-python","patch_set":26,"id":"b98a9581_99c6f127","line":319,"updated":"2024-09-27 18:59:47.000000000","message":"The upper() f.n just returns these string values in UpperCAse","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba2bb8d51cca76951e013e84c6de9660fa104020","unresolved":false,"context_lines":[{"line_number":316,"context_line":"            for chksum in (\u0027crc32\u0027, \u0027crc32c\u0027, \u0027sha1\u0027, \u0027sha256\u0027):"},{"line_number":317,"context_line":"                if \u0027s3_\u0027 + chksum in o:"},{"line_number":318,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":319,"context_line":"                        chksum.upper()"},{"line_number":320,"context_line":"        if fetch_owner or listing_type !\u003d \u0027version-2\u0027:"},{"line_number":321,"context_line":"            owner \u003d SubElement(contents, \u0027Owner\u0027)"},{"line_number":322,"context_line":"            SubElement(owner, \u0027ID\u0027).text \u003d req.user_id"}],"source_content_type":"text/x-python","patch_set":26,"id":"9ace1d59_d5abe55c","line":319,"in_reply_to":"b98a9581_99c6f127","updated":"2024-10-01 20:37:34.000000000","message":"Acknowledged","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ac4abb47d3152475c45c09dfdf4c09b91d1d6e08","unresolved":true,"context_lines":[{"line_number":314,"context_line":"            SubElement(contents, \u0027Size\u0027).text \u003d str(o[\u0027bytes\u0027])"},{"line_number":315,"context_line":"            for chksum, param in checksum_to_listing_param.items():"},{"line_number":316,"context_line":"                if param in o:"},{"line_number":317,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":318,"context_line":"                        chksum.upper()"},{"line_number":319,"context_line":"        if fetch_owner or listing_type !\u003d \u0027version-2\u0027:"},{"line_number":320,"context_line":"            owner \u003d SubElement(contents, \u0027Owner\u0027)"}],"source_content_type":"text/x-python","patch_set":40,"id":"70d8c5f4_dfac6633","line":317,"range":{"start_line":317,"start_character":42,"end_line":317,"end_character":59},"updated":"2025-01-21 17:27:15.000000000","message":"is this *required* by clients?\n\nThe s3 doc has \u0027Required: No\u0027 https://docs.aws.amazon.com/AmazonS3/latest/API/API_Object.html ... but the same for all the members of the Object xml element !?\n\nIs there a cross-compat test that fails if we don\u0027t include this element?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":314,"context_line":"            SubElement(contents, \u0027Size\u0027).text \u003d str(o[\u0027bytes\u0027])"},{"line_number":315,"context_line":"            for chksum, param in checksum_to_listing_param.items():"},{"line_number":316,"context_line":"                if param in o:"},{"line_number":317,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":318,"context_line":"                        chksum.upper()"},{"line_number":319,"context_line":"        if fetch_owner or listing_type !\u003d \u0027version-2\u0027:"},{"line_number":320,"context_line":"            owner \u003d SubElement(contents, \u0027Owner\u0027)"}],"source_content_type":"text/x-python","patch_set":40,"id":"bd93a29a_525623ba","line":317,"range":{"start_line":317,"start_character":42,"end_line":317,"end_character":59},"in_reply_to":"70d8c5f4_dfac6633","updated":"2025-01-25 04:33:47.000000000","message":"https://review.opendev.org/c/openstack/swift/+/909801/40/test/s3api/test_object_checksums.py#75\n\nI think by \"Required: No\" they mean that the response may or may not include it -- though it\u0027s wild to me that `Key` is also annotated like that.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8de3d1e200b5a458ff19f0c81936a726cc36a88b","unresolved":true,"context_lines":[{"line_number":315,"context_line":"            for chksum, param in checksum_to_listing_param.items():"},{"line_number":316,"context_line":"                if param in o:"},{"line_number":317,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":318,"context_line":"                        chksum.upper()"},{"line_number":319,"context_line":"        if fetch_owner or listing_type !\u003d \u0027version-2\u0027:"},{"line_number":320,"context_line":"            owner \u003d SubElement(contents, \u0027Owner\u0027)"},{"line_number":321,"context_line":"            SubElement(owner, \u0027ID\u0027).text \u003d req.user_id"}],"source_content_type":"text/x-python","patch_set":40,"id":"ddc59881_d227051f","line":318,"updated":"2025-01-21 17:10:46.000000000","message":"so the value of param (which IIUC is the calculated digest) is not actually returned in the client listing?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":315,"context_line":"            for chksum, param in checksum_to_listing_param.items():"},{"line_number":316,"context_line":"                if param in o:"},{"line_number":317,"context_line":"                    SubElement(contents, \u0027ChecksumAlgorithm\u0027).text \u003d \\"},{"line_number":318,"context_line":"                        chksum.upper()"},{"line_number":319,"context_line":"        if fetch_owner or listing_type !\u003d \u0027version-2\u0027:"},{"line_number":320,"context_line":"            owner \u003d SubElement(contents, \u0027Owner\u0027)"},{"line_number":321,"context_line":"            SubElement(owner, \u0027ID\u0027).text \u003d req.user_id"}],"source_content_type":"text/x-python","patch_set":40,"id":"f0d71d2f_108ae123","line":318,"in_reply_to":"ddc59881_d227051f","updated":"2025-01-25 04:33:47.000000000","message":"Apparently not? It struck me as weird, too -- but I wanted to stuff the value into listings because\n- we may as well, and\n- AWS may well start putting the value in listings, and I don\u0027t want to be kicking myself later.\n\nOh! There\u0027s another reason I\u0027d forgotten about: we need it in listings when listing parts for in-progress uploads. If we need it for parts, may as well store it for all uploads.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"}],"swift/common/middleware/s3api/s3api.py":[{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":235,"context_line":"                if name in params:"},{"line_number":236,"context_line":"                    item[name] \u003d \u0027\"%s\"\u0027 % params.pop(name)"},{"line_number":237,"context_line":"                    changed \u003d True"},{"line_number":238,"context_line":"                for name in (\u0027s3_crc32\u0027, \u0027s3_crc32c\u0027, \u0027s3_sha1\u0027, \u0027s3_sha256\u0027):"},{"line_number":239,"context_line":"                    if name in params:"},{"line_number":240,"context_line":"                        item[name] \u003d params.pop(name)"},{"line_number":241,"context_line":"                        changed \u003d True"}],"source_content_type":"text/x-python","patch_set":26,"id":"b25d6f05_0ee7f0fe","line":238,"updated":"2024-09-27 18:59:47.000000000","message":"same here i guess prefer a dict over a loop","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"73205651696a9e9239ad262ef5f8240c94a09736","unresolved":false,"context_lines":[{"line_number":235,"context_line":"                if name in params:"},{"line_number":236,"context_line":"                    item[name] \u003d \u0027\"%s\"\u0027 % params.pop(name)"},{"line_number":237,"context_line":"                    changed \u003d True"},{"line_number":238,"context_line":"                for name in (\u0027s3_crc32\u0027, \u0027s3_crc32c\u0027, \u0027s3_sha1\u0027, \u0027s3_sha256\u0027):"},{"line_number":239,"context_line":"                    if name in params:"},{"line_number":240,"context_line":"                        item[name] \u003d params.pop(name)"},{"line_number":241,"context_line":"                        changed \u003d True"}],"source_content_type":"text/x-python","patch_set":26,"id":"3fe2aaea_740e1288","line":238,"in_reply_to":"b25d6f05_0ee7f0fe","updated":"2024-09-27 23:23:29.000000000","message":"Done","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":232,"context_line":"                    continue"},{"line_number":233,"context_line":"                value, params \u003d parse_header(item[\u0027hash\u0027])"},{"line_number":234,"context_line":"                changed \u003d False"},{"line_number":235,"context_line":"                name \u003d \u0027s3_etag\u0027"},{"line_number":236,"context_line":"                if name in params:"},{"line_number":237,"context_line":"                    item[name] \u003d \u0027\"%s\"\u0027 % params.pop(name)"},{"line_number":238,"context_line":"                    changed \u003d True"},{"line_number":239,"context_line":"                for name in checksum_to_listing_param.values():"},{"line_number":240,"context_line":"                    if name in params:"}],"source_content_type":"text/x-python","patch_set":40,"id":"7ec8ee21_aaf06376","line":237,"range":{"start_line":235,"start_character":16,"end_line":237,"end_character":58},"updated":"2025-01-20 18:48:15.000000000","message":"I\u0027m not sure breaking out the var ``name`` adds much here for s3_etag handling","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8de3d1e200b5a458ff19f0c81936a726cc36a88b","unresolved":true,"context_lines":[{"line_number":238,"context_line":"                    changed \u003d True"},{"line_number":239,"context_line":"                for name in checksum_to_listing_param.values():"},{"line_number":240,"context_line":"                    if name in params:"},{"line_number":241,"context_line":"                        item[name] \u003d params.pop(name)"},{"line_number":242,"context_line":"                        changed \u003d True"},{"line_number":243,"context_line":"                if changed:"},{"line_number":244,"context_line":"                    item[\u0027hash\u0027] \u003d value + \u0027\u0027.join("}],"source_content_type":"text/x-python","patch_set":40,"id":"89f6ed08_4ff569ee","line":241,"updated":"2025-01-21 17:10:46.000000000","message":"ok so here\u0027s where the param is extracted and put in the top level dict for bucket controller to later transform to the xml response","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":true,"context_lines":[{"line_number":131,"context_line":"    \"\"\""},{"line_number":132,"context_line":"    def __init__(self, expected, computed):"},{"line_number":133,"context_line":"        self.expected \u003d expected"},{"line_number":134,"context_line":"        self.computed \u003d computed"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"class HashingInput(object):"}],"source_content_type":"text/x-python","patch_set":23,"id":"c61936d3_1c72716b","side":"PARENT","line":134,"updated":"2024-09-19 04:05:12.000000000","message":"Ahh this just moved. Nice.","commit_id":"d402e93058c9bcdaec41343899f58db5764f38ed"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    \"\"\""},{"line_number":132,"context_line":"    def __init__(self, expected, computed):"},{"line_number":133,"context_line":"        self.expected \u003d expected"},{"line_number":134,"context_line":"        self.computed \u003d computed"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"class HashingInput(object):"}],"source_content_type":"text/x-python","patch_set":23,"id":"bc36870f_6985ba91","side":"PARENT","line":134,"in_reply_to":"c61936d3_1c72716b","updated":"2025-02-28 17:57:13.000000000","message":"Acknowledged","commit_id":"d402e93058c9bcdaec41343899f58db5764f38ed"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":true,"context_lines":[{"line_number":62,"context_line":"from swift.common.middleware.s3api.exception import NotS3Request, \\"},{"line_number":63,"context_line":"    S3InputSHA256Mismatch, S3InputChecksumMismatch"},{"line_number":64,"context_line":"from swift.common.middleware.s3api.utils import utf8encode, \\"},{"line_number":65,"context_line":"    S3Timestamp, mktime, MULTIUPLOAD_SUFFIX, CRCHasher"},{"line_number":66,"context_line":"from swift.common.middleware.s3api.subresource import decode_acl, encode_acl"},{"line_number":67,"context_line":"from swift.common.middleware.s3api.utils import sysmeta_header, \\"},{"line_number":68,"context_line":"    validate_bucket_name, Config"}],"source_content_type":"text/x-python","patch_set":23,"id":"887c0680_35731b29","line":65,"range":{"start_line":65,"start_character":45,"end_line":65,"end_character":54},"updated":"2024-09-19 04:05:12.000000000","message":"Is this a candidate to move to swift.common.checksum maybe?","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"52319526d88105fde797bf284e5e0d6924b52772","unresolved":false,"context_lines":[{"line_number":62,"context_line":"from swift.common.middleware.s3api.exception import NotS3Request, \\"},{"line_number":63,"context_line":"    S3InputSHA256Mismatch, S3InputChecksumMismatch"},{"line_number":64,"context_line":"from swift.common.middleware.s3api.utils import utf8encode, \\"},{"line_number":65,"context_line":"    S3Timestamp, mktime, MULTIUPLOAD_SUFFIX, CRCHasher"},{"line_number":66,"context_line":"from swift.common.middleware.s3api.subresource import decode_acl, encode_acl"},{"line_number":67,"context_line":"from swift.common.middleware.s3api.utils import sysmeta_header, \\"},{"line_number":68,"context_line":"    validate_bucket_name, Config"}],"source_content_type":"text/x-python","patch_set":23,"id":"a7246239_edda5ef1","line":65,"range":{"start_line":65,"start_character":45,"end_line":65,"end_character":54},"in_reply_to":"2477d8fa_f5435d2f","updated":"2024-10-10 21:38:27.000000000","message":"Done","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3285b6566002eb2a3a7c6a7229d7e9988d53adde","unresolved":true,"context_lines":[{"line_number":62,"context_line":"from swift.common.middleware.s3api.exception import NotS3Request, \\"},{"line_number":63,"context_line":"    S3InputSHA256Mismatch, S3InputChecksumMismatch"},{"line_number":64,"context_line":"from swift.common.middleware.s3api.utils import utf8encode, \\"},{"line_number":65,"context_line":"    S3Timestamp, mktime, MULTIUPLOAD_SUFFIX, CRCHasher"},{"line_number":66,"context_line":"from swift.common.middleware.s3api.subresource import decode_acl, encode_acl"},{"line_number":67,"context_line":"from swift.common.middleware.s3api.utils import sysmeta_header, \\"},{"line_number":68,"context_line":"    validate_bucket_name, Config"}],"source_content_type":"text/x-python","patch_set":23,"id":"2477d8fa_f5435d2f","line":65,"range":{"start_line":65,"start_character":45,"end_line":65,"end_character":54},"in_reply_to":"887c0680_35731b29","updated":"2024-09-22 23:56:13.000000000","message":"Yeah, probably not a bad idea!","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":true,"context_lines":[{"line_number":227,"context_line":"                self._hasher.digest() !\u003d self._expected):"},{"line_number":228,"context_line":"            self.close()"},{"line_number":229,"context_line":"            # Since we don\u0027t return the last chunk, the PUT never completes"},{"line_number":230,"context_line":"            raise S3InputChecksumMismatch(self._checksum_name)"},{"line_number":231,"context_line":"        return chunk"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def close(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"899e2432_48f6b22a","line":230,"updated":"2024-09-19 04:05:12.000000000","message":"OK so this is basically saying. If we\u0027ve read too much or read less then expected or if the checksums don\u0027t match we return an S3InputChecksumMismatch.\n\nWhat if we do a short read of over read and the checksum does match.. I guess that would be a weird collision. Maybe more likely on a crc :shrug:\nIn anycase we probably do want to raise something on a short or long read. And I guess this is what s3api would do too?","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":false,"context_lines":[{"line_number":227,"context_line":"                self._hasher.digest() !\u003d self._expected):"},{"line_number":228,"context_line":"            self.close()"},{"line_number":229,"context_line":"            # Since we don\u0027t return the last chunk, the PUT never completes"},{"line_number":230,"context_line":"            raise S3InputChecksumMismatch(self._checksum_name)"},{"line_number":231,"context_line":"        return chunk"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def close(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"1bf8c0ae_516031fb","line":230,"in_reply_to":"79452f51_2e13d4b2","updated":"2024-12-17 03:56:58.000000000","message":"Acknowledged","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3285b6566002eb2a3a7c6a7229d7e9988d53adde","unresolved":true,"context_lines":[{"line_number":227,"context_line":"                self._hasher.digest() !\u003d self._expected):"},{"line_number":228,"context_line":"            self.close()"},{"line_number":229,"context_line":"            # Since we don\u0027t return the last chunk, the PUT never completes"},{"line_number":230,"context_line":"            raise S3InputChecksumMismatch(self._checksum_name)"},{"line_number":231,"context_line":"        return chunk"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    def close(self):"}],"source_content_type":"text/x-python","patch_set":23,"id":"79452f51_2e13d4b2","line":230,"in_reply_to":"899e2432_48f6b22a","updated":"2024-09-22 23:56:13.000000000","message":"So we *should* never have a long read -- the input reader *should* keep us constrained to valid HTTP framing, which would prevent over-reads (as that\u0027d have us reading the start of the next request in the pipeline). Belt and bracers.\n\n Under-reads can happen as various layers may swallow the `IOError` that a closed connection will (should?) trip and instead return `b\u0027\u0027`, and yeah, it seemed like a checksum-mismatch was as reasonable a thing to return as anything else. I\u0027m not sure I tested what AWS does... I think I at least started to do that sort of a thing with the aws-chunked protocol, though -- and IIRC you may be right that we should be returning something else...","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":true,"context_lines":[{"line_number":989,"context_line":""},{"line_number":990,"context_line":"                if self.headers.get("},{"line_number":991,"context_line":"                        \u0027x-amz-sdk-checksum-algorithm\u0027,"},{"line_number":992,"context_line":"                        header[15:]).lower() !\u003d header[15:]:"},{"line_number":993,"context_line":"                    raise InvalidRequest(\u0027Value for x-amz-sdk-checksum-\u0027"},{"line_number":994,"context_line":"                                         \u0027algorithm header is invalid.\u0027)"},{"line_number":995,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"c8e5f8a0_56bf9da7","line":992,"updated":"2024-09-19 04:05:12.000000000","message":"So it\u0027s ok for an s3 request to have `x-amz-checksum-\u003calg\u003e: \u003cchecksum\u003e` but not have `x-amz-sdk-checksum-algorithm: \u003calg\u003e` header? which this seems to indicate.\n\nEDIT: According to the s3api tests and some example in the s3 docs, it seems this is the case. Nice.","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":false,"context_lines":[{"line_number":989,"context_line":""},{"line_number":990,"context_line":"                if self.headers.get("},{"line_number":991,"context_line":"                        \u0027x-amz-sdk-checksum-algorithm\u0027,"},{"line_number":992,"context_line":"                        header[15:]).lower() !\u003d header[15:]:"},{"line_number":993,"context_line":"                    raise InvalidRequest(\u0027Value for x-amz-sdk-checksum-\u0027"},{"line_number":994,"context_line":"                                         \u0027algorithm header is invalid.\u0027)"},{"line_number":995,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"73178936_503f2c21","line":992,"in_reply_to":"c8e5f8a0_56bf9da7","updated":"2024-12-17 03:56:58.000000000","message":"Done","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":200,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":201,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":202,"context_line":"            self._input.read(1)"},{"line_number":203,"context_line":"            # TODO: how does AWS fail?"},{"line_number":204,"context_line":"            raise InvalidRequest"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"1f563187_b0acebc3","line":203,"updated":"2024-09-27 18:59:47.000000000","message":"It seems AWS raises a  HTTP status code with a `400 Bad Request` with a SOAP fault code prefix value of *Client*. The Error code for a mismatch situation is *BadDigest* with a description as \"The Content-MD5 or checksum value that you specified did not match what the server received.\" and the error code for a checksum being invalid is an *InvalidDigest*\n\nThe InvalidRequest error in this situation looks correct to me. The error message in this scenario should be `The request is using the wrong signature version. Use AWS4-HMAC-SHA256 (Signature Version 4).` with a similar SOAP fault code prefix and a status code.\n\nI found this information on https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"73205651696a9e9239ad262ef5f8240c94a09736","unresolved":true,"context_lines":[{"line_number":200,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":201,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":202,"context_line":"            self._input.read(1)"},{"line_number":203,"context_line":"            # TODO: how does AWS fail?"},{"line_number":204,"context_line":"            raise InvalidRequest"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"fb5b1605_f3afe3cd","line":203,"in_reply_to":"1f563187_b0acebc3","updated":"2024-09-27 23:23:29.000000000","message":"Want to try your hand at writing a test for it in `test/s3api/test_input_errors.py`? If not, I\u0027ll try to get one together.","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"78b691ec3360d40dab984f7be7f106ab7bcba719","unresolved":false,"context_lines":[{"line_number":200,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":201,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":202,"context_line":"            self._input.read(1)"},{"line_number":203,"context_line":"            # TODO: how does AWS fail?"},{"line_number":204,"context_line":"            raise InvalidRequest"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"d4eea207_ce0f039a","line":203,"in_reply_to":"bb5e0fce_d2598501","updated":"2024-10-03 15:14:40.000000000","message":"Followed up in https://review.opendev.org/c/openstack/swift/+/931223","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"583eb2fec49a7293e3e76251d8582cd4e527304f","unresolved":true,"context_lines":[{"line_number":200,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":201,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":202,"context_line":"            self._input.read(1)"},{"line_number":203,"context_line":"            # TODO: how does AWS fail?"},{"line_number":204,"context_line":"            raise InvalidRequest"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"bb5e0fce_d2598501","line":203,"in_reply_to":"d18cd98f_647edbf8","updated":"2024-10-01 20:38:16.000000000","message":"This is a small diff that is worth adding to the existing tests:\n```\n@@ -1699,6 +1699,9 @@ class TestS3ApiMultiUpload(BaseS3ApiMultiUpload, S3ApiTestCase):\n         status, headers, body \u003d self.call_s3api(req)\n         self.assertEqual(\u0027400 Bad Request\u0027, status)\n         self.assertEqual(self._get_error_code(body), \u0027BadDigest\u0027)\n+        self.assertEqual(self._get_error_message(body),\n+                         \u0027The Content-Md5 you specified did \u0027\n+                         \u0027not match what we received.\u0027)\n```","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba2bb8d51cca76951e013e84c6de9660fa104020","unresolved":true,"context_lines":[{"line_number":200,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":201,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":202,"context_line":"            self._input.read(1)"},{"line_number":203,"context_line":"            # TODO: how does AWS fail?"},{"line_number":204,"context_line":"            raise InvalidRequest"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"d18cd98f_647edbf8","line":203,"in_reply_to":"dc364d22_76e7a21d","updated":"2024-10-01 20:37:34.000000000","message":"This seems like something that should be more of an addition to the existing test coverage we have that could be merged to master or added as a diff here, since it specifically involves how we handle md5 mismatch errors. I am still looking into the wrong signature version error!","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d899001525149505b545d40a138846fd2caaddf9","unresolved":true,"context_lines":[{"line_number":200,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":201,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":202,"context_line":"            self._input.read(1)"},{"line_number":203,"context_line":"            # TODO: how does AWS fail?"},{"line_number":204,"context_line":"            raise InvalidRequest"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":26,"id":"dc364d22_76e7a21d","line":203,"in_reply_to":"fb5b1605_f3afe3cd","updated":"2024-09-30 16:04:10.000000000","message":"Yes, thats what i was looking into on Fri, I will suggest a diff as soon as I am done with verifying the tests","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":true,"context_lines":[{"line_number":889,"context_line":"            self.environ[\u0027wsgi.input\u0027] \u003d HashingInput("},{"line_number":890,"context_line":"                self.environ[\u0027wsgi.input\u0027],"},{"line_number":891,"context_line":"                self.content_length,"},{"line_number":892,"context_line":"                sha256,"},{"line_number":893,"context_line":"                aws_sha256)"},{"line_number":894,"context_line":"        # If no content-length, either client\u0027s trying to do a HTTP chunked"},{"line_number":895,"context_line":"        # transfer, or a HTTP/1.0-style transfer (in which case swift will"}],"source_content_type":"text/x-python","patch_set":31,"id":"b26825d5_a67479cf","side":"PARENT","line":892,"updated":"2024-12-17 03:56:58.000000000","message":"Ahh ok so we always use sha256, so you just moved it into HashingInput.","commit_id":"d85889d88387df6a2af4595917842c556dbe2e26"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"afb4673a4c8d76af1897f8bb6b43c3daa5c75848","unresolved":true,"context_lines":[{"line_number":889,"context_line":"            self.environ[\u0027wsgi.input\u0027] \u003d HashingInput("},{"line_number":890,"context_line":"                self.environ[\u0027wsgi.input\u0027],"},{"line_number":891,"context_line":"                self.content_length,"},{"line_number":892,"context_line":"                sha256,"},{"line_number":893,"context_line":"                aws_sha256)"},{"line_number":894,"context_line":"        # If no content-length, either client\u0027s trying to do a HTTP chunked"},{"line_number":895,"context_line":"        # transfer, or a HTTP/1.0-style transfer (in which case swift will"}],"source_content_type":"text/x-python","patch_set":31,"id":"02c9c9a9_db1f63e6","side":"PARENT","line":892,"in_reply_to":"b26825d5_a67479cf","updated":"2024-12-17 20:53:26.000000000","message":"I don\u0027t remember exactly why I changed the signature of `HashingInput`... I think it was mostly just that I realized it was all very sha256-specific?","commit_id":"d85889d88387df6a2af4595917842c556dbe2e26"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":true,"context_lines":[{"line_number":984,"context_line":"                        \u0027headers were found.\u0027)"},{"line_number":985,"context_line":"            elif len(checksum_headers) \u003d\u003d 1:"},{"line_number":986,"context_line":"                header, b64digest \u003d list(checksum_headers.items())[0]"},{"line_number":987,"context_line":"                algo \u003d header[15:]"},{"line_number":988,"context_line":""},{"line_number":989,"context_line":"                if self.headers.get("},{"line_number":990,"context_line":"                        \u0027x-amz-sdk-checksum-algorithm\u0027,"}],"source_content_type":"text/x-python","patch_set":35,"id":"4c286018_7121e5a7","line":987,"updated":"2024-12-17 03:56:58.000000000","message":"Nit: I wonder if\n```\nalgo \u003d header[len(\"x-amz-checksum-\"):]\n``\n\nreads better in knowing what\u0027s happening here. But def not a blocker.","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"afb4673a4c8d76af1897f8bb6b43c3daa5c75848","unresolved":false,"context_lines":[{"line_number":984,"context_line":"                        \u0027headers were found.\u0027)"},{"line_number":985,"context_line":"            elif len(checksum_headers) \u003d\u003d 1:"},{"line_number":986,"context_line":"                header, b64digest \u003d list(checksum_headers.items())[0]"},{"line_number":987,"context_line":"                algo \u003d header[15:]"},{"line_number":988,"context_line":""},{"line_number":989,"context_line":"                if self.headers.get("},{"line_number":990,"context_line":"                        \u0027x-amz-sdk-checksum-algorithm\u0027,"}],"source_content_type":"text/x-python","patch_set":35,"id":"090307ac_094c9094","line":987,"in_reply_to":"4c286018_7121e5a7","updated":"2024-12-17 20:53:26.000000000","message":"Done","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":true,"context_lines":[{"line_number":1008,"context_line":"                old_update_footers \u003d self.environ.get("},{"line_number":1009,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1010,"context_line":"                override_hdr \u003d (\u0027x-object-sysmeta-container-update-\u0027"},{"line_number":1011,"context_line":"                                \u0027override-etag\u0027)"},{"line_number":1012,"context_line":"                if \u0027etag\u0027 not in self.headers and \\"},{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1014,"context_line":"                    # We need to track MD5 ourself, in case no one else will"}],"source_content_type":"text/x-python","patch_set":35,"id":"1d3b7034_622beeda","line":1011,"updated":"2024-12-17 03:56:58.000000000","message":"Seeing as we use sysmeta_header helper a few lines earlier, should we use it again here?\n\n```\noverride_hdr \u003d sysmeta_header(\n    \u0027object\u0027, \u0027container-update-override-etag\u0027)\n```","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"afb4673a4c8d76af1897f8bb6b43c3daa5c75848","unresolved":false,"context_lines":[{"line_number":1008,"context_line":"                old_update_footers \u003d self.environ.get("},{"line_number":1009,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1010,"context_line":"                override_hdr \u003d (\u0027x-object-sysmeta-container-update-\u0027"},{"line_number":1011,"context_line":"                                \u0027override-etag\u0027)"},{"line_number":1012,"context_line":"                if \u0027etag\u0027 not in self.headers and \\"},{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1014,"context_line":"                    # We need to track MD5 ourself, in case no one else will"}],"source_content_type":"text/x-python","patch_set":35,"id":"2136a02a_54dd081f","line":1011,"in_reply_to":"1d3b7034_622beeda","updated":"2024-12-17 20:53:26.000000000","message":"Done","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"92c0c7a8468c4d6e843688e14934ec13be96cf8f","unresolved":true,"context_lines":[{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1014,"context_line":"                    # We need to track MD5 ourself, in case no one else will"},{"line_number":1015,"context_line":"                    etag_input \u003d self.environ[\u0027wsgi.input\u0027] \u003d MD5Input("},{"line_number":1016,"context_line":"                        self.environ[\u0027wsgi.input\u0027])"},{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"                def update_for_checksum(footers):"},{"line_number":1019,"context_line":"                    if old_update_footers:"}],"source_content_type":"text/x-python","patch_set":35,"id":"8bce1982_5e815856","line":1016,"updated":"2024-12-17 03:56:58.000000000","message":"So in this case, we could have: `wsgi.input \u003d MD5Input(ChecksummingInput(self.environ[\u0027wsgi.input\u0027]))`\n\nThanks a bunch of chaining, but also pretty cool that we can do it 😊","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"afb4673a4c8d76af1897f8bb6b43c3daa5c75848","unresolved":true,"context_lines":[{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1014,"context_line":"                    # We need to track MD5 ourself, in case no one else will"},{"line_number":1015,"context_line":"                    etag_input \u003d self.environ[\u0027wsgi.input\u0027] \u003d MD5Input("},{"line_number":1016,"context_line":"                        self.environ[\u0027wsgi.input\u0027])"},{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"                def update_for_checksum(footers):"},{"line_number":1019,"context_line":"                    if old_update_footers:"}],"source_content_type":"text/x-python","patch_set":35,"id":"e33ea338_aaac661a","line":1016,"in_reply_to":"8bce1982_5e815856","updated":"2024-12-17 20:53:26.000000000","message":"Yup, and you can also get a `HashingInput` in the mix, too 😵‍💫","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b783a9c86b566e5d7fb1c31e406d9675ecfdb07f","unresolved":false,"context_lines":[{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1014,"context_line":"                    # We need to track MD5 ourself, in case no one else will"},{"line_number":1015,"context_line":"                    etag_input \u003d self.environ[\u0027wsgi.input\u0027] \u003d MD5Input("},{"line_number":1016,"context_line":"                        self.environ[\u0027wsgi.input\u0027])"},{"line_number":1017,"context_line":""},{"line_number":1018,"context_line":"                def update_for_checksum(footers):"},{"line_number":1019,"context_line":"                    if old_update_footers:"}],"source_content_type":"text/x-python","patch_set":35,"id":"7aa30749_214f5a9e","line":1016,"in_reply_to":"e33ea338_aaac661a","updated":"2024-12-17 22:27:41.000000000","message":"Acknowledged","commit_id":"bca4eb0cfb9ca90db7133999851c397514c4352d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"848d73aa236591e0539d7fd8aab6d72494bd5047","unresolved":true,"context_lines":[{"line_number":1007,"context_line":"                # if the client didn\u0027t send it, so we\u0027re using footers."},{"line_number":1008,"context_line":"                old_update_footers \u003d self.environ.get("},{"line_number":1009,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1010,"context_line":"                override_hdr \u003d sysmeta_header("},{"line_number":1011,"context_line":"                    \u0027object\u0027, \u0027container-update-override-etag\u0027)"},{"line_number":1012,"context_line":"                if \u0027etag\u0027 not in self.headers and \\"},{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"}],"source_content_type":"text/x-python","patch_set":36,"id":"3c54d973_011bed53","line":1010,"range":{"start_line":1010,"start_character":31,"end_line":1010,"end_character":45},"updated":"2024-12-17 23:10:25.000000000","message":"Ha! Wrong `sysmeta_header`!","commit_id":"1fa4a325fb17f5bc3f90f7068c499528d9202660"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"a82ccc921ecae5ca02f0e20f426d1cdeb8f11c6c","unresolved":true,"context_lines":[{"line_number":1008,"context_line":"                old_update_footers \u003d self.environ.get("},{"line_number":1009,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1010,"context_line":"                override_hdr \u003d get_sys_meta_prefix(\u0027object\u0027) + \\"},{"line_number":1011,"context_line":"                               \u0027container-update-override-etag\u0027"},{"line_number":1012,"context_line":"                if \u0027etag\u0027 not in self.headers and \\"},{"line_number":1013,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1014,"context_line":"                    # We need to track MD5 ourself, in case no one else will"}],"source_content_type":"text/x-python","patch_set":37,"id":"961ee1fd_7fc3b39b","line":1011,"in_reply_to":"47457af4_e9ae95f5","updated":"2024-12-18 00:28:24.000000000","message":"\u003e pep8: E127 continuation line over-indented for visual indent\n\nPlease fix.","commit_id":"b950315b6ef97ecba10f29ee92f894efeb2fc8eb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":158,"context_line":"        close_if_possible(self._input)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"class MD5Input(object):"},{"line_number":162,"context_line":"    \"\"\""},{"line_number":163,"context_line":"    wsgi.input wrapper to calculate the MD5 of the input as it\u0027s read."},{"line_number":164,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":40,"id":"f94f0dc7_ebc57dff","line":161,"updated":"2025-01-20 18:48:15.000000000","message":"1. this class is sandwiched between two other *Input classes but has a different behaviour i.e. it does not check the hash at the end of the stream. If that is deliberate, perhaps it could be relocated and maybe the class names somehow differentiated?\n\n2. we already have utils.InputProxy https://github.com/openstack/swift/blob/ae6300af86c292b4ded1b4606f7e978bf7474f8a/swift/common/utils/__init__.py#L2514 which could be modified to have an optional etag hasher (see comment below about putting the etag hasher in the environ, which means decoupling it from the input stream)\n\n3. utils.InputProxy has a readline() method, this doesn\u0027t, wsgi says it should https://peps.python.org/pep-3333/#input-and-error-streams :shrug:","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":158,"context_line":"        close_if_possible(self._input)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"class MD5Input(object):"},{"line_number":162,"context_line":"    \"\"\""},{"line_number":163,"context_line":"    wsgi.input wrapper to calculate the MD5 of the input as it\u0027s read."},{"line_number":164,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":40,"id":"ead825b3_f157d03a","line":161,"in_reply_to":"f94f0dc7_ebc57dff","updated":"2025-02-21 15:31:58.000000000","message":"ok, we\u0027re getting lined up to refactor now this is based on https://review.opendev.org/c/openstack/swift/+/940059/\n\nsee https://review.opendev.org/c/openstack/swift/+/942464","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c2bfd41ba3c15d6129e132fb1c63267ecc27da92","unresolved":true,"context_lines":[{"line_number":188,"context_line":"        self._input \u003d reader"},{"line_number":189,"context_line":"        self._to_read \u003d content_length"},{"line_number":190,"context_line":"        self._checksum_header \u003d checksum_header"},{"line_number":191,"context_line":"        self._checksum_name \u003d checksum_header[len(\u0027x-amz-checksum-\u0027):].lower()"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":"        if self._checksum_name not in checksum_to_hasher:"},{"line_number":194,"context_line":"            # boto3 (at least) can get into framing issues if we"}],"source_content_type":"text/x-python","patch_set":40,"id":"bf26a0b9_00ebd1da","line":191,"updated":"2025-01-22 14:46:27.000000000","message":"why repeat parsing the header - this was done right before constructing the ``ChecksummingInput``, so  the parsed ``algo`` could just be passed in. AFAICT ``self._checksum_header`` is not used.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":232,"context_line":"        return chunk"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def close(self):"},{"line_number":235,"context_line":"        close_if_possible(self._input)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"class SigV4Mixin(object):"}],"source_content_type":"text/x-python","patch_set":40,"id":"2d4ca0b4_b151765c","line":235,"updated":"2025-01-20 18:48:15.000000000","message":"at a glance I suspect these classes could share some common input proxy code and customise the hasher","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"26d75f52808364f142a1b55d059c40cd9a2ccf2e","unresolved":true,"context_lines":[{"line_number":232,"context_line":"        return chunk"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def close(self):"},{"line_number":235,"context_line":"        close_if_possible(self._input)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"class SigV4Mixin(object):"}],"source_content_type":"text/x-python","patch_set":40,"id":"5a7e2e47_2976aeff","line":235,"in_reply_to":"2d4ca0b4_b151765c","updated":"2025-01-23 17:03:44.000000000","message":"tried some refactoring here to provide a more re-usable InputProxy https://review.opendev.org/c/openstack/swift/+/940059","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":232,"context_line":"        return chunk"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def close(self):"},{"line_number":235,"context_line":"        close_if_possible(self._input)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"class SigV4Mixin(object):"}],"source_content_type":"text/x-python","patch_set":40,"id":"e5b9db7b_36049324","line":235,"in_reply_to":"5a7e2e47_2976aeff","updated":"2025-02-21 15:31:58.000000000","message":"we would try out some refactor now this is based on https://review.opendev.org/c/openstack/swift/+/940059\n\nsee https://review.opendev.org/c/openstack/swift/+/942464","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":false,"context_lines":[{"line_number":232,"context_line":"        return chunk"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def close(self):"},{"line_number":235,"context_line":"        close_if_possible(self._input)"},{"line_number":236,"context_line":""},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"class SigV4Mixin(object):"}],"source_content_type":"text/x-python","patch_set":40,"id":"b7aa8219_0aa72cfa","line":235,"in_reply_to":"e5b9db7b_36049324","updated":"2025-02-28 17:57:13.000000000","message":"Done","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c2bfd41ba3c15d6129e132fb1c63267ecc27da92","unresolved":true,"context_lines":[{"line_number":986,"context_line":"                        \u0027headers were found.\u0027)"},{"line_number":987,"context_line":"            elif len(checksum_headers) \u003d\u003d 1:"},{"line_number":988,"context_line":"                header, b64digest \u003d list(checksum_headers.items())[0]"},{"line_number":989,"context_line":"                algo \u003d header[len(\u0027x-amz-checksum-\u0027):]"},{"line_number":990,"context_line":""},{"line_number":991,"context_line":"                if self.headers.get("},{"line_number":992,"context_line":"                        \u0027x-amz-sdk-checksum-algorithm\u0027,"}],"source_content_type":"text/x-python","patch_set":40,"id":"82eca2e3_a1fde36d","line":989,"range":{"start_line":989,"start_character":16,"end_line":989,"end_character":20},"updated":"2025-01-22 14:46:27.000000000","message":"elsewhere this is referred to as \u0027checksum_name\u0027 - consistent naming would help track what\u0027s what.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":1001,"context_line":"                    b64digest,"},{"line_number":1002,"context_line":"                )"},{"line_number":1003,"context_line":"                self.headers[sysmeta_header("},{"line_number":1004,"context_line":"                    \u0027object\u0027, \u0027checksum-\u0027 + algo)] \u003d b64digest"},{"line_number":1005,"context_line":""},{"line_number":1006,"context_line":"                # Also get this into the container listing. Since it\u0027s a"},{"line_number":1007,"context_line":"                # property of the body itself, hang it off the etag in the"}],"source_content_type":"text/x-python","patch_set":40,"id":"80ea90b8_06f1daec","line":1004,"updated":"2025-01-20 18:48:15.000000000","message":"IIUC the same info is going in the container-update-override-etag sysmeta - do we need it in both places?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":1001,"context_line":"                    b64digest,"},{"line_number":1002,"context_line":"                )"},{"line_number":1003,"context_line":"                self.headers[sysmeta_header("},{"line_number":1004,"context_line":"                    \u0027object\u0027, \u0027checksum-\u0027 + algo)] \u003d b64digest"},{"line_number":1005,"context_line":""},{"line_number":1006,"context_line":"                # Also get this into the container listing. Since it\u0027s a"},{"line_number":1007,"context_line":"                # property of the body itself, hang it off the etag in the"}],"source_content_type":"text/x-python","patch_set":40,"id":"8bc3a901_97721f28","line":1004,"in_reply_to":"80ea90b8_06f1daec","updated":"2025-01-25 04:33:47.000000000","message":"I don\u0027t want the object GET/HEAD path picking out values from `x-object-sysmeta-container-update-override-etag` to return in client-facing headers -- doesn\u0027t seem like good separation of concerns. It\u0027s similar to how we\u0027ve got `swift_bytes` going into `Content-Type`, but then also write down `x-object-sysmeta-slo-size`.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":1015,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1016,"context_line":"                    # We need to track MD5 ourself, in case no one else will"},{"line_number":1017,"context_line":"                    etag_input \u003d self.environ[\u0027wsgi.input\u0027] \u003d MD5Input("},{"line_number":1018,"context_line":"                        self.environ[\u0027wsgi.input\u0027])"},{"line_number":1019,"context_line":""},{"line_number":1020,"context_line":"                def update_for_checksum(footers):"},{"line_number":1021,"context_line":"                    if old_update_footers:"}],"source_content_type":"text/x-python","patch_set":40,"id":"fc11c4a7_c1c45ca5","line":1018,"updated":"2025-01-20 18:48:15.000000000","message":"this is unfortunate because for EC policies we already calculate the md5 in the proxy PUT path https://github.com/openstack/swift/blob/128124cdd8ca09136d4988affd1bb8c5c1361fc1/swift/proxy/controllers/obj.py#L3343-L3347 so now we may do it twice\n\nMaybe we could put the etag hasher in the req.environ so that the proxy can find it and use its result instead of using another etag hasher?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8de3d1e200b5a458ff19f0c81936a726cc36a88b","unresolved":true,"context_lines":[{"line_number":1032,"context_line":"                    else:"},{"line_number":1033,"context_line":"                        base \u003d etag_input.hexdigest()"},{"line_number":1034,"context_line":"                    footers[override_hdr] \u003d base + \u0027; %s\u003d%s\u0027 % ("},{"line_number":1035,"context_line":"                        checksum_to_listing_param[algo], b64digest)"},{"line_number":1036,"context_line":""},{"line_number":1037,"context_line":"                self.environ[\u0027swift.callback.update_footers\u0027] \u003d \\"},{"line_number":1038,"context_line":"                    update_for_checksum"}],"source_content_type":"text/x-python","patch_set":40,"id":"f825a052_dd9ac9e3","line":1035,"range":{"start_line":1035,"start_character":57,"end_line":1035,"end_character":66},"updated":"2025-01-21 17:10:46.000000000","message":"AFAICT we don\u0027t return the digest in  listings, so could we just add the algo as a param to content-type and avoid all the footers etag override stuff?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"26d75f52808364f142a1b55d059c40cd9a2ccf2e","unresolved":true,"context_lines":[{"line_number":1032,"context_line":"                    else:"},{"line_number":1033,"context_line":"                        base \u003d etag_input.hexdigest()"},{"line_number":1034,"context_line":"                    footers[override_hdr] \u003d base + \u0027; %s\u003d%s\u0027 % ("},{"line_number":1035,"context_line":"                        checksum_to_listing_param[algo], b64digest)"},{"line_number":1036,"context_line":""},{"line_number":1037,"context_line":"                self.environ[\u0027swift.callback.update_footers\u0027] \u003d \\"},{"line_number":1038,"context_line":"                    update_for_checksum"}],"source_content_type":"text/x-python","patch_set":40,"id":"1cdc946d_679b3783","line":1035,"range":{"start_line":1035,"start_character":57,"end_line":1035,"end_character":66},"in_reply_to":"f825a052_dd9ac9e3","updated":"2025-01-23 17:03:44.000000000","message":"scratch that - content-type is mutable in the container metadata","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":1041,"context_line":"                self.environ[\u0027wsgi.input\u0027].read(1)"},{"line_number":1042,"context_line":"                raise InvalidRequest("},{"line_number":1043,"context_line":"                    \u0027Expecting a single x-amz-checksum- header. \u0027"},{"line_number":1044,"context_line":"                    \u0027Multiple checksum Types are not allowed.\u0027)"},{"line_number":1045,"context_line":""},{"line_number":1046,"context_line":"        # https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html"},{"line_number":1047,"context_line":"        # describes some of what would be required to support this"}],"source_content_type":"text/x-python","patch_set":40,"id":"aec37475_b709cdda","line":1044,"updated":"2025-01-20 18:48:15.000000000","message":"this feels like a lot more than the scope I\u0027d expect for the ``_validate_headers`` method, which is already quite long. Perhaps ``_validate_headers`` could extract the single expected checksum and a separate ``_install_hashers`` method deal with the wsgi input?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":1053,"context_line":"                                   \u0027using aws-chunked is not supported.\u0027)"},{"line_number":1054,"context_line":""},{"line_number":1055,"context_line":"        if \u0027x-amz-trailer\u0027 in self.headers:"},{"line_number":1056,"context_line":"            raise S3NotImplemented(\u0027x-amz-trailer is not supported.\u0027)"},{"line_number":1057,"context_line":""},{"line_number":1058,"context_line":"        if \u0027x-amz-tagging\u0027 in self.headers:"},{"line_number":1059,"context_line":"            raise S3NotImplemented(\u0027Object tagging is not supported.\u0027)"}],"source_content_type":"text/x-python","patch_set":40,"id":"28d72ec5_1ad4c7f6","line":1056,"updated":"2025-01-20 18:48:15.000000000","message":"is this a drive-by ? I removed these lines and didn\u0027t see any test fail in test/unit/common/middleware/s3api","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"26d75f52808364f142a1b55d059c40cd9a2ccf2e","unresolved":true,"context_lines":[{"line_number":1006,"context_line":"                # Also get this into the container listing. Since it\u0027s a"},{"line_number":1007,"context_line":"                # property of the body itself, hang it off the etag in the"},{"line_number":1008,"context_line":"                # listing. That also means we need to *have* the etag, even"},{"line_number":1009,"context_line":"                # if the client didn\u0027t send it, so we\u0027re using footers."},{"line_number":1010,"context_line":"                old_update_footers \u003d self.environ.get("},{"line_number":1011,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1012,"context_line":"                override_hdr \u003d get_sys_meta_prefix(\u0027object\u0027) + \\"}],"source_content_type":"text/x-python","patch_set":41,"id":"693c5a8d_4d420ca0","line":1009,"updated":"2025-01-23 17:03:44.000000000","message":"AFAIK this is the first time we\u0027ve overridden etag in *footers* to the left of other middlewares that override etag in headers (e.g. slo, symlink and formative mpu) which makes me wonder if this breaks those other middlewares:\n\n* rightwards-middleware sets override etag header with \u003cetag\u003e; x\u003dy\n* swift.callback.update_footers is called from rightmost proxy app\n* s3api sets override etag footer with  \u003cetag\u003e; algo\u003ddigest\n\nMaybe we get away with it because s3api only uses slo on a POST to s3api, and a versioning symlink gets its etag from the version PUT response.\n\nCome to think of it, when a version is PUT to the versions container, what etag/override etag goes to the symlink and thus the user container listing?\n\nAnyway, it seems like it\u0027s a bug waiting to happen to have middlewares variously annotating the etag in headers and in footers. I\u0027m thinking we should introduce a reference implementation to handle the pattern that is here and also in encrypter, then apply it everywhere we do etag overrides.","commit_id":"9fb91818710ded3d1f501a00ba5037511eafd703"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":202,"context_line":"            # TODO: how does AWS fail?"},{"line_number":203,"context_line":"            raise InvalidRequest"},{"line_number":204,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"},{"line_number":205,"context_line":"        self.expect(expected_checksum)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    def expect(self, expected_checksum):"},{"line_number":208,"context_line":"        if expected_checksum is None:"}],"source_content_type":"text/x-python","patch_set":45,"id":"21d08542_5818dd10","line":205,"updated":"2025-02-21 15:31:58.000000000","message":"I find it easier to track instance attributes when they are set in the constructor, so perhaps this could be\n\n```\nself._expected \u003d self.expect(expected_checksum)\n```\n\nbut, IF the header is validated earlier then we probably don\u0027t need self._expected, it can just be decoded from self._expected_b64 when checked in read()??","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":209,"context_line":"            self._expected \u003d None"},{"line_number":210,"context_line":"            return"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"        # XXX: seems like this should maybe happen in _validate_headers?"},{"line_number":213,"context_line":"        try:"},{"line_number":214,"context_line":"            self._expected \u003d strict_b64decode(expected_checksum)"},{"line_number":215,"context_line":"            reencoded \u003d base64.b64encode(self._expected).decode(\u0027ascii\u0027)"}],"source_content_type":"text/x-python","patch_set":45,"id":"d144c066_2f18c7ca","line":212,"updated":"2025-02-21 15:31:58.000000000","message":"but we may also have to validate a trailer.\n\nMaybe there could be a helper validator function that returns _expected (see comment in __init__) - so validate the header *earlier* if present, or validate the trailer here\n\ndo we have anywhere else that checks for valid b64?","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1744676461190ea90cc329c3da41e2e272ab152b","unresolved":true,"context_lines":[{"line_number":209,"context_line":"            self._expected \u003d None"},{"line_number":210,"context_line":"            return"},{"line_number":211,"context_line":""},{"line_number":212,"context_line":"        # XXX: seems like this should maybe happen in _validate_headers?"},{"line_number":213,"context_line":"        try:"},{"line_number":214,"context_line":"            self._expected \u003d strict_b64decode(expected_checksum)"},{"line_number":215,"context_line":"            reencoded \u003d base64.b64encode(self._expected).decode(\u0027ascii\u0027)"}],"source_content_type":"text/x-python","patch_set":45,"id":"a94b179d_11dc6b1d","line":212,"in_reply_to":"d144c066_2f18c7ca","updated":"2025-03-13 04:17:25.000000000","message":"\u003e do we have anywhere else that checks for valid b64?\n\nI wonder if `strict_b64decode` needs to get a little stricter -- maybe gated off an optional `expected_length` arg.","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":221,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":222,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":223,"context_line":"            self._input.read(1)"},{"line_number":224,"context_line":"            raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":225,"context_line":"                                 self.checksum_info.client_header)"},{"line_number":226,"context_line":"        self._expected_b64 \u003d expected_checksum"},{"line_number":227,"context_line":""}],"source_content_type":"text/x-python","patch_set":45,"id":"074f266e_f1665931","line":224,"range":{"start_line":224,"start_character":12,"end_line":224,"end_character":32},"updated":"2025-02-21 15:31:58.000000000","message":"if this is raised while validating a trailer don\u0027t we need it be be an S3InputError (similar to how we needed S3InputMissingSecret)?\n\nif so, that\u0027s another argument for having a simple validation helper function that raises ValueError, and validating the header earlier to raise InvalidRequest, then validating the trailer here to raise an S3InputError.","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1744676461190ea90cc329c3da41e2e272ab152b","unresolved":true,"context_lines":[{"line_number":221,"context_line":"            # boto3 (at least) can get into framing issues if we"},{"line_number":222,"context_line":"            # haven\u0027t sent a 100 Continue"},{"line_number":223,"context_line":"            self._input.read(1)"},{"line_number":224,"context_line":"            raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":225,"context_line":"                                 self.checksum_info.client_header)"},{"line_number":226,"context_line":"        self._expected_b64 \u003d expected_checksum"},{"line_number":227,"context_line":""}],"source_content_type":"text/x-python","patch_set":45,"id":"6f0d4658_85d5f2b3","line":224,"range":{"start_line":224,"start_character":12,"end_line":224,"end_character":32},"in_reply_to":"074f266e_f1665931","updated":"2025-03-13 04:17:25.000000000","message":"Yup, good call. Clearly another cross-compat test needs to be written.\n\nEep! And the `read(1)` could be particularly dangerous when dealing with trailers!","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":223,"context_line":"            self._input.read(1)"},{"line_number":224,"context_line":"            raise InvalidRequest(\u0027Value for %s header is invalid.\u0027 %"},{"line_number":225,"context_line":"                                 self.checksum_info.client_header)"},{"line_number":226,"context_line":"        self._expected_b64 \u003d expected_checksum"},{"line_number":227,"context_line":""},{"line_number":228,"context_line":"    def read(self, size\u003dNone):"},{"line_number":229,"context_line":"        chunk \u003d self._input.read(size)"}],"source_content_type":"text/x-python","patch_set":45,"id":"9f10fdcd_5c86b140","line":226,"range":{"start_line":226,"start_character":8,"end_line":226,"end_character":26},"updated":"2025-02-21 15:31:58.000000000","message":"this ought to be a public attribute\n\nAlso, while it is helpful to have a reminder of which version is b64 or not, I\u0027d prefer to have ``expected_checksum`` used consistently for the same thing. Or use ``expected_b64_checksum`` throughout the module?","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":231,"context_line":"        self._to_read -\u003d len(chunk)"},{"line_number":232,"context_line":"        short_read \u003d bool(chunk) if size is None else (len(chunk) \u003c size)"},{"line_number":233,"context_line":"        if self._to_read \u003d\u003d 0 and self._expected is None:"},{"line_number":234,"context_line":"            self.expect(self._input.trailers[self.checksum_info.client_header])"},{"line_number":235,"context_line":"        if self._to_read \u003c 0 or (short_read and self._to_read) or ("},{"line_number":236,"context_line":"                self._to_read \u003d\u003d 0 and"},{"line_number":237,"context_line":"                self._hasher.digest() !\u003d self._expected):"}],"source_content_type":"text/x-python","patch_set":45,"id":"10869dc9_7757fbd7","line":234,"range":{"start_line":234,"start_character":44,"end_line":234,"end_character":78},"updated":"2025-02-21 15:31:58.000000000","message":"what do we want to happen if the trailer isn\u0027t present? this is going to KeyError...","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1067,"context_line":"        self._validate_headers()"},{"line_number":1068,"context_line":"        self.sig_checker \u003d self.sig_checker_cls(self)"},{"line_number":1069,"context_line":"        self._install_input_wrapper()"},{"line_number":1070,"context_line":"        self._install_checksumming_input_wrapper()"},{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        # Lock in string-to-sign now, before we start messing with query params"},{"line_number":1073,"context_line":"        self.environ[\u0027s3api.auth_details\u0027] \u003d {"}],"source_content_type":"text/x-python","patch_set":45,"id":"0c5a5923_f4e8e89e","line":1070,"updated":"2025-02-21 15:31:58.000000000","message":"is this deliberately being attempted for v2 requests? I moved this to the end of SigV4Mixin._install_input_wrapper() and no unit tests broke\n\nupdate: ok, so cross-compat tests do fail if I move this to be v4 specific","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1396,"context_line":"        # MissingContentLength)"},{"line_number":1397,"context_line":""},{"line_number":1398,"context_line":"    def _install_checksumming_input_wrapper(self):"},{"line_number":1399,"context_line":"        if self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1400,"context_line":"            checksum_headers \u003d {"},{"line_number":1401,"context_line":"                h.lower(): v"},{"line_number":1402,"context_line":"                for h, v in self.headers.items()"}],"source_content_type":"text/x-python","patch_set":45,"id":"ced50848_50f35f71","line":1399,"updated":"2025-02-21 15:31:58.000000000","message":"could return early if not PUT and dedent the rest of the method","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":false,"context_lines":[{"line_number":1396,"context_line":"        # MissingContentLength)"},{"line_number":1397,"context_line":""},{"line_number":1398,"context_line":"    def _install_checksumming_input_wrapper(self):"},{"line_number":1399,"context_line":"        if self.method \u003d\u003d \u0027PUT\u0027:"},{"line_number":1400,"context_line":"            checksum_headers \u003d {"},{"line_number":1401,"context_line":"                h.lower(): v"},{"line_number":1402,"context_line":"                for h, v in self.headers.items()"}],"source_content_type":"text/x-python","patch_set":45,"id":"0561a469_e893ee40","line":1399,"in_reply_to":"ced50848_50f35f71","updated":"2025-02-28 17:57:13.000000000","message":"Done","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1407,"context_line":"                    for h in list_from_csv(self.headers.get(\u0027x-amz-trailer\u0027))"},{"line_number":1408,"context_line":"                    if h.lower().startswith(\u0027x-amz-checksum-\u0027)}"},{"line_number":1409,"context_line":"            if not checksum_headers:"},{"line_number":1410,"context_line":"                if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"},{"line_number":1411,"context_line":"                    raise InvalidRequest("},{"line_number":1412,"context_line":"                        \u0027x-amz-sdk-checksum-algorithm specified, but no \u0027"},{"line_number":1413,"context_line":"                        \u0027corresponding x-amz-checksum-* or x-amz-trailer \u0027"}],"source_content_type":"text/x-python","patch_set":45,"id":"be194cec_98a56c00","line":1410,"updated":"2025-02-21 15:31:58.000000000","message":"no need to read the single byte here?","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1439,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1440,"context_line":"                override_hdr \u003d get_sys_meta_prefix(\u0027object\u0027) + \\"},{"line_number":1441,"context_line":"                    \u0027container-update-override-etag\u0027"},{"line_number":1442,"context_line":"                checksum_input \u003d self.environ[\u0027wsgi.input\u0027]"},{"line_number":1443,"context_line":"                if \u0027etag\u0027 not in self.headers and \\"},{"line_number":1444,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1445,"context_line":"                    # We need to track MD5 ourself, in case no one else will"}],"source_content_type":"text/x-python","patch_set":45,"id":"f65cc8f7_0ebd0e67","line":1442,"range":{"start_line":1442,"start_character":16,"end_line":1442,"end_character":30},"updated":"2025-02-21 15:31:58.000000000","message":"nit: define the var at line 1425 before setting into req.environ","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":false,"context_lines":[{"line_number":1439,"context_line":"                    \u0027swift.callback.update_footers\u0027)"},{"line_number":1440,"context_line":"                override_hdr \u003d get_sys_meta_prefix(\u0027object\u0027) + \\"},{"line_number":1441,"context_line":"                    \u0027container-update-override-etag\u0027"},{"line_number":1442,"context_line":"                checksum_input \u003d self.environ[\u0027wsgi.input\u0027]"},{"line_number":1443,"context_line":"                if \u0027etag\u0027 not in self.headers and \\"},{"line_number":1444,"context_line":"                        override_hdr not in self.headers:"},{"line_number":1445,"context_line":"                    # We need to track MD5 ourself, in case no one else will"}],"source_content_type":"text/x-python","patch_set":45,"id":"ba100086_2308bd10","line":1442,"range":{"start_line":1442,"start_character":16,"end_line":1442,"end_character":30},"in_reply_to":"f65cc8f7_0ebd0e67","updated":"2025-02-28 17:57:13.000000000","message":"Done","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1448,"context_line":""},{"line_number":1449,"context_line":"                def update_for_checksum(footers):"},{"line_number":1450,"context_line":"                    if old_update_footers:"},{"line_number":1451,"context_line":"                        old_update_footers(footers)"},{"line_number":1452,"context_line":""},{"line_number":1453,"context_line":"                    if override_hdr in footers:"},{"line_number":1454,"context_line":"                        base \u003d footers[override_hdr]"}],"source_content_type":"text/x-python","patch_set":45,"id":"b107e292_d2b615e0","line":1451,"updated":"2025-02-21 15:31:58.000000000","message":"I\u0027m trying to encapsulate the etag override/footers business in this patch https://review.opendev.org/c/openstack/swift/+/940803/4/swift/common/request_helpers.py\n\nI\u0027ll volunteer to see how those proposed helpers work out with this use case.","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1463,"context_line":""},{"line_number":1464,"context_line":"                    footers[override_hdr] \u003d base + \u0027; %s\u003d%s\u0027 % ("},{"line_number":1465,"context_line":"                        checksum_info.listing_param_name,"},{"line_number":1466,"context_line":"                        checksum_input._expected_b64)"},{"line_number":1467,"context_line":"                    if not b64digest:"},{"line_number":1468,"context_line":"                        footers[checksum_info.sysmeta_header] \u003d \\"},{"line_number":1469,"context_line":"                            checksum_input._expected_b64"}],"source_content_type":"text/x-python","patch_set":45,"id":"f2c01e17_e800874f","line":1466,"updated":"2025-02-21 15:31:58.000000000","message":"in setting this footer, any etag override params previously set on a header are lost\n\nI\u0027m trying to fix that in this patch https://review.opendev.org/c/openstack/swift/+/940165/6","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84606f39effc9575a74995872f280fd697c503bd","unresolved":true,"context_lines":[{"line_number":1470,"context_line":""},{"line_number":1471,"context_line":"                self.environ[\u0027swift.callback.update_footers\u0027] \u003d \\"},{"line_number":1472,"context_line":"                    update_for_checksum"},{"line_number":1473,"context_line":"            else:"},{"line_number":1474,"context_line":"                # Ensure we\u0027ve sent 100 Continue"},{"line_number":1475,"context_line":"                self.environ[\u0027wsgi.input\u0027].read(1)"},{"line_number":1476,"context_line":"                if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"}],"source_content_type":"text/x-python","patch_set":45,"id":"bc22ebd1_85dbf0dd","line":1473,"updated":"2025-02-21 15:31:58.000000000","message":"we could dedent the long elif happy path clause by putting this clause ahead of it\n\n```\nif not checksum_headers:\n    raise ...\n\nif len(checksum_headers) \u003e 1:\n    raise...\n    \nhappy path\n``","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":false,"context_lines":[{"line_number":1470,"context_line":""},{"line_number":1471,"context_line":"                self.environ[\u0027swift.callback.update_footers\u0027] \u003d \\"},{"line_number":1472,"context_line":"                    update_for_checksum"},{"line_number":1473,"context_line":"            else:"},{"line_number":1474,"context_line":"                # Ensure we\u0027ve sent 100 Continue"},{"line_number":1475,"context_line":"                self.environ[\u0027wsgi.input\u0027].read(1)"},{"line_number":1476,"context_line":"                if self.headers.get(\u0027x-amz-sdk-checksum-algorithm\u0027):"}],"source_content_type":"text/x-python","patch_set":45,"id":"a9698627_30423b9e","line":1473,"in_reply_to":"bc22ebd1_85dbf0dd","updated":"2025-02-28 17:57:13.000000000","message":"Done","commit_id":"66103a90deb743faa73d0bff2177f8494b05b1e6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":true,"context_lines":[{"line_number":226,"context_line":"            error \u003d eof"},{"line_number":227,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":228,"context_line":"            if self.expected_checksum is None:"},{"line_number":229,"context_line":"                self.expected_checksum \u003d self.wsgi_input.trailers.get("},{"line_number":230,"context_line":"                    self.checksum_info.client_header)"},{"line_number":231,"context_line":"                self.expected_checksum \u003d self.expect(self.expected_checksum)"},{"line_number":232,"context_line":"            actual \u003d base64.b64encode(self._hasher.digest()).decode(\u0027ascii\u0027)"}],"source_content_type":"text/x-python","patch_set":46,"id":"bce18a8a_31873ffe","line":229,"updated":"2025-02-28 17:57:13.000000000","message":"I don\u0027t like how ChecksummingInput is used to wrap both a StreamingInput (that has a trailers attribute) and a HashingInput (no trailers) and it\u0027s left to implicit header combination to avoid getting to this line in the latter case...except it\u0027s quite easy to get here and blow up with a Hashing Input:\n\n```\ndiff --git a/test/s3api/test_input_errors.py b/test/s3api/test_input_errors.py\nindex 9716bced5..46946dfcd 100644\n--- a/test/s3api/test_input_errors.py\n+++ b/test/s3api/test_input_errors.py\n@@ -819,7 +819,8 @@ class InputErrorsMixin(object):\n             headers\u003d{\n                 \u0027content-md5\u0027: _md5(TEST_BODY),\n                 \u0027x-amz-content-sha256\u0027: _sha256(TEST_BODY),\n-                \u0027x-amz-checksum-crc32\u0027: _crc32(TEST_BODY),\n+                # \u0027x-amz-checksum-crc32\u0027: _crc32(TEST_BODY),\n+                \u0027x-amz-trailer\u0027: \u0027x-amz-checksum-crc32\u0027\n             })\n         self.assertOK(resp)\n```\n\nI think we should try to make the valid execution paths explicit, or at least as a workaround:\n- have HashingInput provide an (empty dict) trailers attribute.\n- or have both input wrappers provide an expected_checksum attribute\n\nThe problem with those workarounds is that I think we\u0027d end up with the wrong error type. With that diff, S3 returns a 400 with:\n\n\"\u003cError\u003e\u003cCode\u003eMalformedTrailerError\u003c/Code\u003e\u003cMessage\u003eThe request contained trailing data that was not well-formed or did not conform to our published schema....\"\n\nrather than \"InputChecksumMismatch\". (V2 and V4 header auth). It suggests it is trying to read a trailer ??? or maybe just translating the bad header combination to that error?","commit_id":"aa1d677caa779d3a6a90889606e409ad7bdee462"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1744676461190ea90cc329c3da41e2e272ab152b","unresolved":true,"context_lines":[{"line_number":226,"context_line":"            error \u003d eof"},{"line_number":227,"context_line":"        elif self.bytes_received \u003d\u003d self._expected_length:"},{"line_number":228,"context_line":"            if self.expected_checksum is None:"},{"line_number":229,"context_line":"                self.expected_checksum \u003d self.wsgi_input.trailers.get("},{"line_number":230,"context_line":"                    self.checksum_info.client_header)"},{"line_number":231,"context_line":"                self.expected_checksum \u003d self.expect(self.expected_checksum)"},{"line_number":232,"context_line":"            actual \u003d base64.b64encode(self._hasher.digest()).decode(\u0027ascii\u0027)"}],"source_content_type":"text/x-python","patch_set":46,"id":"b276c741_eafdfa0d","line":229,"in_reply_to":"bce18a8a_31873ffe","updated":"2025-03-13 04:17:25.000000000","message":"Funny -- yeah, I kinda would\u0027ve expected AWS to do something like it does in `test_strm_unsgnd_pyld_trl_multiple_trailers` for that case:\n```\n        self.assertEqual(resp.status_code, 400, resp.content)\n        self.assertIn(b\u0027\u003cCode\u003eInvalidRequest\u003c/Code\u003e\u0027, resp.content)\n        self.assertIn(b\u0027\u003cMessage\u003eThe value specified in the x-amz-trailer \u0027\n                      b\u0027header is not supported\u003c/Message\u003e\u0027,\n                      resp.content)\n```","commit_id":"aa1d677caa779d3a6a90889606e409ad7bdee462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f874d368f0199912d2fcab0fbd592feddf25765d","unresolved":true,"context_lines":[{"line_number":200,"context_line":"        self._hasher \u003d self.checksum_info.new_hasher()"},{"line_number":201,"context_line":"        self.expected_checksum \u003d self.expect(expected_checksum)"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"    def expect(self, expected_checksum):"},{"line_number":204,"context_line":"        if expected_checksum is None:"},{"line_number":205,"context_line":"            return None"},{"line_number":206,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"88755f45_9a523ca5","line":203,"range":{"start_line":203,"start_character":8,"end_line":203,"end_character":14},"updated":"2025-03-12 21:01:45.000000000","message":"could we rename this? I keep thinking this is asserting the expected value _is matched_ (rather than validating it)","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f874d368f0199912d2fcab0fbd592feddf25765d","unresolved":true,"context_lines":[{"line_number":207,"context_line":"        # XXX: seems like this should maybe happen in _validate_headers?"},{"line_number":208,"context_line":"        try:"},{"line_number":209,"context_line":"            raw_bytes \u003d strict_b64decode(expected_checksum)"},{"line_number":210,"context_line":"            reencoded \u003d base64.b64encode(raw_bytes).decode(\u0027ascii\u0027)"},{"line_number":211,"context_line":"            if reencoded !\u003d expected_checksum:"},{"line_number":212,"context_line":"                raise ValueError"},{"line_number":213,"context_line":"            if len(raw_bytes) !\u003d self.checksum_info.digest_size:"}],"source_content_type":"text/x-python","patch_set":47,"id":"de74f3e1_1bcd9d2d","line":210,"range":{"start_line":210,"start_character":24,"end_line":210,"end_character":67},"updated":"2025-03-12 21:01:45.000000000","message":"there\u0027s a few places we do this - I wonder about a utils helper??","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f874d368f0199912d2fcab0fbd592feddf25765d","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                self.expected_checksum \u003d self.wsgi_input.trailers.get("},{"line_number":230,"context_line":"                    self.checksum_info.client_header)"},{"line_number":231,"context_line":"                self.expected_checksum \u003d self.expect(self.expected_checksum)"},{"line_number":232,"context_line":"            actual \u003d base64.b64encode(self._hasher.digest()).decode(\u0027ascii\u0027)"},{"line_number":233,"context_line":"            error \u003d (actual !\u003d self.expected_checksum)"},{"line_number":234,"context_line":"        else:"},{"line_number":235,"context_line":"            error \u003d True"}],"source_content_type":"text/x-python","patch_set":47,"id":"d203f171_f16ae22e","line":232,"range":{"start_line":232,"start_character":21,"end_line":232,"end_character":76},"updated":"2025-03-12 21:01:45.000000000","message":"we re-encode here and in the ``expect()`` method, but we could just leave both values as the decoded form","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1744676461190ea90cc329c3da41e2e272ab152b","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                self.expected_checksum \u003d self.wsgi_input.trailers.get("},{"line_number":230,"context_line":"                    self.checksum_info.client_header)"},{"line_number":231,"context_line":"                self.expected_checksum \u003d self.expect(self.expected_checksum)"},{"line_number":232,"context_line":"            actual \u003d base64.b64encode(self._hasher.digest()).decode(\u0027ascii\u0027)"},{"line_number":233,"context_line":"            error \u003d (actual !\u003d self.expected_checksum)"},{"line_number":234,"context_line":"        else:"},{"line_number":235,"context_line":"            error \u003d True"}],"source_content_type":"text/x-python","patch_set":47,"id":"b7a7c2bc_bfc2f371","line":232,"range":{"start_line":232,"start_character":21,"end_line":232,"end_character":76},"in_reply_to":"d203f171_f16ae22e","updated":"2025-03-13 04:17:25.000000000","message":"I think I maybe expected our `raise S3InputChecksumMismatch` might want more args so we could return the client-provided vs calculated checksums.... but I guess AWS doesn\u0027t do that? Need to confirm.","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f874d368f0199912d2fcab0fbd592feddf25765d","unresolved":true,"context_lines":[{"line_number":230,"context_line":"                    self.checksum_info.client_header)"},{"line_number":231,"context_line":"                self.expected_checksum \u003d self.expect(self.expected_checksum)"},{"line_number":232,"context_line":"            actual \u003d base64.b64encode(self._hasher.digest()).decode(\u0027ascii\u0027)"},{"line_number":233,"context_line":"            error \u003d (actual !\u003d self.expected_checksum)"},{"line_number":234,"context_line":"        else:"},{"line_number":235,"context_line":"            error \u003d True"},{"line_number":236,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"29f7428e_061308af","line":233,"updated":"2025-03-12 21:01:45.000000000","message":"I think the mismatch case may need some unit test coverage","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1744676461190ea90cc329c3da41e2e272ab152b","unresolved":true,"context_lines":[{"line_number":230,"context_line":"                    self.checksum_info.client_header)"},{"line_number":231,"context_line":"                self.expected_checksum \u003d self.expect(self.expected_checksum)"},{"line_number":232,"context_line":"            actual \u003d base64.b64encode(self._hasher.digest()).decode(\u0027ascii\u0027)"},{"line_number":233,"context_line":"            error \u003d (actual !\u003d self.expected_checksum)"},{"line_number":234,"context_line":"        else:"},{"line_number":235,"context_line":"            error \u003d True"},{"line_number":236,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"f8687d49_6737512a","line":233,"in_reply_to":"29f7428e_061308af","updated":"2025-03-13 04:17:25.000000000","message":"We hit it with `test_good_md5_good_sha_bad_crc` FWIW. At some point I had a `test_strm_unsgnd_pyld_trl_good_then_bad_trailer` (and I think a `test_strm_unsgnd_pyld_trl_bad_trailer`?) but it seems to have been lost in the shuffle.","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"}],"swift/common/middleware/s3api/s3response.py":[{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":484,"context_line":""},{"line_number":485,"context_line":"class InvalidPart(ErrorResponse):"},{"line_number":486,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":487,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":488,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":489,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":490,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"bdd66570_d7eec9c0","line":487,"updated":"2024-09-27 18:59:47.000000000","message":"Thanks for fixing this up, this definitely follows https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"73205651696a9e9239ad262ef5f8240c94a09736","unresolved":false,"context_lines":[{"line_number":484,"context_line":""},{"line_number":485,"context_line":"class InvalidPart(ErrorResponse):"},{"line_number":486,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":487,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":488,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":489,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":490,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"2a724fb1_a03e24af","line":487,"in_reply_to":"bdd66570_d7eec9c0","updated":"2024-09-27 23:23:29.000000000","message":"Acknowledged","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":179,"context_line":"                checksum \u003d s3_sysmeta_headers.get("},{"line_number":180,"context_line":"                    sysmeta_header(\u0027object\u0027, \u0027checksum-\u0027 + algo))"},{"line_number":181,"context_line":"                if checksum:"},{"line_number":182,"context_line":"                    headers[\u0027x-amz-checksum-\u0027 + algo] \u003d checksum"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        self.headers \u003d headers"},{"line_number":185,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"68d9c62c_a09b640d","line":182,"updated":"2025-01-20 18:48:15.000000000","message":"ok so this is the sysmeta that got added in ``S3Request._validate_headers``","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":483,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":484,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":485,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":486,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":""},{"line_number":489,"context_line":"class InvalidPartOrder(ErrorResponse):"}],"source_content_type":"text/x-python","patch_set":40,"id":"4ae19da2_219a3cf9","line":486,"updated":"2025-01-20 18:48:15.000000000","message":"is this change to satisfy a cross-compat test? How is it related to this patch?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":483,"context_line":"    _status \u003d \u0027400 Bad Request\u0027"},{"line_number":484,"context_line":"    _msg \u003d \u0027One or more of the specified parts could not be found.  The \u0027 \\"},{"line_number":485,"context_line":"           \u0027part may not have been uploaded, or the specified entity tag \u0027 \\"},{"line_number":486,"context_line":"           \u0027may not match the part\\\u0027s entity tag.\u0027"},{"line_number":487,"context_line":""},{"line_number":488,"context_line":""},{"line_number":489,"context_line":"class InvalidPartOrder(ErrorResponse):"}],"source_content_type":"text/x-python","patch_set":40,"id":"96cb0fd3_2d04af41","line":486,"in_reply_to":"4ae19da2_219a3cf9","updated":"2025-01-25 04:33:47.000000000","message":"Yeah, should probably have gone in the next patch.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"}],"swift/common/middleware/s3api/utils.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":true,"context_lines":[{"line_number":118,"context_line":"        self.crc \u003d self.crc_func(data, self.crc)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def digest(self):"},{"line_number":121,"context_line":"        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"class S3Timestamp(utils.Timestamp):"}],"source_content_type":"text/x-python","patch_set":23,"id":"fe102d0b_8bdfcb07","line":121,"updated":"2024-09-19 04:05:12.000000000","message":"Might be a useful addition to the new swift.common.checksum namespace. We may want to take advantage of more crcs. I guess we can always move it later.","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"52319526d88105fde797bf284e5e0d6924b52772","unresolved":false,"context_lines":[{"line_number":118,"context_line":"        self.crc \u003d self.crc_func(data, self.crc)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def digest(self):"},{"line_number":121,"context_line":"        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"class S3Timestamp(utils.Timestamp):"}],"source_content_type":"text/x-python","patch_set":23,"id":"7a79779c_8392f74a","line":121,"in_reply_to":"61178daf_d636fabc","updated":"2024-10-10 21:38:27.000000000","message":"Done","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3285b6566002eb2a3a7c6a7229d7e9988d53adde","unresolved":true,"context_lines":[{"line_number":118,"context_line":"        self.crc \u003d self.crc_func(data, self.crc)"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    def digest(self):"},{"line_number":121,"context_line":"        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"class S3Timestamp(utils.Timestamp):"}],"source_content_type":"text/x-python","patch_set":23,"id":"61178daf_d636fabc","line":121,"in_reply_to":"fe102d0b_8bdfcb07","updated":"2024-09-22 23:56:13.000000000","message":"Yeah, I was thinking we\u0027d do it later if we want, but I could do it sooner.","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba2bb8d51cca76951e013e84c6de9660fa104020","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    return epoch_time"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"checksum_to_hasher \u003d {"},{"line_number":170,"context_line":"    \u0027crc32\u0027: functools.partial(checksum.CRCHasher, zlib.crc32),"},{"line_number":171,"context_line":"    \u0027crc32c\u0027: functools.partial(checksum.CRCHasher, checksum.crc32c),"},{"line_number":172,"context_line":"    \u0027sha1\u0027: hashlib.sha1,"}],"source_content_type":"text/x-python","patch_set":27,"id":"a8a2bd20_9311a7a6","line":169,"updated":"2024-10-01 20:37:34.000000000","message":"awesome","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":194,"context_line":"    \u0027crc64nvme\u0027: \u0027ChecksumCRC64NVME\u0027,"},{"line_number":195,"context_line":"    \u0027sha1\u0027: \u0027ChecksumSHA1\u0027,"},{"line_number":196,"context_line":"    \u0027sha256\u0027: \u0027ChecksumSHA256\u0027,"},{"line_number":197,"context_line":"}"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"class Config(dict):"}],"source_content_type":"text/x-python","patch_set":40,"id":"d6665551_ede74d70","line":197,"updated":"2025-01-20 18:48:15.000000000","message":"a NamedTuple might help reduce this to a single dict mapping checksum-\u003enamed_tuple","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":215,"context_line":"    name \u003d \u0027sha1\u0027"},{"line_number":216,"context_line":""},{"line_number":217,"context_line":"    def new_hasher(self):"},{"line_number":218,"context_line":"        return hashlib.sha1()"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":""},{"line_number":221,"context_line":"class SHA256Info(ChecksumInfo):"}],"source_content_type":"text/x-python","patch_set":43,"id":"2acceb9d_21ea1461","line":218,"updated":"2025-01-25 04:33:47.000000000","message":"Boo!\n```\n\u003e\u003e Issue: [B324:hashlib] Use of weak SHA1 hash for security. Consider usedforsecurity\u003dFalse\n```\n...but `usedforsecurity` came in py39 and we still want to test on py36... I guess the good news is that FIPS doesn\u0027t disable sha1 (yet?)\n\nMaybe time for a `# nosec: B324`?","commit_id":"9ae00a55701be3a9d283406d86054d3395b138ae"}],"swift/common/middleware/versioned_writes/object_versioning.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":true,"context_lines":[{"line_number":324,"context_line":"        incoming_footer_callback \u003d None"},{"line_number":325,"context_line":"        if footer_key in req.environ:"},{"line_number":326,"context_line":"            put_req.environ[footer_key] \u003d incoming_footer_callback \u003d \\"},{"line_number":327,"context_line":"                req.environ.pop(footer_key)"},{"line_number":328,"context_line":"        req.body \u003d b\u0027\u0027"},{"line_number":329,"context_line":"        # move metadata over, including sysmeta"},{"line_number":330,"context_line":""}],"source_content_type":"text/x-python","patch_set":46,"id":"7510bd41_fd348f48","line":327,"updated":"2025-02-28 17:57:13.000000000","message":"I guess we never previously thought about the footers callback being copied to subrequests in general?\n\nAlso, why the pop? I\u0027m curious if something broke if the footer_callback was called again during the symlink PUT?","commit_id":"aa1d677caa779d3a6a90889606e409ad7bdee462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":true,"context_lines":[{"line_number":344,"context_line":"            # put_req.environ -- that may have been updated further along"},{"line_number":345,"context_line":"            # the pipeline."},{"line_number":346,"context_line":"            # Hope it\u0027s idempotent!"},{"line_number":347,"context_line":"            incoming_footer_callback(put_footers)"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"        if put_resp.status_int \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":350,"context_line":"            drain_and_close(put_resp)"}],"source_content_type":"text/x-python","patch_set":46,"id":"8f1e9573_2bfab181","line":347,"updated":"2025-02-28 17:57:13.000000000","message":"I\u0027m hoping this will be unnecessary of we have systags https://review.opendev.org/c/openstack/swift/+/943034\n\nThe version PUT would get the checksum systag into the req environ, and the  symlink PUT would just find it already there","commit_id":"aa1d677caa779d3a6a90889606e409ad7bdee462"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aa2946eae33052454f987a84893b3c964b059db6","unresolved":true,"context_lines":[{"line_number":399,"context_line":"        # for the listing; we want that for the versioning link, too"},{"line_number":400,"context_line":"        override_header \u003d get_container_update_override_key(\u0027etag\u0027)"},{"line_number":401,"context_line":"        if override_header in put_footers:"},{"line_number":402,"context_line":"            req.headers[override_header] \u003d put_footers[override_header]"},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"        # *do* set swift_source here; this PUT is an implementation detail"},{"line_number":405,"context_line":"        req.environ[\u0027swift.source\u0027] \u003d \u0027OV\u0027"}],"source_content_type":"text/x-python","patch_set":46,"id":"0c498185_b3c1a93f","line":402,"updated":"2025-02-28 17:57:13.000000000","message":"wait, we\u0027re promoting footer \"metadata\" to the header??? what if 1st other middleware wants to override something in footers that was set by 2nd other middleware in headers, but now the precedence is inverted and 2nd other middleware gets to override the 1st in headers?\n\nThis footers callback/etag manipulation is way to fragile for my liking.","commit_id":"aa1d677caa779d3a6a90889606e409ad7bdee462"}],"swift/common/utils/checksum.py":[{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":31,"context_line":"    Helper that works like a hashlib hasher, but with a (32-bit) CRC."},{"line_number":32,"context_line":"    \"\"\""},{"line_number":33,"context_line":"    def __init__(self, crc_func, initial_value\u003d0):"},{"line_number":34,"context_line":"        self.crc \u003d initial_value"},{"line_number":35,"context_line":"        self.crc_func \u003d crc_func"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def update(self, data):"}],"source_content_type":"text/x-python","patch_set":26,"id":"1cb0ad42_ef117d2c","line":34,"updated":"2024-09-27 18:59:47.000000000","message":"It would be nice to see docstrings for the methods as well with something like:\n```\ndef __init__(self, crc_func, initial_value\u003d0):\n        \"\"\"\n        Initialize the CRCHasher.\n\n        :param crc_func: Function to compute the CRC.\n        :param initial_value: Initial CRC value.\n        \"\"\"\n        self.crc \u003d initial_value\n        self.crc_func \u003d crc_func\n\n    def update(self, data):\n        \"\"\"\n        Update the CRC with new data.\n\n        :param data: Data to update the CRC with.\n        \"\"\"\n        self.crc \u003d self.crc_func(data, self.crc)\n\n    def digest(self):\n        \"\"\"\n        Return the current CRC value as a 4-byte big-endian integer.\n\n        :return: Packed CRC value.\n        \"\"\"\n        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)\n```","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"78b691ec3360d40dab984f7be7f106ab7bcba719","unresolved":true,"context_lines":[{"line_number":31,"context_line":"    Helper that works like a hashlib hasher, but with a (32-bit) CRC."},{"line_number":32,"context_line":"    \"\"\""},{"line_number":33,"context_line":"    def __init__(self, crc_func, initial_value\u003d0):"},{"line_number":34,"context_line":"        self.crc \u003d initial_value"},{"line_number":35,"context_line":"        self.crc_func \u003d crc_func"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def update(self, data):"}],"source_content_type":"text/x-python","patch_set":26,"id":"1e326d2f_e2988391","line":34,"in_reply_to":"1cb0ad42_ef117d2c","updated":"2024-10-03 15:14:40.000000000","message":"This would be nice","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5bd189e92785256f7c8ec893aaa5a652899f28c7","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    Helper that works like a hashlib hasher, but with a (32-bit) CRC."},{"line_number":32,"context_line":"    \"\"\""},{"line_number":33,"context_line":"    def __init__(self, crc_func, initial_value\u003d0):"},{"line_number":34,"context_line":"        self.crc \u003d initial_value"},{"line_number":35,"context_line":"        self.crc_func \u003d crc_func"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    def update(self, data):"}],"source_content_type":"text/x-python","patch_set":26,"id":"3aa159ec_990131e6","line":34,"in_reply_to":"1e326d2f_e2988391","updated":"2024-10-04 20:09:51.000000000","message":"Pulled in -- thanks!","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":38,"context_line":"        self.crc \u003d self.crc_func(data, self.crc)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def digest(self):"},{"line_number":41,"context_line":"        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def crc32c_ref(data, seed\u003d0):"}],"source_content_type":"text/x-python","patch_set":26,"id":"c385a21e_5fa057c8","line":41,"updated":"2024-09-27 18:59:47.000000000","message":"This method returns the crc value as a 4-byte big-endian integer using the struct.pack function, i wanna look into more examples of struct usages as a ds in python.\n\nI am well familiar with struct usage in Go i am glad to see it here!\n\nedit: I see now that the bitwise AND op helps ensure that we don\u0027t raise an OverfloeError that exceeds the range of a 32-bit unsigned integer","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d899001525149505b545d40a138846fd2caaddf9","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        self.crc \u003d self.crc_func(data, self.crc)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def digest(self):"},{"line_number":41,"context_line":"        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def crc32c_ref(data, seed\u003d0):"}],"source_content_type":"text/x-python","patch_set":26,"id":"a7079da4_3fe25ff3","line":41,"in_reply_to":"2f0611c3_40ea0fcc","updated":"2024-09-30 16:04:10.000000000","message":"Acknowledged","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"73205651696a9e9239ad262ef5f8240c94a09736","unresolved":true,"context_lines":[{"line_number":38,"context_line":"        self.crc \u003d self.crc_func(data, self.crc)"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def digest(self):"},{"line_number":41,"context_line":"        return struct.pack(\"!I\", 0xffffffff \u0026 self.crc)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def crc32c_ref(data, seed\u003d0):"}],"source_content_type":"text/x-python","patch_set":26,"id":"2f0611c3_40ea0fcc","line":41,"in_reply_to":"c385a21e_5fa057c8","updated":"2024-09-27 23:23:29.000000000","message":"Actually it\u0027s a py2-ism. On py3,\n```\n\u003e\u003e\u003e zlib.crc32(b\u0027a\u0027)\n3904355907\n```\nbut on py2\n```\n\u003e\u003e\u003e zlib.crc32(b\u0027a\u0027)\n-390611389\n\u003e\u003e\u003e zlib.crc32(b\u0027a\u0027) \u0026 0xffffffff\n3904355907\n```","commit_id":"ddf8c02713f47639ed690aacf5ee0fad7ecccedf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":26,"context_line":"    pkg_files \u003d None"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class CRCHasher(object):"},{"line_number":30,"context_line":"    \"\"\""},{"line_number":31,"context_line":"    Helper that works like a hashlib hasher, but with a CRC."},{"line_number":32,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":40,"id":"e5b42e74_f184a62e","line":29,"updated":"2025-01-20 18:48:15.000000000","message":"this ought to be tested on test_checksum.py\n\nAlso, could this be in the prior patch?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":45,"context_line":"        elif width \u003d\u003d 64:"},{"line_number":46,"context_line":"            self.digest_fmt \u003d \"!Q\""},{"line_number":47,"context_line":"        else:"},{"line_number":48,"context_line":"            raise ValueError(\"CRCHasher only supports 32- or 64-bit CRCs\")"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def update(self, data):"},{"line_number":51,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":40,"id":"85cf314d_2b8ac30c","line":48,"updated":"2025-01-20 18:48:15.000000000","message":"AFAICT ``width\u003d\u003d64`` is never passed in","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":45,"context_line":"        elif width \u003d\u003d 64:"},{"line_number":46,"context_line":"            self.digest_fmt \u003d \"!Q\""},{"line_number":47,"context_line":"        else:"},{"line_number":48,"context_line":"            raise ValueError(\"CRCHasher only supports 32- or 64-bit CRCs\")"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def update(self, data):"},{"line_number":51,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":40,"id":"a5924d61_d436cfc3","line":48,"in_reply_to":"85cf314d_2b8ac30c","updated":"2025-01-25 04:33:47.000000000","message":"We do it via a `partial` over in s3api/utils: https://review.opendev.org/c/openstack/swift/+/909801/40/swift/common/middleware/s3api/utils.py#172","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":72,"context_line":"        hex \u003d binascii.hexlify(self.digest()).decode(\"ascii\")"},{"line_number":73,"context_line":"        return hex"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def copy(self):"},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        Copy the current state of this CRCHasher to a new one."},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"ecf7c1ce_2c3a3003","line":75,"updated":"2025-01-20 18:48:15.000000000","message":"I couldn\u0027t find where this was used?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0aacadf2f06fb510b9187e6b6fbf9a7fecb7b310","unresolved":true,"context_lines":[{"line_number":72,"context_line":"        hex \u003d binascii.hexlify(self.digest()).decode(\"ascii\")"},{"line_number":73,"context_line":"        return hex"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def copy(self):"},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        Copy the current state of this CRCHasher to a new one."},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"019dd91f_1edc0cb4","line":75,"in_reply_to":"ecf7c1ce_2c3a3003","updated":"2025-01-25 04:33:47.000000000","message":"I just went down [the interface for hash objects](https://docs.python.org/3/library/hashlib.html#hash-objects) and implemented it.","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a1b2fc36c1addb2982320a9f02294873b647d42e","unresolved":true,"context_lines":[{"line_number":65,"context_line":"        \"\"\""},{"line_number":66,"context_line":"        return struct.pack(self.digest_fmt, self.crc)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def hexdigest(self):"},{"line_number":69,"context_line":"        \"\"\""},{"line_number":70,"context_line":"        Return the hexadecimal representation of the current CRC value."},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"bd1858a8_7ff34731","line":68,"range":{"start_line":68,"start_character":8,"end_line":68,"end_character":17},"updated":"2025-03-12 21:28:35.000000000","message":"I\u0027m not sure I saw this being used - the header values are the base64 encoded _digest_\n\nbut it\u0027s nice for the interface consistency with a hashlib hasher","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1744676461190ea90cc329c3da41e2e272ab152b","unresolved":true,"context_lines":[{"line_number":65,"context_line":"        \"\"\""},{"line_number":66,"context_line":"        return struct.pack(self.digest_fmt, self.crc)"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def hexdigest(self):"},{"line_number":69,"context_line":"        \"\"\""},{"line_number":70,"context_line":"        Return the hexadecimal representation of the current CRC value."},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"6f4012af_8225df9a","line":68,"range":{"start_line":68,"start_character":8,"end_line":68,"end_character":17},"in_reply_to":"bd1858a8_7ff34731","updated":"2025-03-13 04:17:25.000000000","message":"Yeah, that was the reason I implemented it -- same for `copy`. I was tempted to extend the interface and add a `base64digest`, but then we\u0027d need a wrapper for `sha1`/`sha256` :-/","commit_id":"81cbd84a16671b2d83538e74425bdf3ed8654b2d"}],"test/s3api/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bcbbac457078d15cac950265726cf3bbf6606696","unresolved":true,"context_lines":[{"line_number":50,"context_line":"    conf \u003d readconf(conf_file, \u0027default\u0027)"},{"line_number":51,"context_line":"    global _CONFIG"},{"line_number":52,"context_line":"    _CONFIG \u003d {"},{"line_number":53,"context_line":"        \u0027endpoint\u0027: conf.get(\u0027endpoint\u0027, \u0027https://s3.amazonaws.com\u0027),"},{"line_number":54,"context_line":"        \u0027region\u0027: conf.get(\u0027region\u0027, \u0027us-east-1\u0027),"},{"line_number":55,"context_line":"        \u0027access_key1\u0027: conf.get(\u0027aws_access_key_id\u0027),"},{"line_number":56,"context_line":"        \u0027secret_key1\u0027: conf.get(\u0027aws_secret_access_key\u0027),"}],"source_content_type":"text/x-python","patch_set":33,"id":"4506443c_334e6301","line":53,"updated":"2024-11-07 00:42:47.000000000","message":"I found myself wanting to change this between `https` and `http`; `region` was a drive-by. I don\u0027t think awscli (or other tooling) use these config opts, though.","commit_id":"ecd7b9e05e07cc9c148469ab5fbe77771a44ce12"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"152653a360c88ec6f287c78bdc76bccefadd1931","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    conf \u003d readconf(conf_file, \u0027default\u0027)"},{"line_number":51,"context_line":"    global _CONFIG"},{"line_number":52,"context_line":"    _CONFIG \u003d {"},{"line_number":53,"context_line":"        \u0027endpoint\u0027: conf.get(\u0027endpoint\u0027, \u0027https://s3.amazonaws.com\u0027),"},{"line_number":54,"context_line":"        \u0027region\u0027: conf.get(\u0027region\u0027, \u0027us-east-1\u0027),"},{"line_number":55,"context_line":"        \u0027access_key1\u0027: conf.get(\u0027aws_access_key_id\u0027),"},{"line_number":56,"context_line":"        \u0027secret_key1\u0027: conf.get(\u0027aws_secret_access_key\u0027),"}],"source_content_type":"text/x-python","patch_set":33,"id":"2ee0a8ee_5641619c","line":53,"in_reply_to":"4506443c_334e6301","updated":"2024-12-02 21:50:26.000000000","message":"Acknowledged","commit_id":"ecd7b9e05e07cc9c148469ab5fbe77771a44ce12"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"68c79a7ac69267cfa5b759815d180f228bd88fee","unresolved":true,"context_lines":[{"line_number":50,"context_line":"    conf \u003d readconf(conf_file, \u0027default\u0027)"},{"line_number":51,"context_line":"    global _CONFIG"},{"line_number":52,"context_line":"    _CONFIG \u003d {"},{"line_number":53,"context_line":"        \u0027endpoint\u0027: conf.get(\u0027endpoint\u0027, \u0027https://s3.amazonaws.com\u0027),"},{"line_number":54,"context_line":"        \u0027region\u0027: conf.get(\u0027region\u0027, \u0027us-east-1\u0027),"},{"line_number":55,"context_line":"        \u0027access_key1\u0027: conf.get(\u0027aws_access_key_id\u0027),"},{"line_number":56,"context_line":"        \u0027secret_key1\u0027: conf.get(\u0027aws_secret_access_key\u0027),"}],"source_content_type":"text/x-python","patch_set":34,"id":"0139168a_c1cdd2fd","line":53,"updated":"2024-11-08 16:35:40.000000000","message":"nice!","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"152653a360c88ec6f287c78bdc76bccefadd1931","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    conf \u003d readconf(conf_file, \u0027default\u0027)"},{"line_number":51,"context_line":"    global _CONFIG"},{"line_number":52,"context_line":"    _CONFIG \u003d {"},{"line_number":53,"context_line":"        \u0027endpoint\u0027: conf.get(\u0027endpoint\u0027, \u0027https://s3.amazonaws.com\u0027),"},{"line_number":54,"context_line":"        \u0027region\u0027: conf.get(\u0027region\u0027, \u0027us-east-1\u0027),"},{"line_number":55,"context_line":"        \u0027access_key1\u0027: conf.get(\u0027aws_access_key_id\u0027),"},{"line_number":56,"context_line":"        \u0027secret_key1\u0027: conf.get(\u0027aws_secret_access_key\u0027),"}],"source_content_type":"text/x-python","patch_set":34,"id":"34d5a374_e45cbc15","line":53,"in_reply_to":"0139168a_c1cdd2fd","updated":"2024-12-02 21:50:26.000000000","message":"Done","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"68c79a7ac69267cfa5b759815d180f228bd88fee","unresolved":true,"context_lines":[{"line_number":249,"context_line":"class BaseS3TestCaseWithBucket(BaseS3Mixin, unittest.TestCase):"},{"line_number":250,"context_line":"    @classmethod"},{"line_number":251,"context_line":"    def setUpClass(cls):"},{"line_number":252,"context_line":"        cls.bucket_name \u003d cls.create_name(\u0027test-bucket\u0027)"},{"line_number":253,"context_line":"        client \u003d cls.get_s3_client(1)"},{"line_number":254,"context_line":"        client.create_bucket(Bucket\u003dcls.bucket_name)"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":34,"id":"fc886360_e4e3748a","line":252,"updated":"2024-11-08 16:35:40.000000000","message":"can we change this to just:\n```\ncls.bucket_name \u003d cls.create_name(\u0027bucket\u0027)\n```","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"152653a360c88ec6f287c78bdc76bccefadd1931","unresolved":false,"context_lines":[{"line_number":249,"context_line":"class BaseS3TestCaseWithBucket(BaseS3Mixin, unittest.TestCase):"},{"line_number":250,"context_line":"    @classmethod"},{"line_number":251,"context_line":"    def setUpClass(cls):"},{"line_number":252,"context_line":"        cls.bucket_name \u003d cls.create_name(\u0027test-bucket\u0027)"},{"line_number":253,"context_line":"        client \u003d cls.get_s3_client(1)"},{"line_number":254,"context_line":"        client.create_bucket(Bucket\u003dcls.bucket_name)"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":34,"id":"853dde30_8f57041b","line":252,"in_reply_to":"ac010799_a37e7d85","updated":"2024-12-02 21:50:26.000000000","message":"Done","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7986f51ba65404eb1e54c7d1e81a23f19e06dfd0","unresolved":true,"context_lines":[{"line_number":249,"context_line":"class BaseS3TestCaseWithBucket(BaseS3Mixin, unittest.TestCase):"},{"line_number":250,"context_line":"    @classmethod"},{"line_number":251,"context_line":"    def setUpClass(cls):"},{"line_number":252,"context_line":"        cls.bucket_name \u003d cls.create_name(\u0027test-bucket\u0027)"},{"line_number":253,"context_line":"        client \u003d cls.get_s3_client(1)"},{"line_number":254,"context_line":"        client.create_bucket(Bucket\u003dcls.bucket_name)"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":34,"id":"ac010799_a37e7d85","line":252,"in_reply_to":"fc886360_e4e3748a","updated":"2024-11-08 20:54:38.000000000","message":"Oh yeah! I forgot about [`TEST_PREFIX`](https://github.com/openstack/swift/blob/2.34.0/test/s3api/__init__.py#L147) -- good catch.","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"50857345bb3a3689555cccbabfe947c44e374fbf","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    conf \u003d readconf(conf_file, \u0027default\u0027)"},{"line_number":51,"context_line":"    global _CONFIG"},{"line_number":52,"context_line":"    _CONFIG \u003d {"},{"line_number":53,"context_line":"        \u0027endpoint\u0027: conf.get(\u0027endpoint\u0027, \u0027https://s3.amazonaws.com\u0027),"},{"line_number":54,"context_line":"        \u0027region\u0027: conf.get(\u0027region\u0027, \u0027us-east-1\u0027),"},{"line_number":55,"context_line":"        \u0027access_key1\u0027: conf.get(\u0027aws_access_key_id\u0027),"},{"line_number":56,"context_line":"        \u0027secret_key1\u0027: conf.get(\u0027aws_secret_access_key\u0027),"}],"source_content_type":"text/x-python","patch_set":44,"id":"a33b5953_6bd91644","line":53,"updated":"2025-02-20 16:09:03.000000000","message":"Oh, hell -- this should *definitely* get pulled out in front! Here I thought I\u0027d tried testing the `aws-chunked` patch with both http and https...\n\nhttps://review.opendev.org/c/openstack/swift/+/942309","commit_id":"9e9641d7029cd509854cc4629263dd307ff95bda"}],"test/s3api/test_object_checksums.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"60a7a879cbbe6c538b05050a81999b41cc7aa9fd","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestObjectChecksums(BaseS3TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    maxDiff \u003d None"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def setUp(self):"},{"line_number":27,"context_line":"        self.client \u003d self.get_s3_client(1)"}],"source_content_type":"text/x-python","patch_set":23,"id":"8a08fb3e_7d52be12","line":24,"updated":"2024-09-19 04:05:12.000000000","message":"Is this just left here from debugging? Although I always add it to help debugging so not against just adding it.","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"b102334cc79deab8600539f40bbd558d9575c11d","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestObjectChecksums(BaseS3TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    maxDiff \u003d None"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def setUp(self):"},{"line_number":27,"context_line":"        self.client \u003d self.get_s3_client(1)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3623f638_ea408bb1","line":24,"in_reply_to":"10251a3c_ae996483","updated":"2024-09-27 19:21:50.000000000","message":"I still need to go through all of the tests stepwise and add suggestions to add more if needed","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"78b691ec3360d40dab984f7be7f106ab7bcba719","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestObjectChecksums(BaseS3TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    maxDiff \u003d None"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def setUp(self):"},{"line_number":27,"context_line":"        self.client \u003d self.get_s3_client(1)"}],"source_content_type":"text/x-python","patch_set":23,"id":"4bdaaf75_7585bbc3","line":24,"in_reply_to":"3623f638_ea408bb1","updated":"2024-10-03 15:14:40.000000000","message":"Done","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3285b6566002eb2a3a7c6a7229d7e9988d53adde","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestObjectChecksums(BaseS3TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    maxDiff \u003d None"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def setUp(self):"},{"line_number":27,"context_line":"        self.client \u003d self.get_s3_client(1)"}],"source_content_type":"text/x-python","patch_set":23,"id":"a0d092be_7820f6a5","line":24,"in_reply_to":"8a08fb3e_7d52be12","updated":"2024-09-22 23:56:13.000000000","message":"Yeah -- it seems hit or miss whether we leave it in there or not.","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f687e11f2a3bba57ab2c4d1825a7ed02f3bd56eb","unresolved":true,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class TestObjectChecksums(BaseS3TestCase):"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    maxDiff \u003d None"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    def setUp(self):"},{"line_number":27,"context_line":"        self.client \u003d self.get_s3_client(1)"}],"source_content_type":"text/x-python","patch_set":23,"id":"10251a3c_ae996483","line":24,"in_reply_to":"a0d092be_7820f6a5","updated":"2024-09-27 18:59:47.000000000","message":"These probably are the most important tests that we have with this patchset","commit_id":"4427f2f3c5078aa617e06935dbe889296de4af77"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba2bb8d51cca76951e013e84c6de9660fa104020","unresolved":true,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def test_crc32c(self):"},{"line_number":211,"context_line":"        if not botocore.httpchecksum.HAS_CRT:"},{"line_number":212,"context_line":"            raise SkipTest(\u0027botocore cannot crc32c (install awscrt)\u0027)"},{"line_number":213,"context_line":"        self.check_alg(\u0027CRC32C\u0027, \u00274waSgw\u003d\u003d\u0027, \u00274waSgx\u003d\u003d\u0027, \u00275waSgw\u003d\u003d\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_sha1(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"1a37698a_5bf25bbc","line":212,"updated":"2024-10-01 20:37:34.000000000","message":"Shouldn\u0027t we add `awscrt` in our test-requirements file ?","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"251824def997435b575884223cbf7c00622054ff","unresolved":false,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def test_crc32c(self):"},{"line_number":211,"context_line":"        if not botocore.httpchecksum.HAS_CRT:"},{"line_number":212,"context_line":"            raise SkipTest(\u0027botocore cannot crc32c (install awscrt)\u0027)"},{"line_number":213,"context_line":"        self.check_alg(\u0027CRC32C\u0027, \u00274waSgw\u003d\u003d\u0027, \u00274waSgx\u003d\u003d\u0027, \u00275waSgw\u003d\u003d\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_sha1(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"2133b5fc_4467eb87","line":212,"in_reply_to":"1a37698a_5bf25bbc","updated":"2024-10-09 15:43:06.000000000","message":"Done","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"52319526d88105fde797bf284e5e0d6924b52772","unresolved":true,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def test_crc32c(self):"},{"line_number":211,"context_line":"        if not botocore.httpchecksum.HAS_CRT:"},{"line_number":212,"context_line":"            raise SkipTest(\u0027botocore cannot crc32c (install awscrt)\u0027)"},{"line_number":213,"context_line":"        self.check_alg(\u0027CRC32C\u0027, \u00274waSgw\u003d\u003d\u0027, \u00274waSgx\u003d\u003d\u0027, \u00275waSgw\u003d\u003d\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_sha1(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"5e00e8ff_9418b4cb","line":212,"in_reply_to":"1a37698a_5bf25bbc","updated":"2024-10-10 21:38:27.000000000","message":"Well, the `requirements-check` job didn\u0027t like it:\n```\nERROR: Requirement \u0027{Requirement(package\u003d\u0027awscrt\u0027, ...)}\u0027 not in openstack/requirements\n```\nIDK whether it\u0027s worth trying to get it into https://github.com/openstack/requirements/blob/master/global-requirements.txt -- the skip-if-missing is a nice, low-effort way to have the test and advertise it to developers. Maybe it\u0027d be better if I said `(run pip install awscrt)`?\n\nHere\u0027s the really wild thing, though -- this is also what\u0027s causing the func test failures! Something about the *combination* of\n\n- having `awscrt` installed \u0026 available and\n- having `s3_acl` enabled\n\ntrips the signature-mismatch -- but I\u0027m still a little confused as to *why* yet -- I didn\u0027t even think `s3_acl` impacted signature calculation at all!?\n\nI guess... if `awscrt` is available, it overrides the signing process -- from digging in more, it looks like `boto3` always upper-cases the request method, so `s3api` has grown to expect that too, while awscrt leaves it as-is (and the affected test does lower case). With `s3_acl` disabled, we\u0027d catch the bad method... somewhere... but with it enabled, we try to [pre-auth with our `TEST` request](https://github.com/openstack/swift/blob/2.34.0/swift/common/middleware/s3api/s3request.py#L1673) so we get the 403 out before the 405?","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"e8bd38439a0bcc766d28f46d83b39ed57e8c88e4","unresolved":true,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def test_crc32c(self):"},{"line_number":211,"context_line":"        if not botocore.httpchecksum.HAS_CRT:"},{"line_number":212,"context_line":"            raise SkipTest(\u0027botocore cannot crc32c (install awscrt)\u0027)"},{"line_number":213,"context_line":"        self.check_alg(\u0027CRC32C\u0027, \u00274waSgw\u003d\u003d\u0027, \u00274waSgx\u003d\u003d\u0027, \u00275waSgw\u003d\u003d\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_sha1(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"704c07f3_521f7c44","line":212,"in_reply_to":"2133b5fc_4467eb87","updated":"2024-10-09 20:41:39.000000000","message":"We probably should be adding `awscrt` in lower-constraints as well as `requirements.txt` potentially if we want the [requirements-check-ci-test](https://zuul.opendev.org/t/openstack/build/aa838a75811a4688b19343c7ec6da3e5) to pass, ref","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4db1aef7b05ddae71ec0ccb0b6994ed48a4cd9ff","unresolved":true,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def test_crc32c(self):"},{"line_number":211,"context_line":"        if not botocore.httpchecksum.HAS_CRT:"},{"line_number":212,"context_line":"            raise SkipTest(\u0027botocore cannot crc32c (install awscrt)\u0027)"},{"line_number":213,"context_line":"        self.check_alg(\u0027CRC32C\u0027, \u00274waSgw\u003d\u003d\u0027, \u00274waSgx\u003d\u003d\u0027, \u00275waSgw\u003d\u003d\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_sha1(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"ecc0a783_c47766ea","line":212,"in_reply_to":"5e00e8ff_9418b4cb","updated":"2024-10-11 15:49:53.000000000","message":"That\u0027s very interesting and worth replicating, so imma do so.","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"210374c95ed3810f7c8a713598c6ae42f4bf6e34","unresolved":false,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"    def test_crc32c(self):"},{"line_number":211,"context_line":"        if not botocore.httpchecksum.HAS_CRT:"},{"line_number":212,"context_line":"            raise SkipTest(\u0027botocore cannot crc32c (install awscrt)\u0027)"},{"line_number":213,"context_line":"        self.check_alg(\u0027CRC32C\u0027, \u00274waSgw\u003d\u003d\u0027, \u00274waSgx\u003d\u003d\u0027, \u00275waSgw\u003d\u003d\u0027)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    def test_sha1(self):"}],"source_content_type":"text/x-python","patch_set":27,"id":"87d66696_053eb5bf","line":212,"in_reply_to":"ecc0a783_c47766ea","updated":"2024-10-15 21:51:21.000000000","message":"Done","commit_id":"041caddcd27e00cdf9c1af038f6921b361717959"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"68c79a7ac69267cfa5b759815d180f228bd88fee","unresolved":true,"context_lines":[{"line_number":102,"context_line":"        self.assertEqual(item[\u0027ChecksumAlgorithm\u0027], [self.ALGORITHM])"},{"line_number":103,"context_line":"        self.assertIn(\u0027VersionId\u0027, item)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def assert_error(self, resp, err_code, err_msg, obj_name):"},{"line_number":106,"context_line":"        self.assertEqual(400, resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":107,"context_line":"        self.assertEqual(err_code, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":108,"context_line":"        self.assertEqual(err_msg, resp[\u0027Error\u0027][\u0027Message\u0027])"}],"source_content_type":"text/x-python","patch_set":34,"id":"331cb3b6_42de04bb","line":105,"updated":"2024-11-08 16:35:40.000000000","message":"This helper is useful and better than the alternatove i suggested here, ref: https://review.opendev.org/c/openstack/swift/+/931223/10/test/s3api/test_object_checksums.py#116, which is not generic enough","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"152653a360c88ec6f287c78bdc76bccefadd1931","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        self.assertEqual(item[\u0027ChecksumAlgorithm\u0027], [self.ALGORITHM])"},{"line_number":103,"context_line":"        self.assertIn(\u0027VersionId\u0027, item)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def assert_error(self, resp, err_code, err_msg, obj_name):"},{"line_number":106,"context_line":"        self.assertEqual(400, resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":107,"context_line":"        self.assertEqual(err_code, resp[\u0027Error\u0027][\u0027Code\u0027])"},{"line_number":108,"context_line":"        self.assertEqual(err_msg, resp[\u0027Error\u0027][\u0027Message\u0027])"}],"source_content_type":"text/x-python","patch_set":34,"id":"e474887e_2484124b","line":105,"in_reply_to":"331cb3b6_42de04bb","updated":"2024-12-02 21:50:26.000000000","message":"This has been addressed","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"68c79a7ac69267cfa5b759815d180f228bd88fee","unresolved":true,"context_lines":[{"line_number":267,"context_line":"                \u0027Multiple checksum Types are not allowed.\u0027"},{"line_number":268,"context_line":"        self.assertEqual(resp[\u0027Error\u0027][\u0027Message\u0027], expected)"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    def assert_invalid(self, resp):"},{"line_number":271,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"},{"line_number":272,"context_line":"        self.assertEqual(400, code)"},{"line_number":273,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"}],"source_content_type":"text/x-python","patch_set":34,"id":"e08b52e7_4195defb","line":270,"updated":"2024-11-08 16:35:40.000000000","message":"good helper","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"152653a360c88ec6f287c78bdc76bccefadd1931","unresolved":false,"context_lines":[{"line_number":267,"context_line":"                \u0027Multiple checksum Types are not allowed.\u0027"},{"line_number":268,"context_line":"        self.assertEqual(resp[\u0027Error\u0027][\u0027Message\u0027], expected)"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    def assert_invalid(self, resp):"},{"line_number":271,"context_line":"        code \u003d resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027]"},{"line_number":272,"context_line":"        self.assertEqual(400, code)"},{"line_number":273,"context_line":"        self.assertEqual(\u0027InvalidRequest\u0027, resp[\u0027Error\u0027][\u0027Code\u0027])"}],"source_content_type":"text/x-python","patch_set":34,"id":"7618115a_0856cca6","line":270,"in_reply_to":"e08b52e7_4195defb","updated":"2024-12-02 21:50:26.000000000","message":"Acknowledged","commit_id":"0c41ecd6fc5e33fe44bb476463f69520ef0b9628"}],"test/unit/common/middleware/s3api/test_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9c4883162fdf7ab5a99d1bc752bee244a02f0ae0","unresolved":true,"context_lines":[{"line_number":120,"context_line":"        self.assertEqual(set(utils.checksum_to_hasher),"},{"line_number":121,"context_line":"                         set(utils.checksum_to_listing_param))"},{"line_number":122,"context_line":"        self.assertEqual(set(utils.checksum_to_hasher),"},{"line_number":123,"context_line":"                         set(utils.checksum_to_client_name))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def test_checksum_hash_len(self):"},{"line_number":126,"context_line":"        for chksum, hasher in utils.checksum_to_hasher.items():"}],"source_content_type":"text/x-python","patch_set":40,"id":"7b5f01f0_d4b649c1","line":123,"updated":"2025-01-20 18:48:15.000000000","message":"ok, this prevents the dicts getting different keys, but perhaps a single dict mapping to some kind of per-checksum data struct would be better?","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"50857345bb3a3689555cccbabfe947c44e374fbf","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        self.assertEqual(set(utils.checksum_to_hasher),"},{"line_number":121,"context_line":"                         set(utils.checksum_to_listing_param))"},{"line_number":122,"context_line":"        self.assertEqual(set(utils.checksum_to_hasher),"},{"line_number":123,"context_line":"                         set(utils.checksum_to_client_name))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def test_checksum_hash_len(self):"},{"line_number":126,"context_line":"        for chksum, hasher in utils.checksum_to_hasher.items():"}],"source_content_type":"text/x-python","patch_set":40,"id":"3360e701_cce0d6b8","line":123,"in_reply_to":"7b5f01f0_d4b649c1","updated":"2025-02-20 16:09:03.000000000","message":"Done","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c2bfd41ba3c15d6129e132fb1c63267ecc27da92","unresolved":true,"context_lines":[{"line_number":125,"context_line":"    def test_checksum_hash_len(self):"},{"line_number":126,"context_line":"        for chksum, hasher in utils.checksum_to_hasher.items():"},{"line_number":127,"context_line":"            self.assertEqual(len(hasher().digest()),"},{"line_number":128,"context_line":"                             utils.checksum_to_hash_len[chksum])"},{"line_number":129,"context_line":"            self.assertEqual(len(hasher().hexdigest()),"},{"line_number":130,"context_line":"                             2 * utils.checksum_to_hash_len[chksum])"},{"line_number":131,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"be98abd3_ca688a6c","line":128,"updated":"2025-01-22 14:46:27.000000000","message":"errors on py36 because crc64nvme is None","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"50857345bb3a3689555cccbabfe947c44e374fbf","unresolved":false,"context_lines":[{"line_number":125,"context_line":"    def test_checksum_hash_len(self):"},{"line_number":126,"context_line":"        for chksum, hasher in utils.checksum_to_hasher.items():"},{"line_number":127,"context_line":"            self.assertEqual(len(hasher().digest()),"},{"line_number":128,"context_line":"                             utils.checksum_to_hash_len[chksum])"},{"line_number":129,"context_line":"            self.assertEqual(len(hasher().hexdigest()),"},{"line_number":130,"context_line":"                             2 * utils.checksum_to_hash_len[chksum])"},{"line_number":131,"context_line":""}],"source_content_type":"text/x-python","patch_set":40,"id":"f04a8ffe_f6e46d8d","line":128,"in_reply_to":"be98abd3_ca688a6c","updated":"2025-02-20 16:09:03.000000000","message":"Done","commit_id":"f2ff609392f7b83e683f00b03a56631634a1b2d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20654c51d4143eadf573e1463e9f36ca824e3794","unresolved":true,"context_lines":[{"line_number":126,"context_line":"        for chksum, hasher in utils.checksum_to_hasher.items():"},{"line_number":127,"context_line":"            if not hasher:"},{"line_number":128,"context_line":"                # crc64nvme only available in newer isa-l"},{"line_number":129,"context_line":"                continue"},{"line_number":130,"context_line":"            self.assertEqual(len(hasher().digest()),"},{"line_number":131,"context_line":"                             utils.checksum_to_hash_len[chksum])"},{"line_number":132,"context_line":"            self.assertEqual(len(hasher().hexdigest()),"}],"source_content_type":"text/x-python","patch_set":41,"id":"1aeedc7b_7dd5265d","line":129,"updated":"2025-01-22 14:56:00.000000000","message":"I really don\u0027t like how much testing of the crc\u0027s is platform dependent","commit_id":"9fb91818710ded3d1f501a00ba5037511eafd703"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"50857345bb3a3689555cccbabfe947c44e374fbf","unresolved":true,"context_lines":[{"line_number":126,"context_line":"        for chksum, hasher in utils.checksum_to_hasher.items():"},{"line_number":127,"context_line":"            if not hasher:"},{"line_number":128,"context_line":"                # crc64nvme only available in newer isa-l"},{"line_number":129,"context_line":"                continue"},{"line_number":130,"context_line":"            self.assertEqual(len(hasher().digest()),"},{"line_number":131,"context_line":"                             utils.checksum_to_hash_len[chksum])"},{"line_number":132,"context_line":"            self.assertEqual(len(hasher().hexdigest()),"}],"source_content_type":"text/x-python","patch_set":41,"id":"1842bea2_06e214a7","line":129,"in_reply_to":"1aeedc7b_7dd5265d","updated":"2025-02-20 16:09:03.000000000","message":"I think this has mostly been satisfied now? We\u0027ll always have a `crc64nvme` implementation, anyway.\n\nThere\u0027s still a decent bit of platform-dependency in the cross-compat tests, though. (Is `boto3` \u003e\u003d1.36? Is `awscrt` installed?)","commit_id":"9fb91818710ded3d1f501a00ba5037511eafd703"}]}
