)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4ee18e581f388461a4df7c1eaa5bde3517efd3c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"1ad4dc11_12c848c5","updated":"2026-01-20 11:07:02.000000000","message":"recheck\n\nbandit failure fixed by https://review.opendev.org/c/openstack/swift/+/937884","commit_id":"cced07999fca875375d883b13606a87981a5c587"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"99aecb48b923d783716e9a2c68e48f974a127703","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"75b8bd33_87a08b54","updated":"2026-01-27 20:53:49.000000000","message":"I like the idea to have a single place in swift proxy-server to set ``x-timestamp``, which will make it easier to maintain/debug things down the road.","commit_id":"0007353a3985e4b3db38a1a159f51b8601af12b3"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e3ff8459385a35e0acc48716505163550b5f8998","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"d8140c4d_8925b50f","updated":"2026-01-28 05:42:12.000000000","message":"Nice, I think this is ready. Al you may do the honours or I\u0027ll come back once I check out a few more in the chain 😊","commit_id":"0007353a3985e4b3db38a1a159f51b8601af12b3"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7742d501b7da75238128038e7e2fb427ec5df8d0","unresolved":true,"context_lines":[{"line_number":204,"context_line":"                                        part_number)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        req_timestamp \u003d S3Timestamp.now()"},{"line_number":207,"context_line":"        req.headers[\u0027X-Timestamp\u0027] \u003d req_timestamp.internal"},{"line_number":208,"context_line":"        source_resp \u003d req.check_copy_source(self.app)"},{"line_number":209,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers and \\"},{"line_number":210,"context_line":"                \u0027X-Amz-Copy-Source-Range\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":3,"id":"e7352e2f_95e49655","side":"PARENT","line":207,"updated":"2026-01-15 00:50:03.000000000","message":"Some [history](https://review.opendev.org/c/x/swift3/+/242578). (I don\u0027t remember the context real well, but looks like I seemed to like it at the time?)","commit_id":"1971983dece9f889ccb4dfd5dde628727390f074"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e3ff8459385a35e0acc48716505163550b5f8998","unresolved":true,"context_lines":[{"line_number":204,"context_line":"                                        part_number)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        req_timestamp \u003d S3Timestamp.now()"},{"line_number":207,"context_line":"        req.headers[\u0027X-Timestamp\u0027] \u003d req_timestamp.internal"},{"line_number":208,"context_line":"        source_resp \u003d req.check_copy_source(self.app)"},{"line_number":209,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers and \\"},{"line_number":210,"context_line":"                \u0027X-Amz-Copy-Source-Range\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":3,"id":"22c8dbb3_20461f9d","side":"PARENT","line":207,"in_reply_to":"c38a1fa5_7e15ae06","updated":"2026-01-28 05:42:12.000000000","message":"oh so it was back in the swift3 days. Ie back when it was tracked seperately from the rest of swift.. then yeah this is the only way they could be sure it exists.. now it\u0027s sure to exist in the greater swift thanks to this patch, so this isn\u0027t strictly needed now.","commit_id":"1971983dece9f889ccb4dfd5dde628727390f074"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6b60a63cdea966574e9e2fd68eeb9b7ffd4d8a67","unresolved":true,"context_lines":[{"line_number":204,"context_line":"                                        part_number)"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        req_timestamp \u003d S3Timestamp.now()"},{"line_number":207,"context_line":"        req.headers[\u0027X-Timestamp\u0027] \u003d req_timestamp.internal"},{"line_number":208,"context_line":"        source_resp \u003d req.check_copy_source(self.app)"},{"line_number":209,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers and \\"},{"line_number":210,"context_line":"                \u0027X-Amz-Copy-Source-Range\u0027 in req.headers:"}],"source_content_type":"text/x-python","patch_set":3,"id":"c38a1fa5_7e15ae06","side":"PARENT","line":207,"in_reply_to":"e7352e2f_95e49655","updated":"2026-01-16 17:30:57.000000000","message":"thanks! I\u0027ll add a Related-Change link","commit_id":"1971983dece9f889ccb4dfd5dde628727390f074"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7742d501b7da75238128038e7e2fb427ec5df8d0","unresolved":true,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":245,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":246,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":247,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":248,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":249,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"ef589498_b01eb825","line":246,"range":{"start_line":246,"start_character":47,"end_line":246,"end_character":62},"updated":"2026-01-15 00:50:03.000000000","message":"We can\u0027t use `X-Timestamp` here and skip the date parsing?","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f8c77dd2985cdb63192fe8d478b38bd26d74c2d4","unresolved":true,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":245,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":246,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":247,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":248,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":249,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"6e8848b9_f9cfda31","line":246,"range":{"start_line":246,"start_character":47,"end_line":246,"end_character":62},"in_reply_to":"c982a7e4_841e75ba","updated":"2026-01-16 17:34:32.000000000","message":"I did check, it is covered for replicated and EC object PUTs","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6b60a63cdea966574e9e2fd68eeb9b7ffd4d8a67","unresolved":true,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":245,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":246,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":247,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":248,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":249,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"c982a7e4_841e75ba","line":246,"range":{"start_line":246,"start_character":47,"end_line":246,"end_character":62},"in_reply_to":"ef589498_b01eb825","updated":"2026-01-16 17:30:57.000000000","message":"I don\u0027t think we get an X-Timestamp back with a PUT response, and even if we did it wouldn\u0027t make it back to the s3 response.\n\nWhereas the proxy app does copy the req.timestamp to the resp.last_modified\nhttps://github.com/openstack/swift/blob/124cdcba668a402bc40c9a0aa20c2f46abfbb7a4/swift/proxy/controllers/obj.py#L1240\n\nI should check that ^^^ is *tested*.","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"}],"swift/common/middleware/s3api/controllers/obj.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7742d501b7da75238128038e7e2fb427ec5df8d0","unresolved":true,"context_lines":[{"line_number":162,"context_line":"        \"\"\""},{"line_number":163,"context_line":"        if len(req.object_name) \u003e constraints.MAX_OBJECT_NAME_LENGTH:"},{"line_number":164,"context_line":"            raise KeyTooLongError()"},{"line_number":165,"context_line":"        # set X-Timestamp by s3api to use at copy resp body"},{"line_number":166,"context_line":"        if all(h in req.headers"},{"line_number":167,"context_line":"               for h in (\u0027X-Amz-Copy-Source\u0027, \u0027X-Amz-Copy-Source-Range\u0027)):"},{"line_number":168,"context_line":"            raise InvalidArgument(\u0027x-amz-copy-source-range\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"c0333679_4eca05fd","line":165,"updated":"2026-01-15 00:50:03.000000000","message":"Dead comment?","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6b60a63cdea966574e9e2fd68eeb9b7ffd4d8a67","unresolved":false,"context_lines":[{"line_number":162,"context_line":"        \"\"\""},{"line_number":163,"context_line":"        if len(req.object_name) \u003e constraints.MAX_OBJECT_NAME_LENGTH:"},{"line_number":164,"context_line":"            raise KeyTooLongError()"},{"line_number":165,"context_line":"        # set X-Timestamp by s3api to use at copy resp body"},{"line_number":166,"context_line":"        if all(h in req.headers"},{"line_number":167,"context_line":"               for h in (\u0027X-Amz-Copy-Source\u0027, \u0027X-Amz-Copy-Source-Range\u0027)):"},{"line_number":168,"context_line":"            raise InvalidArgument(\u0027x-amz-copy-source-range\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"c0e489eb_de12aa5e","line":165,"in_reply_to":"c0333679_4eca05fd","updated":"2026-01-16 17:30:57.000000000","message":"Done","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7742d501b7da75238128038e7e2fb427ec5df8d0","unresolved":true,"context_lines":[{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":178,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":179,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":180,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":181,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":182,"context_line":"            # delete object metadata from response"}],"source_content_type":"text/x-python","patch_set":3,"id":"b8baf4e8_ec791e16","line":179,"range":{"start_line":179,"start_character":48,"end_line":179,"end_character":61},"updated":"2026-01-15 00:50:03.000000000","message":"Similarly here -- not using X-Timestamp?","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"6995b0ab1a789063d5f139ed587ae6d97ec7921b","unresolved":true,"context_lines":[{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":178,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":179,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":180,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":181,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":182,"context_line":"            # delete object metadata from response"}],"source_content_type":"text/x-python","patch_set":3,"id":"afa16ddc_ffe3b3ef","line":179,"range":{"start_line":179,"start_character":48,"end_line":179,"end_character":61},"in_reply_to":"006d3b00_5518fa34","updated":"2026-01-27 05:38:30.000000000","message":"oic, https://github.com/NVIDIA/swift/blob/master/swift/proxy/controllers/obj.py#L1240\n\nso there is no behavior changes with this regard.","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b7e8b4fc900a605545022e95985fdabbf9cdfc7a","unresolved":true,"context_lines":[{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":178,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":179,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":180,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":181,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":182,"context_line":"            # delete object metadata from response"}],"source_content_type":"text/x-python","patch_set":3,"id":"006d3b00_5518fa34","line":179,"range":{"start_line":179,"start_character":48,"end_line":179,"end_character":61},"in_reply_to":"6da273b9_054af6f6","updated":"2026-01-23 09:46:16.000000000","message":"The swift copy subrequest returns the last-modified time of the newly put object, not the source object.\n\nI added the compat test/s3api/test_object.py to verify that both swift and s3 return a last-modified that is later than the source object.","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6b60a63cdea966574e9e2fd68eeb9b7ffd4d8a67","unresolved":true,"context_lines":[{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":178,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":179,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":180,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":181,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":182,"context_line":"            # delete object metadata from response"}],"source_content_type":"text/x-python","patch_set":3,"id":"e57ec19a_2208934b","line":179,"range":{"start_line":179,"start_character":48,"end_line":179,"end_character":61},"in_reply_to":"b8baf4e8_ec791e16","updated":"2026-01-16 17:30:57.000000000","message":"x-timestamp isn\u0027t available","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d7c8da8cd740de7f8d2e38ce1dc7e5f383813e1a","unresolved":true,"context_lines":[{"line_number":176,"context_line":""},{"line_number":177,"context_line":"        if \u0027X-Amz-Copy-Source\u0027 in req.headers:"},{"line_number":178,"context_line":"            last_modified_ts \u003d S3Timestamp("},{"line_number":179,"context_line":"                parse_date_header(resp.headers[\u0027Last-Modified\u0027]))"},{"line_number":180,"context_line":"            resp.append_copy_resp_body(req.controller_name,"},{"line_number":181,"context_line":"                                       last_modified_ts.s3xmlformat)"},{"line_number":182,"context_line":"            # delete object metadata from response"}],"source_content_type":"text/x-python","patch_set":3,"id":"6da273b9_054af6f6","line":179,"range":{"start_line":179,"start_character":48,"end_line":179,"end_character":61},"in_reply_to":"e57ec19a_2208934b","updated":"2026-01-23 00:59:45.000000000","message":"this is the place where users would see timestamps differently for s3 ``PUT Object - Copy`` or ``Upload Part - Copy`` requests. Before the patch, it\u0027s a request timestamp; after the patch, it\u0027s  the ``Last-Modified`` of the original object.\n\nI wonder which one is the expected timestamp for real s3 ``PUT Object - Copy`` or ``Upload Part - Copy`` responses?","commit_id":"de7c88432bcfefbccb6ae161998b375a6898082e"}],"test/s3api/test_mpu.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"99aecb48b923d783716e9a2c68e48f974a127703","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            else:"},{"line_number":126,"context_line":"                self.assertEqual(version, resp[\u0027VersionId\u0027])"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def _verify_copy_parts(self, key_src, key_dest, upload_id):"},{"line_number":129,"context_line":"        parts \u003d []"},{"line_number":130,"context_line":"        for part_num, start, end in self._iter_part_num_ranges():"},{"line_number":131,"context_line":"            copy_range \u003d \u0027bytes\u003d%d-%d\u0027 % (start, end - 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7bc0c274_72a7d6da","side":"PARENT","line":128,"updated":"2026-01-27 20:53:49.000000000","message":"this function was only used by ``test_upload_part_copy``","commit_id":"64bde7e05c258322864703b55042455d4d3c48ad"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e3ff8459385a35e0acc48716505163550b5f8998","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            else:"},{"line_number":126,"context_line":"                self.assertEqual(version, resp[\u0027VersionId\u0027])"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def _verify_copy_parts(self, key_src, key_dest, upload_id):"},{"line_number":129,"context_line":"        parts \u003d []"},{"line_number":130,"context_line":"        for part_num, start, end in self._iter_part_num_ranges():"},{"line_number":131,"context_line":"            copy_range \u003d \u0027bytes\u003d%d-%d\u0027 % (start, end - 1)"}],"source_content_type":"text/x-python","patch_set":7,"id":"2db96c78_1163a4c6","side":"PARENT","line":128,"in_reply_to":"7bc0c274_72a7d6da","updated":"2026-01-28 05:42:12.000000000","message":"oh right to is was merged back into test_upload_part_copy, gotcha","commit_id":"64bde7e05c258322864703b55042455d4d3c48ad"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"99aecb48b923d783716e9a2c68e48f974a127703","unresolved":false,"context_lines":[{"line_number":581,"context_line":"                \u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])"},{"line_number":582,"context_line":"            self.assertTrue(copy_resp[\u0027CopyPartResult\u0027][\u0027ETag\u0027])"},{"line_number":583,"context_line":"            self.assertTrue(copy_resp[\u0027CopyPartResult\u0027][\u0027LastModified\u0027])"},{"line_number":584,"context_line":"            self.assertGreater("},{"line_number":585,"context_line":"                copy_resp[\u0027CopyPartResult\u0027][\u0027LastModified\u0027],"},{"line_number":586,"context_line":"                src_head_resp[\u0027LastModified\u0027])"},{"line_number":587,"context_line":"            parts.append({"}],"source_content_type":"text/x-python","patch_set":7,"id":"7572a709_1abae0fc","line":584,"updated":"2026-01-27 20:53:49.000000000","message":"MPU parts are also covered, nice!","commit_id":"0007353a3985e4b3db38a1a159f51b8601af12b3"}],"test/s3api/test_object.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"6995b0ab1a789063d5f139ed587ae6d97ec7921b","unresolved":true,"context_lines":[{"line_number":51,"context_line":"        # the copy gets a fresh timestamp..."},{"line_number":52,"context_line":"        self.assertNotEqual("},{"line_number":53,"context_line":"            head_resp[\u0027LastModified\u0027],"},{"line_number":54,"context_line":"            copy_resp[\u0027CopyObjectResult\u0027][\u0027LastModified\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"39b7a0a7_b8d1b794","line":54,"updated":"2026-01-27 05:38:30.000000000","message":"we should be able to assert that ``copy_resp[\u0027CopyObjectResult\u0027][\u0027LastModified\u0027])`` \u003e ``head_resp[\u0027LastModified\u0027]``?","commit_id":"8a51dc88fd8766a6e58512ed90e0c32a770deafd"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"99aecb48b923d783716e9a2c68e48f974a127703","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        # the copy gets a fresh timestamp..."},{"line_number":52,"context_line":"        self.assertNotEqual("},{"line_number":53,"context_line":"            head_resp[\u0027LastModified\u0027],"},{"line_number":54,"context_line":"            copy_resp[\u0027CopyObjectResult\u0027][\u0027LastModified\u0027])"}],"source_content_type":"text/x-python","patch_set":6,"id":"8610d920_5ab8b5c9","line":54,"in_reply_to":"39b7a0a7_b8d1b794","updated":"2026-01-27 20:53:49.000000000","message":"Done","commit_id":"8a51dc88fd8766a6e58512ed90e0c32a770deafd"}]}
