)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4ab8908e1454a14496bbd3e06db11bb9100b923b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"bfbd9f1e_c6701e8d","updated":"2023-09-25 22:39:00.000000000","message":"I think there\u0027s some good coverage in the part-number unittests but it would be nice to break up the asserts into indiviual behavior oriented tests.\n\nWe also need to test more types of manifests (range-segments and data-segments; sub-slo-range-segments)\n\nI think the inconsistent ETags in the error responses is a bug","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"10e71400944f951a9ac6287e963041a4dfffd2d5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"4f3d9e64_f5b55826","updated":"2023-09-29 04:48:12.000000000","message":"@iwc - I think I kept all your changes from ps15 in my rebase; the underlying slo code is still moving around.\n\nWe need to get those test assertions for the call log in here so we can start debugging the _need_to_refetch logic \n\nWhat\u0027s your plan to address the etag/XXX in tests???\n\nmaybe you can *raise* a swob response?  rip _return_slo_resp into:\n\n```\nresp \u003d _make_slo_resp(response_class\u003dswob.Response, *args, **kwargs)\nreturn resp\n```\n\nand then in get_part_num\n\n```\nerr_resp \u003d _make_slo_response(response_class\u003dswob.HTTPException, *args, **kwargs)\nraise err_resp\n```\n\n???","commit_id":"1d7cc8e811b4dedb03cf419538eb84efdea53b2b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"ba1897d8_a0ce7487","updated":"2023-09-29 19:51:10.000000000","message":"i\u0027d like to get in here and help with clean-up on this, but I\u0027m still dealing with a lot of churn in the pre-reqs and already having trouble keeping tests passing when I move the base around while both of us making changes in here\n\ne.g. s/segments_needed/segment_listing_needed wasn\u0027t a rebase conflict in the is_part_num branch, just a bunch of test failures that I thought were because I broke the _calc_req_range stuff\n\nI\u0027m not complaining; just sort of making excuses for throwing up nits instead of fixing them.  Please try to review this critically and see if there\u0027s any more room for tests/polish/consolidation/simplificiation.","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"127208f70c1765f487508961cf6dda6a5ca02aff","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"aad55c30_7c1094cb","updated":"2023-10-02 20:08:40.000000000","message":"tests are starting to look ok I think!","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e9fd8e3c1a276dcef2802484b5d3d8849ada1d13","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"df7c6fa6_02fa30cb","updated":"2023-10-03 21:48:57.000000000","message":"great effort!","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":25,"id":"0191ace4_8bccad41","updated":"2023-10-10 17:22:15.000000000","message":"I think the tests are starting to shape up.  I had some ideas that might make the implementation flow a little better but it\u0027s already got a few nice things going on, and it\u0027s possible this already works fine and is good enough - I didn\u0027t notice anything that looked obviously wrong to me.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0f9c4c914420e4b76cc64c84b30f2d8eb9f24e07","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":27,"id":"f2e5afe5_8a60682f","updated":"2023-10-11 22:55:41.000000000","message":"please add some functional tests for HEAD requests","commit_id":"5abfc111c38f8870f568eff4c8c2bf0d95d305f3"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"015edc274e4087228ac9dda49a9973a04a0b37e6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":38,"id":"55f97d51_b8f7db25","updated":"2023-10-24 22:48:34.000000000","message":"I pushed over with what I hope will be a py2 fix","commit_id":"b26c91a3c7a8e0177a491152fe6a2155baebf1c7"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"4d2c7374d861bca20620e7f41a093b5eef5f29dc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":47,"id":"17efa3e4_609535ce","updated":"2023-11-01 20:21:25.000000000","message":"We are almost there, but I have a small concern still.","commit_id":"25b2061a3d0acbbe8f8fbcb02d94cf81a7c87f1f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1ac7aa6ea782bd3b6c742f081ac332a98fd7ef77","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":51,"id":"c4195059_76809cfe","updated":"2023-11-10 21:51:44.000000000","message":"I did some functional testing on this and tried to cleanup some nits in the docstrings - I didn\u0027t get to finish looking at tests or responding to the existing comments.","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"43416d0c7039166323156f3afc8ba72b34abaf75","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":55,"id":"3e785319_f810a8cd","updated":"2023-11-14 00:34:54.000000000","message":"(for now)","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2ba0d9b56765aaf95ef51c96b2edaca9c4392d1c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":55,"id":"ba41f531_181645e6","updated":"2023-11-14 19:49:49.000000000","message":"Now I want to write a parallel-downloader for python-swiftclient...","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6b1370febecc22ddb542746cb99168a6199e9db1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":61,"id":"964da38b_e4fcd453","updated":"2023-11-22 19:01:07.000000000","message":"I forgot my summary: this looks good in principle. I\u0027d like the validation pieces to be straightened out. I\u0027ve not yet had time to play with it functionally and review the tests.","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c9d1e7e068151f7394945bffa8943d4f3eccd5f9","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":61,"id":"1e3a090b_6588cedf","updated":"2023-11-22 18:58:15.000000000","message":"Since this patch serves as a base patch for https://review.opendev.org/c/openstack/swift/+/894580, and we are striving to have part-num be completely s3 compatible, we will need to make more modifications in this patch to ensure that we don\u0027t have the cross-compat tests in the aforementioned patch failing, since they are so tightly coupled.\nFor e.g\n```\ntest/s3api/test_mpu.py:189 (TestMultiPartUpload.test_get_by_part_number)\n\u0027InvalidPartNumber\u0027 !\u003d \u0027InvalidRange\u0027\n\nExpected :\u0027InvalidRange\u0027\nActual   :\u0027InvalidPartNumber\u0027\n\u003cClick to see difference\u003e\n\nself \u003d \u003ctest.s3api.test_mpu.TestMultiPartUpload testMethod\u003dtest_get_by_part_number\u003e\n\n    def test_get_by_part_number(self):\n        # let\u0027s use up some memory!\n        num_parts \u003d 3\n        part_size \u003d 5 * (2 ** 20)  # 5 MB\n        key_name \u003d self.create_name(\u0027part-num-test\u0027)\n        mpu_etag \u003d self._upload_mpu(key_name, num_parts, part_size)\n    \n        # partNumber argument is 1 indexed\n        with self.assertRaises(ClientError) as caught:\n            self.client.get_object(Bucket\u003dself.bucket_name,\n                                   Key\u003dkey_name, PartNumber\u003d0)\n        err_resp \u003d caught.exception.response\n        self.assertEqual(400, err_resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])\n        self.assertEqual(\u0027InvalidArgument\u0027, err_resp[\u0027Error\u0027][\u0027Code\u0027])\n        err_msg \u003d \u0027Part number must be an integer between \u0027 \\\n                  \u00271 and 10000, inclusive\u0027\n        self.assertEqual(err_msg, err_resp[\u0027Error\u0027][\u0027Message\u0027])\n        self.assertEqual(\u0027partNumber\u0027, err_resp[\u0027Error\u0027][\u0027ArgumentName\u0027])\n        self.assertEqual(\u00270\u0027, err_resp[\u0027Error\u0027][\u0027ArgumentValue\u0027])\n    \n        # all other partNumber args are valid\n        self._verify_part_num_response(key_name, num_parts, part_size,\n                                       mpu_etag)\n    \n        with self.assertRaises(ClientError) as caught:\n            self.client.get_object(Bucket\u003dself.bucket_name,\n                                   Key\u003dkey_name, PartNumber\u003dnum_parts + 1)\n        err_resp \u003d caught.exception.response\n        self.assertEqual(416, err_resp[\u0027ResponseMetadata\u0027][\u0027HTTPStatusCode\u0027])\n\u003e       self.assertEqual(\u0027InvalidRange\u0027, err_resp[\u0027Error\u0027][\u0027Code\u0027])\n\ntest_mpu.py:219: AssertionError","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"44fc7e2c978ab8970c70ac3ec41627ebd70cf018","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":61,"id":"dbe6edf6_2787cbfb","in_reply_to":"1e3a090b_6588cedf","updated":"2023-12-19 00:01:06.000000000","message":"Done","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":70,"id":"dcc13381_95adbd18","updated":"2023-11-28 22:02:17.000000000","message":"I mostly just looked at unittests:\n\nhttps://review.opendev.org/c/openstack/swift/+/902114\n\nI\u0027m not sold on manifest-bb-regular\nI\u0027m not sold on the specific subset of headers set in check_part_num on errors\nI\u0027m not sold on the 200 response status for HEAD?part-number\u003d\n\nI think there\u0027s some other nits/cleanup we should address - some of them are fixed in the squash","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":70,"id":"edd5c388_2ecac862","updated":"2023-11-29 16:51:27.000000000","message":"We do the intial part-number validation for *all* requests but don\u0027t then check it makes sense if the response turns out to be single part (manifest or non-slo). s3 *does* enforce partnumber\u003d\u003d1 for a non-mpu. I guess the s3api could infer that a response wasn\u0027t an SLO (from X-Static-Large-Object or X-Parts-Count headers??) and then s3api could return the error, but maybe we want SLO to flag this error too? see https://review.opendev.org/c/openstack/swift/+/902172\n\nRelated, I\u0027m interested in other opinions on whether we *should* return Content-Range with the 416 response?","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba3d6be4e98f2059b18f183b1e92444ff8962806","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":76,"id":"84a29e55_c82aad14","updated":"2023-12-08 18:07:15.000000000","message":"I started testing this functionally and noticed some header differences (see inline) but then got distracted before fixing anything - just leaving the comments I have so far.","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e821688bdf08343e628625dccb65753e86fbe7d6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":77,"id":"145e85b1_1477c9e8","updated":"2023-12-14 14:49:40.000000000","message":"some unpublished comments RE: 903636: test: couple raw manifests with their TestCase | https://review.opendev.org/c/openstack/swift/+/903636 (now merged)","commit_id":"c353b1c7977687aaadf42afbdc09b662b6d5385b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3b6bf261e4ecdf85c01fc69c4a5f784dec851671","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":83,"id":"82e68a1b_aeec6d21","updated":"2023-12-20 00:33:38.000000000","message":"recheck","commit_id":"b2b763c4db7760cee204a74be1ff59e7239a21c0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"71e87eba2966bd418f4dfc25b8e8635bcb332f17","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":88,"id":"d1e5ff81_5c5ae7a8","updated":"2024-02-28 06:49:53.000000000","message":"Just starting a review, but dinner time.. so will get back to this in the morning","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1ce4467c4da02d4bb0a17756baf88b0f5c7f993d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":89,"id":"e9f35ed0_085df239","updated":"2024-03-01 17:45:30.000000000","message":"need to fix the sub-slo part-num requests.","commit_id":"52deb2357c66323c1466c8acc0dcf9186ac54176"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b331a5bba081897d49da6dd9eaf5aad6b202b55b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":90,"id":"8b33c0be_118ffaf4","updated":"2024-03-12 05:53:45.000000000","message":"I was just doing to nit, but the comment not being moved with the code I think to me is a blocker... if we have to roll one more then might as well get Al\u0027s NITs in too.\n\nBut otherwise, looks great and think this is ready.","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9a5f78acae691712817871cd037eeb68dfdf194","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":90,"id":"a59ae3fa_18c97c48","updated":"2024-03-04 19:44:39.000000000","message":"recheck","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"75141c147a1f7db56d5fb4a491ba7e44547a19c2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":91,"id":"2134d6fc_9526b5a3","updated":"2024-03-12 22:52:21.000000000","message":"Great! nice work everyone! Its a great feature to have in SLO!","commit_id":"6adbeb40365b88c721294e72c8a95accb1b1d4f7"}],"swift/common/middleware/slo.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6769416985c46f0892469e8eaa9c95f48e7e5113","unresolved":true,"context_lines":[{"line_number":774,"context_line":"            return False"},{"line_number":775,"context_line":""},{"line_number":776,"context_line":"        if is_part_num:"},{"line_number":777,"context_line":"            return True"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":780,"context_line":"            # There my be some cases in the future where a HEAD resp on even a"}],"source_content_type":"text/x-python","patch_set":12,"id":"ba929cfb_051d38db","line":777,"updated":"2023-09-27 16:11:50.000000000","message":"could you explain why this is necessary? what will change in the refetched manifest","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":false,"context_lines":[{"line_number":774,"context_line":"            return False"},{"line_number":775,"context_line":""},{"line_number":776,"context_line":"        if is_part_num:"},{"line_number":777,"context_line":"            return True"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":780,"context_line":"            # There my be some cases in the future where a HEAD resp on even a"}],"source_content_type":"text/x-python","patch_set":12,"id":"ccb35af2_ea1fb0e3","line":777,"in_reply_to":"7a50f2fc_b61911be","updated":"2023-09-29 15:04:53.000000000","message":"Done","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2bbcf1bbe6d398ff74a8dee055b340c727b0f057","unresolved":true,"context_lines":[{"line_number":774,"context_line":"            return False"},{"line_number":775,"context_line":""},{"line_number":776,"context_line":"        if is_part_num:"},{"line_number":777,"context_line":"            return True"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":780,"context_line":"            # There my be some cases in the future where a HEAD resp on even a"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a50f2fc_b61911be","line":777,"in_reply_to":"ba929cfb_051d38db","updated":"2023-09-27 16:50:43.000000000","message":"this perhaps needs to be conditional on it being a HEAD request","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f779c69132bb9c918820169d09e02e0a2de180d","unresolved":true,"context_lines":[{"line_number":1020,"context_line":"        if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1021,"context_line":"            # don\u0027t validate_first_segment on HEAD?"},{"line_number":1022,"context_line":"            resp_iter \u003d self._build_resp_iter(req, segments, slo_attrs,"},{"line_number":1023,"context_line":"                                              part_num)"},{"line_number":1024,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1025,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1026,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"f09954ba_c873c489","line":1023,"updated":"2023-09-27 18:32:28.000000000","message":"perhaps consider moving the changes in _build_resp_iter to a new helper method _update_req_for_part_num(req, segments, part_num) that is called first? That avoids changing the _build_resp_iter interface and can allows finer grained unit testing.","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":1020,"context_line":"        if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1021,"context_line":"            # don\u0027t validate_first_segment on HEAD?"},{"line_number":1022,"context_line":"            resp_iter \u003d self._build_resp_iter(req, segments, slo_attrs,"},{"line_number":1023,"context_line":"                                              part_num)"},{"line_number":1024,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1025,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1026,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"358cd454_e775d48d","line":1023,"in_reply_to":"8b747a62_41850760","updated":"2023-10-04 00:13:21.000000000","message":"Done","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":true,"context_lines":[{"line_number":1020,"context_line":"        if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1021,"context_line":"            # don\u0027t validate_first_segment on HEAD?"},{"line_number":1022,"context_line":"            resp_iter \u003d self._build_resp_iter(req, segments, slo_attrs,"},{"line_number":1023,"context_line":"                                              part_num)"},{"line_number":1024,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1025,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1026,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"8b747a62_41850760","line":1023,"in_reply_to":"f09954ba_c873c489","updated":"2023-09-29 15:04:53.000000000","message":"I did incorporate a refactor but in a different way which looked bette/more appealing to me in the form of introducing a helper method in _build_resp_iter with \n_calculate_byteranges","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f779c69132bb9c918820169d09e02e0a2de180d","unresolved":true,"context_lines":[{"line_number":1050,"context_line":"            json_data \u003d json_data.encode(\u0027utf-8\u0027)"},{"line_number":1051,"context_line":"        return json_data"},{"line_number":1052,"context_line":""},{"line_number":1053,"context_line":"    def _get_part_num(self, req, parts_count):"},{"line_number":1054,"context_line":"        \"\"\""},{"line_number":1055,"context_line":"         Parses the part num param from request and raises"},{"line_number":1056,"context_line":"         HTTPBadRequest if missing or invalid."}],"source_content_type":"text/x-python","patch_set":12,"id":"db632d80_e5a4830d","line":1053,"updated":"2023-09-27 18:32:28.000000000","message":"nit: please locate this method above the call site","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"            json_data \u003d json_data.encode(\u0027utf-8\u0027)"},{"line_number":1051,"context_line":"        return json_data"},{"line_number":1052,"context_line":""},{"line_number":1053,"context_line":"    def _get_part_num(self, req, parts_count):"},{"line_number":1054,"context_line":"        \"\"\""},{"line_number":1055,"context_line":"         Parses the part num param from request and raises"},{"line_number":1056,"context_line":"         HTTPBadRequest if missing or invalid."}],"source_content_type":"text/x-python","patch_set":12,"id":"ae2fdb98_18bec6e3","line":1053,"in_reply_to":"db632d80_e5a4830d","updated":"2023-09-29 15:04:53.000000000","message":"Done","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58a9e48c3a604ef9524d582c62cedce383265912","unresolved":true,"context_lines":[{"line_number":1119,"context_line":"                start +\u003d seg[\u0027segment_length\u0027]"},{"line_number":1120,"context_line":"            last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":1121,"context_line":"            byteranges \u003d [(start, last - 1)]"},{"line_number":1122,"context_line":"            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":1123,"context_line":"        else:"},{"line_number":1124,"context_line":"            byteranges \u003d [(0, slo_attrs.size - 1)]"},{"line_number":1125,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"6935e1c6_b5c2ba97","line":1122,"updated":"2023-09-28 00:28:39.000000000","message":"I think we talked about the fact that this needs to be set since s3api expects a 206 response from a part-num request and not a 200, which is why inline this range value being set.","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":1119,"context_line":"                start +\u003d seg[\u0027segment_length\u0027]"},{"line_number":1120,"context_line":"            last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":1121,"context_line":"            byteranges \u003d [(start, last - 1)]"},{"line_number":1122,"context_line":"            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":1123,"context_line":"        else:"},{"line_number":1124,"context_line":"            byteranges \u003d [(0, slo_attrs.size - 1)]"},{"line_number":1125,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"48610f84_8cb9f1e9","line":1122,"in_reply_to":"45af1504_0f9cc832","updated":"2023-10-04 00:13:21.000000000","message":"Done","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":true,"context_lines":[{"line_number":1119,"context_line":"                start +\u003d seg[\u0027segment_length\u0027]"},{"line_number":1120,"context_line":"            last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":1121,"context_line":"            byteranges \u003d [(start, last - 1)]"},{"line_number":1122,"context_line":"            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":1123,"context_line":"        else:"},{"line_number":1124,"context_line":"            byteranges \u003d [(0, slo_attrs.size - 1)]"},{"line_number":1125,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"45af1504_0f9cc832","line":1122,"in_reply_to":"54daf2bd_9f47972f","updated":"2023-10-02 18:51:40.000000000","message":"Because in the current tests we are doing assertions on 200s and not 206, when we run the s3api cross-compat tests we will see thos failure since it is a mismatch of 200 vs 206","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1119,"context_line":"                start +\u003d seg[\u0027segment_length\u0027]"},{"line_number":1120,"context_line":"            last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":1121,"context_line":"            byteranges \u003d [(start, last - 1)]"},{"line_number":1122,"context_line":"            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":1123,"context_line":"        else:"},{"line_number":1124,"context_line":"            byteranges \u003d [(0, slo_attrs.size - 1)]"},{"line_number":1125,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"54daf2bd_9f47972f","line":1122,"in_reply_to":"6935e1c6_b5c2ba97","updated":"2023-09-29 19:51:10.000000000","message":"maybe I just lost this in a rebase somewhere?  I don\u0027t this in the current patch - why don\u0027t any tests fail?","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if is_part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":846,"context_line":"            self.segments_needed \u003d True"},{"line_number":847,"context_line":"            # XXX do we ALWAYS need to refetch is_part_num!??"},{"line_number":848,"context_line":"            return True"},{"line_number":849,"context_line":""},{"line_number":850,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"}],"source_content_type":"text/x-python","patch_set":17,"id":"edd1a06d_f8d39e91","line":847,"updated":"2023-09-29 19:51:10.000000000","message":"no, only on HEAD","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":false,"context_lines":[{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if is_part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":846,"context_line":"            self.segments_needed \u003d True"},{"line_number":847,"context_line":"            # XXX do we ALWAYS need to refetch is_part_num!??"},{"line_number":848,"context_line":"            return True"},{"line_number":849,"context_line":""},{"line_number":850,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"}],"source_content_type":"text/x-python","patch_set":17,"id":"65018b82_4e6cedf4","line":847,"in_reply_to":"edd1a06d_f8d39e91","updated":"2023-10-02 18:51:40.000000000","message":"Ack","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":850,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":851,"context_line":"            # There may be some cases in the future where a HEAD resp on even a"},{"line_number":852,"context_line":"            # modern manifest should refetch, e.g. lp bug #2029174"},{"line_number":853,"context_line":"            self.segments_needed \u003d slo_attrs.is_legacy"},{"line_number":854,"context_line":"            # it will always be the case that a HEAD must re-fetch iff"},{"line_number":855,"context_line":"            # segments_needed"},{"line_number":856,"context_line":"            return self.segments_needed"}],"source_content_type":"text/x-python","patch_set":17,"id":"676fac11_a9066de5","line":853,"updated":"2023-09-29 19:51:10.000000000","message":"maybe it would make sense to deal with is_part_num for HEAD under this umbrealla for HEAD requests?\n\n    self.segments_needed \u003d slo_attrs.is_legacy or is_part_num","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":false,"context_lines":[{"line_number":850,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":851,"context_line":"            # There may be some cases in the future where a HEAD resp on even a"},{"line_number":852,"context_line":"            # modern manifest should refetch, e.g. lp bug #2029174"},{"line_number":853,"context_line":"            self.segments_needed \u003d slo_attrs.is_legacy"},{"line_number":854,"context_line":"            # it will always be the case that a HEAD must re-fetch iff"},{"line_number":855,"context_line":"            # segments_needed"},{"line_number":856,"context_line":"            return self.segments_needed"}],"source_content_type":"text/x-python","patch_set":17,"id":"b64d355d_cb49061e","line":853,"in_reply_to":"676fac11_a9066de5","updated":"2023-10-02 18:51:40.000000000","message":"Ack","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":973,"context_line":"        replace_headers \u003d {"},{"line_number":974,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":975,"context_line":"            \u0027X-Parts-Count\u0027: parts_count,"},{"line_number":976,"context_line":"        }"},{"line_number":977,"context_line":"        return HeaderKeyDict(self._response_headers, **replace_headers)"},{"line_number":978,"context_line":""},{"line_number":979,"context_line":"    def _validate_part_number(self, part_number_param, parts_count, req,"}],"source_content_type":"text/x-python","patch_set":17,"id":"0ab262b2_445354a0","line":976,"updated":"2023-09-29 19:51:10.000000000","message":"seems to have some overlap with the logic in _return_slo_response","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":true,"context_lines":[{"line_number":973,"context_line":"        replace_headers \u003d {"},{"line_number":974,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":975,"context_line":"            \u0027X-Parts-Count\u0027: parts_count,"},{"line_number":976,"context_line":"        }"},{"line_number":977,"context_line":"        return HeaderKeyDict(self._response_headers, **replace_headers)"},{"line_number":978,"context_line":""},{"line_number":979,"context_line":"    def _validate_part_number(self, part_number_param, parts_count, req,"}],"source_content_type":"text/x-python","patch_set":17,"id":"714bc444_9dc2e2f9","line":976,"in_reply_to":"0ab262b2_445354a0","updated":"2023-10-02 18:51:40.000000000","message":"I understand that, figuring out a way to work on what you mentioned here. ref: https://review.opendev.org/c/openstack/swift/+/894570/comments/4f3d9e64_f5b55826","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ac249d71cb5cf9c725562c38c92082633e6fc3e7","unresolved":true,"context_lines":[{"line_number":973,"context_line":"        replace_headers \u003d {"},{"line_number":974,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":975,"context_line":"            \u0027X-Parts-Count\u0027: parts_count,"},{"line_number":976,"context_line":"        }"},{"line_number":977,"context_line":"        return HeaderKeyDict(self._response_headers, **replace_headers)"},{"line_number":978,"context_line":""},{"line_number":979,"context_line":"    def _validate_part_number(self, part_number_param, parts_count, req,"}],"source_content_type":"text/x-python","patch_set":17,"id":"f752ab20_f93c2840","line":976,"in_reply_to":"714bc444_9dc2e2f9","updated":"2023-10-03 20:43:38.000000000","message":"Maybe we don\u0027t need this logic at all with my earlier comment about how s3api responds maybe all we need to do is raise a `ValueError` and bail, i could refactor the existing tests for coverage, ref: https://review.opendev.org/c/openstack/swift/+/894570/comment/835ba227_dcd5378b/","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c3396e3340b36b8c7c80196b8cfb4247df5e0dc0","unresolved":false,"context_lines":[{"line_number":973,"context_line":"        replace_headers \u003d {"},{"line_number":974,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":975,"context_line":"            \u0027X-Parts-Count\u0027: parts_count,"},{"line_number":976,"context_line":"        }"},{"line_number":977,"context_line":"        return HeaderKeyDict(self._response_headers, **replace_headers)"},{"line_number":978,"context_line":""},{"line_number":979,"context_line":"    def _validate_part_number(self, part_number_param, parts_count, req,"}],"source_content_type":"text/x-python","patch_set":17,"id":"63d2505c_7ce60d3d","line":976,"in_reply_to":"f752ab20_f93c2840","updated":"2023-10-04 00:31:27.000000000","message":"Done","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1019,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":1020,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":1021,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":1022,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1023,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1024,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":1025,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":17,"id":"bb0e99ab_c9469e31","line":1022,"updated":"2023-09-29 19:51:10.000000000","message":"how does this work for range requests?","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ac249d71cb5cf9c725562c38c92082633e6fc3e7","unresolved":false,"context_lines":[{"line_number":1019,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":1020,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":1021,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":1022,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1023,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1024,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":1025,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":17,"id":"84571803_8f6a56e5","line":1022,"in_reply_to":"bb0e99ab_c9469e31","updated":"2023-10-03 20:43:38.000000000","message":"For range requests swob takes care of the calculation by using ranges_for_length defined here, ref: https://github.com/NVIDIA/swift/blob/master/swift/common/swob.py#L596","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1024,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":1025,"context_line":"        }"},{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":17,"id":"fda5190d_a907849b","line":1027,"updated":"2023-09-29 19:51:10.000000000","message":"but i don\u0027t know how you get this header in here conditionally on being a part-num response","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"127208f70c1765f487508961cf6dda6a5ca02aff","unresolved":false,"context_lines":[{"line_number":1024,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":1025,"context_line":"        }"},{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":17,"id":"e1f96a93_86773079","line":1027,"in_reply_to":"15cdbdf3_5639822d","updated":"2023-10-02 20:08:40.000000000","message":"I think only all part-number responses; other-wise we\u0027d always have to parse the manifest since we don\u0027t know how many parts there are generally","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":false,"context_lines":[{"line_number":1024,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":1025,"context_line":"        }"},{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":17,"id":"15cdbdf3_5639822d","line":1027,"in_reply_to":"fda5190d_a907849b","updated":"2023-10-02 18:51:40.000000000","message":"Now I understand correctly, we want this header for all standard responses","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1031,"context_line":"                                     replace_headers)"},{"line_number":1032,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"fd912630_a1ac231d","line":1029,"updated":"2023-09-29 19:51:10.000000000","message":"is this needed?","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"127208f70c1765f487508961cf6dda6a5ca02aff","unresolved":true,"context_lines":[{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1031,"context_line":"                                     replace_headers)"},{"line_number":1032,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"54faa698_c31e4b39","line":1029,"in_reply_to":"4ee0a3a2_5fe70d28","updated":"2023-10-02 20:08:40.000000000","message":"That\u0027s a bummer.  Is that because swob doesn\u0027t support doing the Content-length calculation for HEAD requess with a Range header?","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"eae6b9059dc54527aad887fcdd32cffa9e028d53","unresolved":false,"context_lines":[{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1031,"context_line":"                                     replace_headers)"},{"line_number":1032,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"bef5c63d_1fc87bd7","line":1029,"in_reply_to":"54faa698_c31e4b39","updated":"2023-10-03 20:36:37.000000000","message":"Yes, precisely so.","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":true,"context_lines":[{"line_number":1026,"context_line":"        if part_num:"},{"line_number":1027,"context_line":"            replace_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1028,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1029,"context_line":"                \u0027segment_length\u0027)"},{"line_number":1030,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1031,"context_line":"                                     replace_headers)"},{"line_number":1032,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"4ee0a3a2_5fe70d28","line":1029,"in_reply_to":"fd912630_a1ac231d","updated":"2023-10-02 18:51:40.000000000","message":"This isn\u0027t needed but as i said earlier s3api treats part-num requests as conent-range requests so  when i set the range for the request as:\n```\n        elif part_num:\n            start \u003d 0\n            for seg in segments[:part_num - 1]:\n                start +\u003d seg[\u0027segment_length\u0027]\n            last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]\n            byteranges \u003d [(start, last - 1)]\n            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)\n```\n\nswob takes care of calculating the content-length for the responses for GET part-num requests but doesn\u0027t it do so for HEAD part-num req\u0027s","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1109,"context_line":"                # we\u0027ll need a slo response body, and we don\u0027t validate the"},{"line_number":1110,"context_line":"                # frist segment on HEAD"},{"line_number":1111,"context_line":"                resp_iter \u003d self._build_resp_iter(req, segments, slo_attrs,"},{"line_number":1112,"context_line":"                                                  part_num)"},{"line_number":1113,"context_line":"        else:"},{"line_number":1114,"context_line":"            # if we\u0027d\u0027ve needed the segments we\u0027d\u0027ve refetched them without"},{"line_number":1115,"context_line":"            # conditions already, so this is a HEAD or conditional response"}],"source_content_type":"text/x-python","patch_set":17,"id":"a2f98303_7de4b30f","line":1112,"updated":"2023-09-29 19:51:10.000000000","message":"passing part_num to _buil_resp_iter actually seemed perfectly reasoable","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":false,"context_lines":[{"line_number":1109,"context_line":"                # we\u0027ll need a slo response body, and we don\u0027t validate the"},{"line_number":1110,"context_line":"                # frist segment on HEAD"},{"line_number":1111,"context_line":"                resp_iter \u003d self._build_resp_iter(req, segments, slo_attrs,"},{"line_number":1112,"context_line":"                                                  part_num)"},{"line_number":1113,"context_line":"        else:"},{"line_number":1114,"context_line":"            # if we\u0027d\u0027ve needed the segments we\u0027d\u0027ve refetched them without"},{"line_number":1115,"context_line":"            # conditions already, so this is a HEAD or conditional response"}],"source_content_type":"text/x-python","patch_set":17,"id":"b77d4d78_9b34e658","line":1112,"in_reply_to":"a2f98303_7de4b30f","updated":"2023-10-02 18:51:40.000000000","message":"Ack","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1117,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1118,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1119,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1120,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1121,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1122,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1123,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"01eac486_5836b75b","line":1120,"updated":"2023-09-29 19:51:10.000000000","message":"... this was actually the part that bugged me","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"127208f70c1765f487508961cf6dda6a5ca02aff","unresolved":true,"context_lines":[{"line_number":1117,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1118,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1119,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1120,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1121,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1122,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1123,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"249ea21e_2f8b60d2","line":1120,"in_reply_to":"01eac486_5836b75b","updated":"2023-10-02 20:08:40.000000000","message":"i\u0027m not sure what to do about it\n\nif there\u0027s some headers that ONLY get added if you pass through the block above (because they\u0027re based on segments/part-num) maybe it would be better to have a single self.extra_replace_headers and less args to _return_slo_response\n\n... even if that means we have to look extra places for all the headers that get modified on the way out; not sure.","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ac249d71cb5cf9c725562c38c92082633e6fc3e7","unresolved":true,"context_lines":[{"line_number":1117,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1118,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1119,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1120,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1121,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1122,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1123,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"7ca139df_a2e2be6b","line":1120,"in_reply_to":"249ea21e_2f8b60d2","updated":"2023-10-03 20:43:38.000000000","message":"Currently, we have two different paths for when we err on a part-num response and when we don\u0027t , are you saying we want the header manipulation to occur in a separate call; Also i am reconsidering having any err_resp headers for part-num requests since s3api doesn\u0027t seem to do so!","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c3396e3340b36b8c7c80196b8cfb4247df5e0dc0","unresolved":false,"context_lines":[{"line_number":1117,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1118,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1119,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1120,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1121,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1122,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1123,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"df3611cf_ecf7931d","line":1120,"in_reply_to":"7ca139df_a2e2be6b","updated":"2023-10-04 00:31:27.000000000","message":"Done","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"69aaa6209f10539a4ccdaf16f0df81f4138823e5","unresolved":true,"context_lines":[{"line_number":1202,"context_line":"        :returns: a segmented iterable"},{"line_number":1203,"context_line":"        \"\"\""},{"line_number":1204,"context_line":"        byteranges \u003d self._calculate_byteranges(req, segments, slo_attrs,"},{"line_number":1205,"context_line":"                                                part_num)"},{"line_number":1206,"context_line":""},{"line_number":1207,"context_line":"        ver, account, _junk \u003d req.split_path(3, 3, rest_with_last\u003dTrue)"},{"line_number":1208,"context_line":"        account \u003d wsgi_to_str(account)"}],"source_content_type":"text/x-python","patch_set":17,"id":"2b24ce50_835e9b69","line":1205,"updated":"2023-09-29 19:51:10.000000000","message":"ah, so now i could see _build_resp_iter just taking byteranges instead of slo_attrs and part_num!","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3e24cfd542f1a61aad36c1ee36530ad2b8984ac2","unresolved":false,"context_lines":[{"line_number":1202,"context_line":"        :returns: a segmented iterable"},{"line_number":1203,"context_line":"        \"\"\""},{"line_number":1204,"context_line":"        byteranges \u003d self._calculate_byteranges(req, segments, slo_attrs,"},{"line_number":1205,"context_line":"                                                part_num)"},{"line_number":1206,"context_line":""},{"line_number":1207,"context_line":"        ver, account, _junk \u003d req.split_path(3, 3, rest_with_last\u003dTrue)"},{"line_number":1208,"context_line":"        account \u003d wsgi_to_str(account)"}],"source_content_type":"text/x-python","patch_set":17,"id":"eeec8f61_1be7e9f6","line":1205,"in_reply_to":"2b24ce50_835e9b69","updated":"2023-10-02 18:51:40.000000000","message":"Ack","commit_id":"d5b092d28d548ea6dd0fdecb5ec44fcee4057085"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"127208f70c1765f487508961cf6dda6a5ca02aff","unresolved":true,"context_lines":[{"line_number":1017,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1018,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1019,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":1020,"context_line":"            \u0027X-Parts-Count\u0027: len(segments) if segments is not None else None,"},{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("}],"source_content_type":"text/x-python","patch_set":20,"id":"835ba227_dcd5378b","line":1020,"updated":"2023-10-02 20:08:40.000000000","message":"maybe we just have `_get_slo_response_headers(req, slo_attrs, part_num, segments)` and re-use it both in `_return_slo_repsonse` and `_get_part_num` (which an raise a Error response)\n\nI don\u0027t think we want x-parts-count to sometimes be None; maybe we don\u0027t have to have it on every response i.e. I\u0027m curious if AWS includes x-parts-count with responses to invalid requests like `part-number\u003dfoo` or `part-number\u003d-1`","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e9fd8e3c1a276dcef2802484b5d3d8849ada1d13","unresolved":true,"context_lines":[{"line_number":1017,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1018,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1019,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":1020,"context_line":"            \u0027X-Parts-Count\u0027: len(segments) if segments is not None else None,"},{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("}],"source_content_type":"text/x-python","patch_set":20,"id":"b188d21b_41f6e711","line":1020,"in_reply_to":"2cad87c6_b1649c7f","updated":"2023-10-03 21:48:57.000000000","message":"is that AWS responses or s3api responses - this code makes it LOOK like we always send back the (sometimes empty) x-parts-count header\n\nif some sanitization code in swob or something makes it so that empty headers aren\u0027t returned over HTTP and our behavior is correct despite the code LOOKING wrong - that\u0027s only half good.  It would be worse if unittests make it seems like we return the empty heder and function tests don\u0027t get it at all - how well is this covered in tests?","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0c3ac650e250198ff20f755e0a566aeb58534ba2","unresolved":true,"context_lines":[{"line_number":1017,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1018,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1019,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":1020,"context_line":"            \u0027X-Parts-Count\u0027: len(segments) if segments is not None else None,"},{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("}],"source_content_type":"text/x-python","patch_set":20,"id":"fe97914e_7338a6b1","line":1020,"in_reply_to":"835ba227_dcd5378b","updated":"2023-10-03 19:46:31.000000000","message":"It doesn\u0027t, all it says is the following which is what i would prefer as well.\n```\naws s3api get-object --bucket ash-test-mpu --key test.mp4 --part-number -1 outfile\n\nAn error occurred (InvalidArgument) when calling the GetObject operation: Part number must be an integer between 1 and 10000, inclusive\n```","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":1017,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1018,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1019,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":1020,"context_line":"            \u0027X-Parts-Count\u0027: len(segments) if segments is not None else None,"},{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("}],"source_content_type":"text/x-python","patch_set":20,"id":"0d63fc11_047f29dd","line":1020,"in_reply_to":"b188d21b_41f6e711","updated":"2023-10-04 00:13:21.000000000","message":"ahh i though, i took care of that, my bad should be fixed in the next patchset iteration","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c3ab32fe3e646cb9cb2acab1ef6f7aa70b0a24b1","unresolved":true,"context_lines":[{"line_number":1017,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":1018,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1019,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":1020,"context_line":"            \u0027X-Parts-Count\u0027: len(segments) if segments is not None else None,"},{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("}],"source_content_type":"text/x-python","patch_set":20,"id":"2cad87c6_b1649c7f","line":1020,"in_reply_to":"fe97914e_7338a6b1","updated":"2023-10-03 19:51:06.000000000","message":"We also only get PArtsCount in the response when --part-number is involved:\n```\nashnair@ashnair-mlt ~ % nvaws s3api head-object --bucket ash-test-mpu --key test.mp4 --part-number 3\n{\n    \"AcceptRanges\": \"bytes\",\n    \"LastModified\": \"Wed, 28 Jun 2023 23:23:21 GMT\",\n    \"ContentLength\": 8388608,\n    \"ETag\": \"\\\"b6b71c18174097757f34243aae46b047-16\\\"\",\n    \"ContentType\": \"video/mp4\",\n    \"ServerSideEncryption\": \"AES256\",\n    \"Metadata\": {},\n    \"PartsCount\": 16\n}\nashnair@ashnair-mlt ~ % nvaws s3api head-object --bucket ash-test-mpu --key test.mp4\n\n{\n    \"AcceptRanges\": \"bytes\",\n    \"LastModified\": \"Wed, 28 Jun 2023 23:23:21 GMT\",\n    \"ContentLength\": 126501763,\n    \"ETag\": \"\\\"b6b71c18174097757f34243aae46b047-16\\\"\",\n    \"ContentType\": \"video/mp4\",\n    \"ServerSideEncryption\": \"AES256\",\n    \"Metadata\": {}\n}\n```","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"127208f70c1765f487508961cf6dda6a5ca02aff","unresolved":true,"context_lines":[{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1024,"context_line":"                    \u0027segment_length\u0027)"},{"line_number":1025,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1026,"context_line":"                                     replace_headers)"},{"line_number":1027,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"70ebf8cb_ccdc9772","line":1024,"updated":"2023-10-02 20:08:40.000000000","message":"i\u0027m not sure if it\u0027s more or less confusing that we set Content-Length \u003d slo.size in the block above and the over-ride it for part-number (but only HEAD)\n\nThere\u0027s a comment about swob fixing content-length for range responses (and so I assume part-number responses) - but maybe swob doesn\u0027t go far enough on HEAD","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"eae6b9059dc54527aad887fcdd32cffa9e028d53","unresolved":false,"context_lines":[{"line_number":1021,"context_line":"        }"},{"line_number":1022,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1023,"context_line":"            replace_headers[\u0027Content-Length\u0027] \u003d segments[part_num - 1].get("},{"line_number":1024,"context_line":"                    \u0027segment_length\u0027)"},{"line_number":1025,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1026,"context_line":"                                     replace_headers)"},{"line_number":1027,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"b0ac3a25_182e414d","line":1024,"in_reply_to":"70ebf8cb_ccdc9772","updated":"2023-10-03 20:36:37.000000000","message":"Because we want the content-length set the way s3api expects in the repsonse which we don\u0027t get unless i add this \"extra assignment\", since slo_attrs.size stores the whole length of the object and we only want the part-size as illustrated in the example below:\n```\ncurl --location --head \u0027http://saio:8090/v1/AUTH_test/testpart/test.mp4\u0027 --header \u0027X-Auth-Token: \u0027\nHTTP/1.1 200 OK\nContent-Type: video/mp4\nX-Static-Large-Object: True\nEtag: \"1b65c3ae1712a9ff2e1f0c075af0ec95\"\nLast-Modified: Mon, 02 Oct 2023 20:05:24 GMT\nX-Timestamp: 1696277123.91704\nAccept-Ranges: bytes\nContent-Length: 126501763\nX-Manifest-Etag: 889f2809958e5e076f06fd5ef11f7adf\nX-Trans-Id: txbbc516a92dad46c98678f-00651c7a8f\nX-Openstack-Request-Id: txbbc516a92dad46c98678f-00651c7a8f\nDate: Tue, 03 Oct 2023 20:33:19 GMT\n\nvagrant@vagrant:~$ curl --location --head \u0027http://saio:8090/v1/AUTH_test/testpart/test.mp4?part-number\u003d2\u0027 --header \u0027X-Auth-Token: \u0027\nHTTP/1.1 200 OK\nContent-Type: video/mp4\nX-Static-Large-Object: True\nEtag: \"1b65c3ae1712a9ff2e1f0c075af0ec95\"\nLast-Modified: Mon, 02 Oct 2023 20:05:24 GMT\nX-Timestamp: 1696277123.91704\nAccept-Ranges: bytes\nContent-Length: 31625440\nX-Manifest-Etag: 889f2809958e5e076f06fd5ef11f7adf\nX-Parts-Count: 4\nX-Trans-Id: txc6983c582d3b427ebe87c-00651c7a9d\nX-Openstack-Request-Id: txc6983c582d3b427ebe87c-00651c7a9d\nDate: Tue, 03 Oct 2023 20:33:33 GMT\n```\n\nwhen i remove that block the content-length response be the same as the original object:\n\n```\ncurl --location --head \u0027http://saio:8090/v1/AUTH_test/testpart/test.mp4?part-number\u003d2\u0027 --header \u0027X-Auth-Token: AUTH_tkf5f1028acf36494c8086f79612ea4da0\u0027\nHTTP/1.1 200 OK\nContent-Type: video/mp4\nX-Static-Large-Object: True\nEtag: \"1b65c3ae1712a9ff2e1f0c075af0ec95\"\nLast-Modified: Mon, 02 Oct 2023 20:05:24 GMT\nX-Timestamp: 1696277123.91704\nAccept-Ranges: bytes\nContent-Length: 126501763 (size of original object and not the part)\nX-Manifest-Etag: 889f2809958e5e076f06fd5ef11f7adf\nX-Parts-Count: 4\nX-Trans-Id: tx3790390636324270a3342-00651c7b28\nX-Openstack-Request-Id: tx3790390636324270a3342-00651c7b28\nDate: Tue, 03 Oct 2023 20:35:52 GMT\n```","commit_id":"669093798f313846e399dbccaa5c341bc9a31602"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e9fd8e3c1a276dcef2802484b5d3d8849ada1d13","unresolved":true,"context_lines":[{"line_number":651,"context_line":"        if part_number \u003d\u003d 0:"},{"line_number":652,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":653,"context_line":"                request\u003dreq,"},{"line_number":654,"context_line":"                body\u003d\u0027Invalid part-number query param\u0027)"},{"line_number":655,"context_line":"        if part_number \u003c 1 or parts_count \u003c part_number:"},{"line_number":656,"context_line":"            raise ValueError()"},{"line_number":657,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":21,"id":"82db02b6_e86374a0","line":654,"updated":"2023-10-03 21:48:57.000000000","message":"so part-number in (\u0027foo\u0027, \u0027-1\u0027, \u002710000000000000000\u0027) all raise BadRequest, but part-number \u003d\u003d \u00270\u0027 is a special case that returns 416; interesting.","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":651,"context_line":"        if part_number \u003d\u003d 0:"},{"line_number":652,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":653,"context_line":"                request\u003dreq,"},{"line_number":654,"context_line":"                body\u003d\u0027Invalid part-number query param\u0027)"},{"line_number":655,"context_line":"        if part_number \u003c 1 or parts_count \u003c part_number:"},{"line_number":656,"context_line":"            raise ValueError()"},{"line_number":657,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":21,"id":"7558173f_935c3209","line":654,"in_reply_to":"82db02b6_e86374a0","updated":"2023-10-04 00:13:21.000000000","message":"That\u0027s a very good catch, aws actually returns a 400 as illustrated below:\n```\n2023-10-03 16:29:39,971 - MainThread - urllib3.connectionpool - DEBUG - https://ash-test-mpu.s3.us-east-1.amazonaws.com:443 \"HEAD /test.mp4?partNumber\u003d0 HTTP/1.1\" 400 0\n2023-10-03 16:29:39,972 - MainThread - botocore.parsers - DEBUG - Response headers: {\u0027x-amz-request-id\u0027: \u00273SCMF7VX6BNXV6Z3\u0027, \u0027x-amz-id-2\u0027: \u002778aaJ2D2xP/AlAgbaQ5mwTI1wIPbuv8uGrdApt4OZswW1urJ3qK3YVGFhxKRtaBQBI5gCOgWDrM\u003d\u0027, \u0027Content-Type\u0027: \u0027application/xml\u0027, \u0027Date\u0027: \u0027Tue, 03 Oct 2023 23:29:39 GMT\u0027, \u0027Server\u0027: \u0027AmazonS3\u0027, \u0027Connection\u0027: \u0027close\u0027}\n```","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e9fd8e3c1a276dcef2802484b5d3d8849ada1d13","unresolved":true,"context_lines":[{"line_number":652,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":653,"context_line":"                request\u003dreq,"},{"line_number":654,"context_line":"                body\u003d\u0027Invalid part-number query param\u0027)"},{"line_number":655,"context_line":"        if part_number \u003c 1 or parts_count \u003c part_number:"},{"line_number":656,"context_line":"            raise ValueError()"},{"line_number":657,"context_line":"    except ValueError:"},{"line_number":658,"context_line":"        err_msg \u003d \u0027Invalid part-number query param\u0027"}],"source_content_type":"text/x-python","patch_set":21,"id":"57e1f6a5_7f22c8de","line":655,"updated":"2023-10-03 21:48:57.000000000","message":"I think python let\u0027s you write this as `it 1 \u003c part_number \u003c parts_count:`","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":652,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":653,"context_line":"                request\u003dreq,"},{"line_number":654,"context_line":"                body\u003d\u0027Invalid part-number query param\u0027)"},{"line_number":655,"context_line":"        if part_number \u003c 1 or parts_count \u003c part_number:"},{"line_number":656,"context_line":"            raise ValueError()"},{"line_number":657,"context_line":"    except ValueError:"},{"line_number":658,"context_line":"        err_msg \u003d \u0027Invalid part-number query param\u0027"}],"source_content_type":"text/x-python","patch_set":21,"id":"bde3b501_52d42288","line":655,"in_reply_to":"57e1f6a5_7f22c8de","updated":"2023-10-04 00:13:21.000000000","message":"noted.","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":948,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":949,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":950,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":951,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":952,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":953,"context_line":"        }"},{"line_number":954,"context_line":"        return self._return_response(req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":25,"id":"85acf22a_6f74a97d","side":"PARENT","line":951,"updated":"2023-10-10 17:22:15.000000000","message":"there\u0027s a couple of comment here we lost - I\u0027m not sure they were wrong/bad?  I think i\u0027d prefer they stay unless you had some justification to pull them out?","commit_id":"827a727abc30d969721681ce8458529a19d5e34c"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba552ce0b054f0566f85d26223fc0d786ae186b8","unresolved":false,"context_lines":[{"line_number":948,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":949,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":950,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":951,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":952,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":953,"context_line":"        }"},{"line_number":954,"context_line":"        return self._return_response(req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":25,"id":"65fffaa6_dac67471","side":"PARENT","line":951,"in_reply_to":"85acf22a_6f74a97d","updated":"2023-10-11 00:15:47.000000000","message":"Ack","commit_id":"827a727abc30d969721681ce8458529a19d5e34c"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba552ce0b054f0566f85d26223fc0d786ae186b8","unresolved":false,"context_lines":[{"line_number":948,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":949,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":950,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":951,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":952,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":953,"context_line":"        }"},{"line_number":954,"context_line":"        return self._return_response(req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":25,"id":"56463377_bc5c04c3","side":"PARENT","line":951,"in_reply_to":"85acf22a_6f74a97d","updated":"2023-10-11 00:15:47.000000000","message":"Done","commit_id":"827a727abc30d969721681ce8458529a19d5e34c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":645,"context_line":"    \"\"\""},{"line_number":646,"context_line":"    try:"},{"line_number":647,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":648,"context_line":"        if part_number \u003e parts_count or part_number \u003c\u003d 0 \\"},{"line_number":649,"context_line":"                or not isinstance(part_number, int):"},{"line_number":650,"context_line":"            raise ValueError()"},{"line_number":651,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":25,"id":"b7b94ac1_0d31e6eb","line":648,"updated":"2023-10-10 17:22:15.000000000","message":"this part-number \u003e parts_count is the only validation that requires we\u0027d have actually parsed the manifest; I wonder if this method could support it as an *optional* kwarg?  Like:\n\n```\nget_part_num(req) \u003d\u003e raises error if invalid (or \u003e 1000)\nget_part_num(req, parts_count) \u003d\u003e raises error if invalid (and additionally raises error if \u003e arbitrarily lower limit)\n```","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ec32bb3ab514d390e1f4636d235896933d449d84","unresolved":false,"context_lines":[{"line_number":645,"context_line":"    \"\"\""},{"line_number":646,"context_line":"    try:"},{"line_number":647,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":648,"context_line":"        if part_number \u003e parts_count or part_number \u003c\u003d 0 \\"},{"line_number":649,"context_line":"                or not isinstance(part_number, int):"},{"line_number":650,"context_line":"            raise ValueError()"},{"line_number":651,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":25,"id":"74dfba9c_40c38069","line":648,"in_reply_to":"b7b94ac1_0d31e6eb","updated":"2023-10-16 18:07:57.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":646,"context_line":"    try:"},{"line_number":647,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":648,"context_line":"        if part_number \u003e parts_count or part_number \u003c\u003d 0 \\"},{"line_number":649,"context_line":"                or not isinstance(part_number, int):"},{"line_number":650,"context_line":"            raise ValueError()"},{"line_number":651,"context_line":"    except ValueError:"},{"line_number":652,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"}],"source_content_type":"text/x-python","patch_set":25,"id":"9ab9f622_e226e935","line":649,"updated":"2023-10-10 17:22:15.000000000","message":"how can int(part_number_para) result in anything that\u0027s not an int?  this extra isisntance check is confusing/useless.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"236fb38657f6636c91fce0bed37ca64a414fa509","unresolved":false,"context_lines":[{"line_number":646,"context_line":"    try:"},{"line_number":647,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":648,"context_line":"        if part_number \u003e parts_count or part_number \u003c\u003d 0 \\"},{"line_number":649,"context_line":"                or not isinstance(part_number, int):"},{"line_number":650,"context_line":"            raise ValueError()"},{"line_number":651,"context_line":"    except ValueError:"},{"line_number":652,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"}],"source_content_type":"text/x-python","patch_set":25,"id":"bac7542c_e440b09b","line":649,"in_reply_to":"9ab9f622_e226e935","updated":"2023-10-10 23:06:56.000000000","message":"Ack","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":650,"context_line":"            raise ValueError()"},{"line_number":651,"context_line":"    except ValueError:"},{"line_number":652,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":653,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":654,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":655,"context_line":""},{"line_number":656,"context_line":"    return part_number"}],"source_content_type":"text/x-python","patch_set":25,"id":"1d6ff1e6_a8d63903","line":653,"updated":"2023-10-10 17:22:15.000000000","message":"should we put `parts_count` in this error message?  Is this the error that s3api returns?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"236fb38657f6636c91fce0bed37ca64a414fa509","unresolved":false,"context_lines":[{"line_number":650,"context_line":"            raise ValueError()"},{"line_number":651,"context_line":"    except ValueError:"},{"line_number":652,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":653,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":654,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":655,"context_line":""},{"line_number":656,"context_line":"    return part_number"}],"source_content_type":"text/x-python","patch_set":25,"id":"fe92df28_77637456","line":653,"in_reply_to":"1d6ff1e6_a8d63903","updated":"2023-10-10 23:06:56.000000000","message":"No we don\u0027t have parts count in the s3 error response! But if the parts_num param exceeds the parts_count we get a 416 from s3api not a 400 so this was a good catch as illustrated below:\n```\n2023-10-10 15:46:45,453 - MainThread - urllib3.connectionpool - DEBUG - https://ash-test-mpu.s3.us-east-1.amazonaws.com:443 \"GET /test.mp4?partNumber\u003d100 HTTP/1.1\" 416 None\n2023-10-10 15:46:45,455 - MainThread - botocore.parsers - DEBUG - Response headers: {\u0027x-amz-request-id\u0027: \u0027Z1TYJBE4655K9RYS\u0027, \u0027x-amz-id-2\u0027: \u0027t+c9ekK2t1RojR63tlkl/BUkVmAtw2UJIBx2k8SbpUZ36URpAdyNnBhkmQ+rPU0JY/TpYW1zwcE\u003d\u0027, \u0027Content-Type\u0027: \u0027application/xml\u0027, \u0027Transfer-Encoding\u0027: \u0027chunked\u0027, \u0027Date\u0027: \u0027Tue, 10 Oct 2023 22:46:44 GMT\u0027, \u0027Server\u0027: \u0027AmazonS3\u0027}\n2023-10-10 15:46:45,455 - MainThread - botocore.parsers - DEBUG - Response body:\nb\u0027\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\"?\u003e\\n\u003cError\u003e\u003cCode\u003eInvalidPartNumber\u003c/Code\u003e\u003cMessage\u003eThe requested partnumber is not satisfiable\u003c/Message\u003e\u003cPartNumberRequested\u003e100\u003c/PartNumberRequested\u003e\u003cActualPartCount\u003e8\u003c/ActualPartCount\u003e\u003cRequestId\u003eZ1TYJBE4655K9RYS\u003c/RequestId\u003e\u003cHostId\u003et+c9ekK2t1RojR63tlkl/BUkVmAtw2UJIBx2k8SbpUZ36URpAdyNnBhkmQ+rPU0JY/TpYW1zwcE\u003d\u003c/HostId\u003e\u003c/Error\u003e\u0027\n```","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":651,"context_line":"    except ValueError:"},{"line_number":652,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":653,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":654,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":655,"context_line":""},{"line_number":656,"context_line":"    return part_number"},{"line_number":657,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"f6f39db7_44dabb5f","line":654,"updated":"2023-10-10 17:22:15.000000000","message":"we don\u0027t have to add any special headers?  Does s3api not return an x-parts-count header when you ask for part-number\u003d100 on a MPU with only 10 segments?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"75382dc3814b6af1a15d2420df340c3631800e74","unresolved":false,"context_lines":[{"line_number":651,"context_line":"    except ValueError:"},{"line_number":652,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":653,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":654,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":655,"context_line":""},{"line_number":656,"context_line":"    return part_number"},{"line_number":657,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"6184a9f2_d780fc3e","line":654,"in_reply_to":"f6f39db7_44dabb5f","updated":"2023-10-12 00:33:39.000000000","message":"No, in s3api we do not return any special headers in the error responses","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":868,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":869,"context_line":"            # There may be some cases in the future where a HEAD resp on even a"},{"line_number":870,"context_line":"            # modern manifest should refetch, e.g. lp bug #2029174"},{"line_number":871,"context_line":"            self.segment_listing_needed \u003d slo_attrs.is_legacy or is_part_num"},{"line_number":872,"context_line":"            # it will always be the case that a HEAD must re-fetch iff"},{"line_number":873,"context_line":"            # segment_listing_needed"},{"line_number":874,"context_line":"            return self.segment_listing_needed"}],"source_content_type":"text/x-python","patch_set":25,"id":"90ffa219_543fd886","line":871,"updated":"2023-10-10 17:22:15.000000000","message":"I think the comment could be updated - there\u0027s now a specific example of when a HEAD request has to refetch a modern-manifest ... is_part_num!","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"2ddb78b2d89be10c5577cd93212c5d2308b8384b","unresolved":false,"context_lines":[{"line_number":868,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":869,"context_line":"            # There may be some cases in the future where a HEAD resp on even a"},{"line_number":870,"context_line":"            # modern manifest should refetch, e.g. lp bug #2029174"},{"line_number":871,"context_line":"            self.segment_listing_needed \u003d slo_attrs.is_legacy or is_part_num"},{"line_number":872,"context_line":"            # it will always be the case that a HEAD must re-fetch iff"},{"line_number":873,"context_line":"            # segment_listing_needed"},{"line_number":874,"context_line":"            return self.segment_listing_needed"}],"source_content_type":"text/x-python","patch_set":25,"id":"78ff8de8_6600e91c","line":871,"in_reply_to":"90ffa219_543fd886","updated":"2023-10-13 23:44:40.000000000","message":"Ack","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":967,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":968,"context_line":"                                     replace_headers)"},{"line_number":969,"context_line":""},{"line_number":970,"context_line":"    def _get_part_num(self, req, parts_count, slo_attrs):"},{"line_number":971,"context_line":"        part_number_param \u003d get_param(req, \u0027part-number\u0027)"},{"line_number":972,"context_line":"        if part_number_param is None:"},{"line_number":973,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":25,"id":"8f8f9794_05c024fd","line":970,"updated":"2023-10-10 17:22:15.000000000","message":"slo_attrs param un-used?  I wonder if maybe parts_count should become a SloAttr - it\u0027d only be available IF we\u0027ve parsed the manifest (similar to size/etag on legacy manifests)","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba552ce0b054f0566f85d26223fc0d786ae186b8","unresolved":false,"context_lines":[{"line_number":967,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":968,"context_line":"                                     replace_headers)"},{"line_number":969,"context_line":""},{"line_number":970,"context_line":"    def _get_part_num(self, req, parts_count, slo_attrs):"},{"line_number":971,"context_line":"        part_number_param \u003d get_param(req, \u0027part-number\u0027)"},{"line_number":972,"context_line":"        if part_number_param is None:"},{"line_number":973,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":25,"id":"f713dd26_eff24bb9","line":970,"in_reply_to":"8f8f9794_05c024fd","updated":"2023-10-11 00:15:47.000000000","message":"Ack","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":973,"context_line":"            return None"},{"line_number":974,"context_line":""},{"line_number":975,"context_line":"        part_number \u003d _validate_part_number(part_number_param, parts_count)"},{"line_number":976,"context_line":"        return part_number"},{"line_number":977,"context_line":""},{"line_number":978,"context_line":"    def _prepare_slo_headers(self, req, slo_attrs, part_num, segments):"},{"line_number":979,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":25,"id":"0c0362e1_cd865bf6","line":976,"updated":"2023-10-10 17:22:15.000000000","message":"I rather like this little method - KUDOS!","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"236fb38657f6636c91fce0bed37ca64a414fa509","unresolved":false,"context_lines":[{"line_number":973,"context_line":"            return None"},{"line_number":974,"context_line":""},{"line_number":975,"context_line":"        part_number \u003d _validate_part_number(part_number_param, parts_count)"},{"line_number":976,"context_line":"        return part_number"},{"line_number":977,"context_line":""},{"line_number":978,"context_line":"    def _prepare_slo_headers(self, req, slo_attrs, part_num, segments):"},{"line_number":979,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":25,"id":"7a6a5cfe_5807df20","line":976,"in_reply_to":"0c0362e1_cd865bf6","updated":"2023-10-10 23:06:56.000000000","message":"Ack","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":987,"context_line":"        \"\"\""},{"line_number":988,"context_line":"        headers \u003d {"},{"line_number":989,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":990,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":991,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":992,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":993,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":25,"id":"c8d266f7_d87faa47","line":990,"updated":"2023-10-10 17:22:15.000000000","message":"oh, manifest_etag could become a SloAttr","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":987,"context_line":"        \"\"\""},{"line_number":988,"context_line":"        headers \u003d {"},{"line_number":989,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":990,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":991,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":992,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":993,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":25,"id":"35fc4834_2445cb11","line":990,"in_reply_to":"c8d266f7_d87faa47","updated":"2023-10-14 02:19:46.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":987,"context_line":"        \"\"\""},{"line_number":988,"context_line":"        headers \u003d {"},{"line_number":989,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % slo_attrs.etag,"},{"line_number":990,"context_line":"            \u0027X-Manifest-Etag\u0027: self._response_header_value(\u0027etag\u0027),"},{"line_number":991,"context_line":"            \u0027Content-Length\u0027: str(slo_attrs.size),"},{"line_number":992,"context_line":"            \u0027Content-Range\u0027: None,"},{"line_number":993,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":25,"id":"f93b7d6c_28520a2b","line":990,"in_reply_to":"c8d266f7_d87faa47","updated":"2023-10-14 02:19:46.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":993,"context_line":"        }"},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"        if part_num and segments is not None:"},{"line_number":996,"context_line":"            headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":997,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":998,"context_line":"            # swob calculates the content-length for GETs with"},{"line_number":999,"context_line":"            # swift.common.swob.Range#ranges_for_length but not HEADs"}],"source_content_type":"text/x-python","patch_set":25,"id":"aff77927_db17e41a","line":996,"updated":"2023-10-10 17:22:15.000000000","message":"is it possible for bool(part_num) \u003d\u003d True and NOT segments?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba552ce0b054f0566f85d26223fc0d786ae186b8","unresolved":false,"context_lines":[{"line_number":993,"context_line":"        }"},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"        if part_num and segments is not None:"},{"line_number":996,"context_line":"            headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":997,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":998,"context_line":"            # swob calculates the content-length for GETs with"},{"line_number":999,"context_line":"            # swift.common.swob.Range#ranges_for_length but not HEADs"}],"source_content_type":"text/x-python","patch_set":25,"id":"524f5eee_65711758","line":996,"in_reply_to":"aff77927_db17e41a","updated":"2023-10-11 00:15:47.000000000","message":"No, since we will refetch the manifest always if its a part-num request","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":999,"context_line":"            # swift.common.swob.Range#ranges_for_length but not HEADs"},{"line_number":1000,"context_line":"            # for HEADs  we need to assign value separately"},{"line_number":1001,"context_line":"            headers[\u0027Content-Length\u0027] \u003d \\"},{"line_number":1002,"context_line":"                segments[part_num - 1].get(\u0027segment_length\u0027)"},{"line_number":1003,"context_line":"        return headers"},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"}],"source_content_type":"text/x-python","patch_set":25,"id":"f3e5563d_5ce550f3","line":1002,"updated":"2023-10-10 17:22:15.000000000","message":"that is so annoying!  Can we fix swob?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1ac7aa6ea782bd3b6c742f081ac332a98fd7ef77","unresolved":false,"context_lines":[{"line_number":999,"context_line":"            # swift.common.swob.Range#ranges_for_length but not HEADs"},{"line_number":1000,"context_line":"            # for HEADs  we need to assign value separately"},{"line_number":1001,"context_line":"            headers[\u0027Content-Length\u0027] \u003d \\"},{"line_number":1002,"context_line":"                segments[part_num - 1].get(\u0027segment_length\u0027)"},{"line_number":1003,"context_line":"        return headers"},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"}],"source_content_type":"text/x-python","patch_set":25,"id":"e34cb084_e7aab1c6","line":1002,"in_reply_to":"f3e5563d_5ce550f3","updated":"2023-11-10 21:51:44.000000000","message":"I don\u0027t think swob is going to want or be able to calculate content-length for HEAD responses in general.  I don\u0027t think we can avoid this fixup for part-number HEAD responses.  It\u0027s annoying.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":1003,"context_line":"        return headers"},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"},{"line_number":1006,"context_line":"                             part_num\u003dNone, segments\u003dNone):"},{"line_number":1007,"context_line":"        headers \u003d self._prepare_slo_headers(req, slo_attrs, part_num, segments)"},{"line_number":1008,"context_line":"        return self._return_response(req, start_response, resp_iter, headers)"},{"line_number":1009,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"f52616a1_429b569f","line":1006,"updated":"2023-10-10 17:22:15.000000000","message":"do we ever call this method without passing part_num and segments?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"236fb38657f6636c91fce0bed37ca64a414fa509","unresolved":false,"context_lines":[{"line_number":1003,"context_line":"        return headers"},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"},{"line_number":1006,"context_line":"                             part_num\u003dNone, segments\u003dNone):"},{"line_number":1007,"context_line":"        headers \u003d self._prepare_slo_headers(req, slo_attrs, part_num, segments)"},{"line_number":1008,"context_line":"        return self._return_response(req, start_response, resp_iter, headers)"},{"line_number":1009,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"34f11a7f_08138516","line":1006,"in_reply_to":"f52616a1_429b569f","updated":"2023-10-10 23:06:56.000000000","message":"Yes this method still gets used when we HEAD old manifests","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"},{"line_number":1006,"context_line":"                             part_num\u003dNone, segments\u003dNone):"},{"line_number":1007,"context_line":"        headers \u003d self._prepare_slo_headers(req, slo_attrs, part_num, segments)"},{"line_number":1008,"context_line":"        return self._return_response(req, start_response, resp_iter, headers)"},{"line_number":1009,"context_line":""},{"line_number":1010,"context_line":"    def _return_response(self, req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":25,"id":"68a632e8_a6c65923","line":1007,"updated":"2023-10-10 17:22:15.000000000","message":"part_num is already available on the req - do we need to pass it in separately?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0621d2dd88a440c3333b2292c085bf013855a5f2","unresolved":false,"context_lines":[{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"},{"line_number":1006,"context_line":"                             part_num\u003dNone, segments\u003dNone):"},{"line_number":1007,"context_line":"        headers \u003d self._prepare_slo_headers(req, slo_attrs, part_num, segments)"},{"line_number":1008,"context_line":"        return self._return_response(req, start_response, resp_iter, headers)"},{"line_number":1009,"context_line":""},{"line_number":1010,"context_line":"    def _return_response(self, req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":25,"id":"ec1a52b3_fddb2f02","line":1007,"in_reply_to":"68a632e8_a6c65923","updated":"2023-10-13 23:46:17.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, slo_attrs,"},{"line_number":1006,"context_line":"                             part_num\u003dNone, segments\u003dNone):"},{"line_number":1007,"context_line":"        headers \u003d self._prepare_slo_headers(req, slo_attrs, part_num, segments)"},{"line_number":1008,"context_line":"        return self._return_response(req, start_response, resp_iter, headers)"},{"line_number":1009,"context_line":""},{"line_number":1010,"context_line":"    def _return_response(self, req, start_response, resp_iter,"}],"source_content_type":"text/x-python","patch_set":25,"id":"3954864b_22813cd3","line":1007,"in_reply_to":"68a632e8_a6c65923","updated":"2023-10-14 02:19:46.000000000","message":"No we don\u0027t anymore.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":1050,"context_line":"        \"\"\""},{"line_number":1051,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1052,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1053,"context_line":"        is_part_num \u003d get_param(req, \u0027part-number\u0027) is not None"},{"line_number":1054,"context_line":""},{"line_number":1055,"context_line":"        if not is_manifest_get:"},{"line_number":1056,"context_line":"            # Tell the object server where to find the ETag to match for"}],"source_content_type":"text/x-python","patch_set":25,"id":"3f70ee05_1e00442b","line":1053,"updated":"2023-10-10 17:22:15.000000000","message":"could we do *some* validation here and avoid fetching the manifest just to return an error when `part-number\u003dfoo`","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0621d2dd88a440c3333b2292c085bf013855a5f2","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        \"\"\""},{"line_number":1051,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1052,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1053,"context_line":"        is_part_num \u003d get_param(req, \u0027part-number\u0027) is not None"},{"line_number":1054,"context_line":""},{"line_number":1055,"context_line":"        if not is_manifest_get:"},{"line_number":1056,"context_line":"            # Tell the object server where to find the ETag to match for"}],"source_content_type":"text/x-python","patch_set":25,"id":"e7f0eee6_4ff22fe3","line":1053,"in_reply_to":"3f70ee05_1e00442b","updated":"2023-10-13 23:46:17.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":1050,"context_line":"        \"\"\""},{"line_number":1051,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1052,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1053,"context_line":"        is_part_num \u003d get_param(req, \u0027part-number\u0027) is not None"},{"line_number":1054,"context_line":""},{"line_number":1055,"context_line":"        if not is_manifest_get:"},{"line_number":1056,"context_line":"            # Tell the object server where to find the ETag to match for"}],"source_content_type":"text/x-python","patch_set":25,"id":"7e1a8f74_32499eba","line":1053,"in_reply_to":"3f70ee05_1e00442b","updated":"2023-10-14 02:19:46.000000000","message":"I took care of it in `_get_part_num`, so that `handle_slo_get_or_head` looks neat","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"        # this a GET/HEAD response for the SLO object (not the manifest)"},{"line_number":1082,"context_line":"        if self.segment_listing_needed:"},{"line_number":1083,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1084,"context_line":"            slo_attrs.update_from_segments(segments)"},{"line_number":1085,"context_line":"            part_num \u003d self._get_part_num(req, len(segments), slo_attrs)"},{"line_number":1086,"context_line":"            if req.method \u003d\u003d \u0027GET\u0027:"}],"source_content_type":"text/x-python","patch_set":25,"id":"8524b420_d28945f7","line":1083,"updated":"2023-10-10 17:22:15.000000000","message":"I think we could consider annotating slo-attrs with segments/part_count; seems like they could be useful given the plumbing.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0621d2dd88a440c3333b2292c085bf013855a5f2","unresolved":false,"context_lines":[{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"        # this a GET/HEAD response for the SLO object (not the manifest)"},{"line_number":1082,"context_line":"        if self.segment_listing_needed:"},{"line_number":1083,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1084,"context_line":"            slo_attrs.update_from_segments(segments)"},{"line_number":1085,"context_line":"            part_num \u003d self._get_part_num(req, len(segments), slo_attrs)"},{"line_number":1086,"context_line":"            if req.method \u003d\u003d \u0027GET\u0027:"}],"source_content_type":"text/x-python","patch_set":25,"id":"0b41a1b7_572f91e2","line":1083,"in_reply_to":"8524b420_d28945f7","updated":"2023-10-13 23:46:17.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":1080,"context_line":""},{"line_number":1081,"context_line":"        # this a GET/HEAD response for the SLO object (not the manifest)"},{"line_number":1082,"context_line":"        if self.segment_listing_needed:"},{"line_number":1083,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1084,"context_line":"            slo_attrs.update_from_segments(segments)"},{"line_number":1085,"context_line":"            part_num \u003d self._get_part_num(req, len(segments), slo_attrs)"},{"line_number":1086,"context_line":"            if req.method \u003d\u003d \u0027GET\u0027:"}],"source_content_type":"text/x-python","patch_set":25,"id":"9fca44ca_1b4261a7","line":1083,"in_reply_to":"8524b420_d28945f7","updated":"2023-10-14 02:19:46.000000000","message":"I went forward with annotating with segments, things became much easier after that!","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":1095,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1096,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1097,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1098,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1099,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1100,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1101,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"732caf81_cc076d77","line":1098,"updated":"2023-10-10 17:22:15.000000000","message":"I think i\u0027m coming around to the idea that slo_attrs might have a segments/part_count attrs that defaults to None until you call slo_attrs.update_from_segments(segments)\n\nWRT to part_num req-param there\u0027s a weird coupling that seems to imply \"if the request had a part-number param we\u0027d be in the segment_listing_needed block\" (which you\u0027d know is true if you\u0027ve read _need_to_refetch!  but smells just reading this block).  This might be fine; but it would probably be un-needed if we just grabbed part_num from the request when we needed it.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0621d2dd88a440c3333b2292c085bf013855a5f2","unresolved":false,"context_lines":[{"line_number":1095,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1096,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1097,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1098,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1099,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1100,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1101,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"2cfde95d_45af9f48","line":1098,"in_reply_to":"732caf81_cc076d77","updated":"2023-10-13 23:46:17.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":1095,"context_line":"            # our SLO response doesn\u0027t need the segments from this manifest"},{"line_number":1096,"context_line":"            # resp_iter - so we can close it down"},{"line_number":1097,"context_line":"            friendly_close(resp_iter)  # swob will discard this anyway"},{"line_number":1098,"context_line":"            segments \u003d part_num \u003d None"},{"line_number":1099,"context_line":"        return self._return_slo_response(req, start_response, resp_iter,"},{"line_number":1100,"context_line":"                                         slo_attrs, part_num, segments)"},{"line_number":1101,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"3a7a6e95_8033f46f","line":1098,"in_reply_to":"732caf81_cc076d77","updated":"2023-10-14 02:19:46.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0f9c4c914420e4b76cc64c84b30f2d8eb9f24e07","unresolved":true,"context_lines":[{"line_number":651,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":652,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":653,"context_line":"            raise ValueError()"},{"line_number":654,"context_line":"        elif part_number \u003e parts_count and parts_count is not None:"},{"line_number":655,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":656,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":657,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":27,"id":"41260200_2f03c20f","line":654,"updated":"2023-10-11 22:55:41.000000000","message":"i might flip this boolean around, i\u0027m not sure how it acctually works when parts_count *is* None?\n\n```\n\u003e\u003e\u003e a, b \u003d 1, None\n\u003e\u003e\u003e a \u003e b and b is not None\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nTypeError: \u0027\u003e\u0027 not supported between instances of \u0027int\u0027 and \u0027NoneType\u0027\n```","commit_id":"5abfc111c38f8870f568eff4c8c2bf0d95d305f3"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"2ddb78b2d89be10c5577cd93212c5d2308b8384b","unresolved":false,"context_lines":[{"line_number":651,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":652,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":653,"context_line":"            raise ValueError()"},{"line_number":654,"context_line":"        elif part_number \u003e parts_count and parts_count is not None:"},{"line_number":655,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":656,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":657,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":27,"id":"b2fc63c0_3a03c50a","line":654,"in_reply_to":"41260200_2f03c20f","updated":"2023-10-13 23:44:40.000000000","message":"Ack","commit_id":"5abfc111c38f8870f568eff4c8c2bf0d95d305f3"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0f9c4c914420e4b76cc64c84b30f2d8eb9f24e07","unresolved":true,"context_lines":[{"line_number":1094,"context_line":"        if self.segment_listing_needed:"},{"line_number":1095,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1096,"context_line":"            slo_attrs.update_from_segments(segments)"},{"line_number":1097,"context_line":"            part_num \u003d self._get_part_num(req, slo_attrs.parts_count)"},{"line_number":1098,"context_line":"            if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1099,"context_line":"                # we\u0027ll need a slo response body, and we don\u0027t validate the"},{"line_number":1100,"context_line":"                # frist segment on HEAD"}],"source_content_type":"text/x-python","patch_set":27,"id":"8eca9b57_4a2eb5a6","line":1097,"updated":"2023-10-11 22:55:41.000000000","message":"I think using slo_attrs.parts_count instead of len(segments) here doens\u0027t do a whole lot.\n\nIf you attached *segments* onto slo-attrs  when we call \"update_from_segments\" (at which point parts_count is just a property of the segments attribute) a lot of the plumbing you do into _build_resp_iter and _return_slo_response will no longer be needed\n\nyou can get everyhting you need in those methods from req/slo_attrs","commit_id":"5abfc111c38f8870f568eff4c8c2bf0d95d305f3"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"bc23c334b1f2a0cdd8482f6ec1478f75d68b9637","unresolved":false,"context_lines":[{"line_number":1094,"context_line":"        if self.segment_listing_needed:"},{"line_number":1095,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1096,"context_line":"            slo_attrs.update_from_segments(segments)"},{"line_number":1097,"context_line":"            part_num \u003d self._get_part_num(req, slo_attrs.parts_count)"},{"line_number":1098,"context_line":"            if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1099,"context_line":"                # we\u0027ll need a slo response body, and we don\u0027t validate the"},{"line_number":1100,"context_line":"                # frist segment on HEAD"}],"source_content_type":"text/x-python","patch_set":27,"id":"2d632068_b54c6a2b","line":1097,"in_reply_to":"8eca9b57_4a2eb5a6","updated":"2023-10-13 23:45:09.000000000","message":"Done","commit_id":"5abfc111c38f8870f568eff4c8c2bf0d95d305f3"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":1094,"context_line":"        if self.segment_listing_needed:"},{"line_number":1095,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1096,"context_line":"            slo_attrs.update_from_segments(segments)"},{"line_number":1097,"context_line":"            part_num \u003d self._get_part_num(req, slo_attrs.parts_count)"},{"line_number":1098,"context_line":"            if req.method \u003d\u003d \u0027GET\u0027:"},{"line_number":1099,"context_line":"                # we\u0027ll need a slo response body, and we don\u0027t validate the"},{"line_number":1100,"context_line":"                # frist segment on HEAD"}],"source_content_type":"text/x-python","patch_set":27,"id":"d438a6ea_cd6b87d3","line":1097,"in_reply_to":"8eca9b57_4a2eb5a6","updated":"2023-10-14 02:19:46.000000000","message":"Done","commit_id":"5abfc111c38f8870f568eff4c8c2bf0d95d305f3"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"015edc274e4087228ac9dda49a9973a04a0b37e6","unresolved":true,"context_lines":[{"line_number":639,"context_line":"        Only useful for legacy manifests or part-num requests, calculate"},{"line_number":640,"context_line":"        size/etag values we wouldn\u0027t have gotten from sysmeta headers."},{"line_number":641,"context_line":"        \"\"\""},{"line_number":642,"context_line":"        self.segments \u003d segments if segments is not None else None"},{"line_number":643,"context_line":"        # we only have to set size/etag once; it doesn\u0027t matter if we got the"},{"line_number":644,"context_line":"        # values from sysmeta headers or segments"},{"line_number":645,"context_line":"        if not self._has_size_and_etag():"}],"source_content_type":"text/x-python","patch_set":36,"id":"abe78955_70d646fc","line":642,"updated":"2023-10-24 22:48:34.000000000","message":"so but if segments *is* None then we set segments to ... None ... which is what segments *is*; so either way self.segmnts \u003d segments\n\neither way it\u0027d be good to have some explicit tests that assert SloAttrs always have a segments attribute and after calling update_from_segments it\u0027s equal to the segments we pull the bytes and size from.","commit_id":"2f24fce4aac0b9547f145fb40a903e28006e7ebd"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6ef526d396c7067bed9bb9237abaca372f51c9c0","unresolved":false,"context_lines":[{"line_number":639,"context_line":"        Only useful for legacy manifests or part-num requests, calculate"},{"line_number":640,"context_line":"        size/etag values we wouldn\u0027t have gotten from sysmeta headers."},{"line_number":641,"context_line":"        \"\"\""},{"line_number":642,"context_line":"        self.segments \u003d segments if segments is not None else None"},{"line_number":643,"context_line":"        # we only have to set size/etag once; it doesn\u0027t matter if we got the"},{"line_number":644,"context_line":"        # values from sysmeta headers or segments"},{"line_number":645,"context_line":"        if not self._has_size_and_etag():"}],"source_content_type":"text/x-python","patch_set":36,"id":"b586595e_f860db72","line":642,"in_reply_to":"abe78955_70d646fc","updated":"2023-10-25 13:24:22.000000000","message":"Done","commit_id":"2f24fce4aac0b9547f145fb40a903e28006e7ebd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"13b078c7d880a472823e611a197ea9e083ce35c5","unresolved":true,"context_lines":[{"line_number":977,"context_line":"                raise ValueError()"},{"line_number":978,"context_line":"        except ValueError:"},{"line_number":979,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":980,"context_line":"        parts_count \u003d len(slo_attrs.segments)"},{"line_number":981,"context_line":"        part_number \u003d _validate_part_number(int(part_number_param),"},{"line_number":982,"context_line":"                                            parts_count)"},{"line_number":983,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":38,"id":"de94d09f_a2ead423","line":980,"range":{"start_line":980,"start_character":26,"end_line":980,"end_character":44},"updated":"2023-10-25 13:05:48.000000000","message":"but the method signature default slo_attrs to None so this would blow up?","commit_id":"b26c91a3c7a8e0177a491152fe6a2155baebf1c7"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"a34d4fd14bbac11a2a4fc1a24041e37496f692a8","unresolved":false,"context_lines":[{"line_number":977,"context_line":"                raise ValueError()"},{"line_number":978,"context_line":"        except ValueError:"},{"line_number":979,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":980,"context_line":"        parts_count \u003d len(slo_attrs.segments)"},{"line_number":981,"context_line":"        part_number \u003d _validate_part_number(int(part_number_param),"},{"line_number":982,"context_line":"                                            parts_count)"},{"line_number":983,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":38,"id":"8b4bc35d_19cca0f7","line":980,"range":{"start_line":980,"start_character":26,"end_line":980,"end_character":44},"in_reply_to":"14d60849_570dc906","updated":"2023-10-26 22:33:50.000000000","message":"Done","commit_id":"b26c91a3c7a8e0177a491152fe6a2155baebf1c7"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f68027615b735721c3681faac9ac320c94b9f264","unresolved":true,"context_lines":[{"line_number":977,"context_line":"                raise ValueError()"},{"line_number":978,"context_line":"        except ValueError:"},{"line_number":979,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":980,"context_line":"        parts_count \u003d len(slo_attrs.segments)"},{"line_number":981,"context_line":"        part_number \u003d _validate_part_number(int(part_number_param),"},{"line_number":982,"context_line":"                                            parts_count)"},{"line_number":983,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":38,"id":"14d60849_570dc906","line":980,"range":{"start_line":980,"start_character":26,"end_line":980,"end_character":44},"in_reply_to":"c0cc5935_91574fb7","updated":"2023-10-25 16:01:41.000000000","message":"Not done yet","commit_id":"b26c91a3c7a8e0177a491152fe6a2155baebf1c7"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6ef526d396c7067bed9bb9237abaca372f51c9c0","unresolved":true,"context_lines":[{"line_number":977,"context_line":"                raise ValueError()"},{"line_number":978,"context_line":"        except ValueError:"},{"line_number":979,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":980,"context_line":"        parts_count \u003d len(slo_attrs.segments)"},{"line_number":981,"context_line":"        part_number \u003d _validate_part_number(int(part_number_param),"},{"line_number":982,"context_line":"                                            parts_count)"},{"line_number":983,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":38,"id":"fafd6b22_c02419dd","line":980,"range":{"start_line":980,"start_character":26,"end_line":980,"end_character":44},"in_reply_to":"de94d09f_a2ead423","updated":"2023-10-25 13:24:22.000000000","message":"Nice catch, I will fix it up once i complete the rebase","commit_id":"b26c91a3c7a8e0177a491152fe6a2155baebf1c7"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f8f3a9ec8448b12b7a5cc7706cdade82618209c1","unresolved":false,"context_lines":[{"line_number":977,"context_line":"                raise ValueError()"},{"line_number":978,"context_line":"        except ValueError:"},{"line_number":979,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":980,"context_line":"        parts_count \u003d len(slo_attrs.segments)"},{"line_number":981,"context_line":"        part_number \u003d _validate_part_number(int(part_number_param),"},{"line_number":982,"context_line":"                                            parts_count)"},{"line_number":983,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":38,"id":"c0cc5935_91574fb7","line":980,"range":{"start_line":980,"start_character":26,"end_line":980,"end_character":44},"in_reply_to":"fafd6b22_c02419dd","updated":"2023-10-25 15:27:03.000000000","message":"Done","commit_id":"b26c91a3c7a8e0177a491152fe6a2155baebf1c7"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"5a884454f790a7bbeed2d40ce012525a64415baf","unresolved":true,"context_lines":[{"line_number":979,"context_line":"        try:"},{"line_number":980,"context_line":"            if part_number_param is None:"},{"line_number":981,"context_line":"                return None"},{"line_number":982,"context_line":"            elif not isinstance(int(part_number_param), int):"},{"line_number":983,"context_line":"                raise ValueError()"},{"line_number":984,"context_line":"            else:"},{"line_number":985,"context_line":"                parts_count \u003d len(slo_attrs.segments)"}],"source_content_type":"text/x-python","patch_set":44,"id":"4b53ff10_dfab13f5","line":982,"updated":"2023-10-29 03:10:56.000000000","message":"When is isinstance(int(anything),int)\u003d\u003dfalse? Do you have an example in mind, aside from having a broken anything.\\__int__?","commit_id":"ded6ffe76f3104a18d07247128f70645f2b6d619"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"25bdaaced20404a188b7780e1605d1f0778e61d3","unresolved":false,"context_lines":[{"line_number":979,"context_line":"        try:"},{"line_number":980,"context_line":"            if part_number_param is None:"},{"line_number":981,"context_line":"                return None"},{"line_number":982,"context_line":"            elif not isinstance(int(part_number_param), int):"},{"line_number":983,"context_line":"                raise ValueError()"},{"line_number":984,"context_line":"            else:"},{"line_number":985,"context_line":"                parts_count \u003d len(slo_attrs.segments)"}],"source_content_type":"text/x-python","patch_set":44,"id":"b7fc7499_4ddd0e51","line":982,"in_reply_to":"4b53ff10_dfab13f5","updated":"2023-11-01 19:55:09.000000000","message":"My bad, i think i missed it in the rebase + pre-requisite slo refactoring we had going on","commit_id":"ded6ffe76f3104a18d07247128f70645f2b6d619"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"4d2c7374d861bca20620e7f41a093b5eef5f29dc","unresolved":true,"context_lines":[{"line_number":1160,"context_line":"                start +\u003d seg[\u0027segment_length\u0027]"},{"line_number":1161,"context_line":"            last \u003d start + slo_attrs.segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":1162,"context_line":"            byteranges \u003d [(start, last - 1)]"},{"line_number":1163,"context_line":"            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":1164,"context_line":"        else:"},{"line_number":1165,"context_line":"            byteranges \u003d [(0, slo_attrs.slo_size - 1)]"},{"line_number":1166,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"6059c4c1_1f79b5d7","line":1163,"updated":"2023-11-01 20:21:25.000000000","message":"I see this side effect that is not described in comment,\nand so I have a question: how is req.range used after this?\n\nI looked at how swob provides .range, which is a syntheric property.\nBut even so, I don\u0027t see it actually used for anything explicitly.\nI looked at SegmentedIterable mostly.\nBut it\u0027s in the _response_iter, when Response is called, right?\n\nI think we need to document this side effect in the docstring.","commit_id":"25b2061a3d0acbbe8f8fbcb02d94cf81a7c87f1f"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"db196796fb3d2060fe7970b63580b8f77810a5f2","unresolved":false,"context_lines":[{"line_number":1160,"context_line":"                start +\u003d seg[\u0027segment_length\u0027]"},{"line_number":1161,"context_line":"            last \u003d start + slo_attrs.segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":1162,"context_line":"            byteranges \u003d [(start, last - 1)]"},{"line_number":1163,"context_line":"            req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":1164,"context_line":"        else:"},{"line_number":1165,"context_line":"            byteranges \u003d [(0, slo_attrs.slo_size - 1)]"},{"line_number":1166,"context_line":""}],"source_content_type":"text/x-python","patch_set":47,"id":"aa28b457_2da7602c","line":1163,"in_reply_to":"6059c4c1_1f79b5d7","updated":"2023-11-15 20:43:50.000000000","message":"Done","commit_id":"25b2061a3d0acbbe8f8fbcb02d94cf81a7c87f1f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5a76c5e33b17b819190df876f5186f146b359b9a","unresolved":true,"context_lines":[{"line_number":575,"context_line":"    try:"},{"line_number":576,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":577,"context_line":"            raise ValueError()"},{"line_number":578,"context_line":"        elif parts_count is not None and part_number \u003e parts_count:"},{"line_number":579,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":49,"id":"acdb5a18_aca41bed","line":578,"range":{"start_line":578,"start_character":53,"end_line":578,"end_character":66},"updated":"2023-11-07 21:43:17.000000000","message":"What if `parts_count \u003d\u003d 0`? I think I\u0027m partial toward us mostly behaving as though there was a single zero-byte data segment when the manifest is an empty list... though `X-Parts-Count` should still be zero.","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":575,"context_line":"    try:"},{"line_number":576,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":577,"context_line":"            raise ValueError()"},{"line_number":578,"context_line":"        elif parts_count is not None and part_number \u003e parts_count:"},{"line_number":579,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":49,"id":"af66f05d_96af9fad","line":578,"range":{"start_line":578,"start_character":53,"end_line":578,"end_character":66},"in_reply_to":"acdb5a18_aca41bed","updated":"2023-11-13 23:30:43.000000000","message":"I think its an invalid value for s3api so it might be prudent to comply with how s3 handles it, if we handle it for \"part-number\u003d0\" as a different case we might have to translate the error response on the s3api layer to make it \"appear\" compatible","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5a76c5e33b17b819190df876f5186f146b359b9a","unresolved":true,"context_lines":[{"line_number":577,"context_line":"            raise ValueError()"},{"line_number":578,"context_line":"        elif parts_count is not None and part_number \u003e parts_count:"},{"line_number":579,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"bd82a83b_b38718aa","line":580,"updated":"2023-11-07 21:43:17.000000000","message":"No `Content-Range`? No `X-Parts-Count`?","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"97f7c1bb40b9a58885112a186b99a4ed0951f622","unresolved":false,"context_lines":[{"line_number":577,"context_line":"            raise ValueError()"},{"line_number":578,"context_line":"        elif parts_count is not None and part_number \u003e parts_count:"},{"line_number":579,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"a5e1c19a_73552ddc","line":580,"in_reply_to":"495f5acf_0fdd26b9","updated":"2023-11-15 16:41:47.000000000","message":"Tim, thanks for explaining that for me, now it makes sense!","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2ba0d9b56765aaf95ef51c96b2edaca9c4392d1c","unresolved":true,"context_lines":[{"line_number":577,"context_line":"            raise ValueError()"},{"line_number":578,"context_line":"        elif parts_count is not None and part_number \u003e parts_count:"},{"line_number":579,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"495f5acf_0fdd26b9","line":580,"in_reply_to":"7dc9b69d_369050ee","updated":"2023-11-14 19:49:49.000000000","message":"Yeah, I think the error is appropriate -- and if S3 doesn\u0027t include that wort of info in its errors, s3api can filter it out.\n\nI just think that we can and should provide a little more context with the Swift error. When I make a `Range` request and get back a 416, it includes a `Content-Range` to give me a hint about how I might retry to get a 2xx:\n```\nvagravagrant@saio:~/swift$ `swift auth`\nvagrant@saio:~/swift$ curl -H x-auth-token:$OS_AUTH_TOKEN $OS_STORAGE_URL/c/o -v -H \u0027Range: bytes\u003d9999-\u0027\n*   Trying 127.0.2.1:8080...\n* Connected to saio (127.0.2.1) port 8080 (#0)\n\u003e GET /v1/AUTH_test/c/o HTTP/1.1\n\u003e Host: saio:8080\n\u003e User-Agent: curl/7.81.0\n\u003e Accept: */*\n\u003e x-auth-token:AUTH_tk663aa994fa6c4a04a8f8dbad94baf47b\n\u003e Range: bytes\u003d9999-\n\u003e \n* Mark bundle as not supporting multiuse\n\u003c HTTP/1.1 416 Requested Range Not Satisfiable\n\u003c Content-Type: application/octet-stream\n\u003c X-Object-Meta-Mtime: 1699473539.306715\n\u003c Etag: \"999db7b21966554d5651eed4beada9c3\"\n\u003c Last-Modified: Tue, 14 Nov 2023 19:18:33 GMT\n\u003c X-Timestamp: 1699989512.78888\n\u003c Content-Range: bytes */5846\n\u003c Accept-Ranges: bytes\n\u003c Content-Length: 97\n\u003c X-Trans-Id: tx6b5889f5a94f421688e61-006553c872\n\u003c X-Openstack-Request-Id: tx6b5889f5a94f421688e61-006553c872\n\u003c Date: Tue, 14 Nov 2023 19:20:18 GMT\n\u003c \n* Connection #0 to host saio left intact\n\u003chtml\u003e\u003ch1\u003eRequested Range Not Satisfiable\u003c/h1\u003e\u003cp\u003eThe Range requested is not available.\u003c/p\u003e\u003c/html\u003e\n```\nThe `Content-Range: bytes */5846` tells me that the object is 5846 bytes, so I could retry with `Range: bytes\u003d5500-` or something if I wanted. From [the spec](https://www.rfc-editor.org/rfc/rfc9110#section-15.5.17):\n\n\u003e A server that generates a 416 response to a byte-range request SHOULD generate a Content-Range header field specifying the current length of the selected representation.\n\nGranted, this isn\u0027t exactly a byte-range request, but I\u0027ve grown to expect that a 416 should have a `Content-Range` and we\u0027ve got the information in our heads anyway. Including `X-Parts-Count` seems like the part-number request equivalent of including `Content-Range` on byte-range requests.","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6ff0a56aced5d2def235075f4c4d380d22e18010","unresolved":true,"context_lines":[{"line_number":577,"context_line":"            raise ValueError()"},{"line_number":578,"context_line":"        elif parts_count is not None and part_number \u003e parts_count:"},{"line_number":579,"context_line":"            raise HTTPRequestedRangeNotSatisfiable("},{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"}],"source_content_type":"text/x-python","patch_set":49,"id":"7dc9b69d_369050ee","line":580,"in_reply_to":"bd82a83b_b38718aa","updated":"2023-11-13 21:47:06.000000000","message":"I was trying to be S3 compatible as well as I could which included error responses on the part-num api","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5a76c5e33b17b819190df876f5186f146b359b9a","unresolved":true,"context_lines":[{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":584,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":585,"context_line":""},{"line_number":586,"context_line":"    return part_number"}],"source_content_type":"text/x-python","patch_set":49,"id":"aaa9aeb3_e41996de","line":583,"range":{"start_line":583,"start_character":33,"end_line":583,"end_character":37},"updated":"2023-11-07 21:43:17.000000000","message":"This isn\u0027t the condition we\u0027re checking. Better as\n```\nraise HTTPBadRequest(\u0027Part number must be an integer between \u0027\n                     \u00271 and %d, inclusive\u0027 % parts_count)\n```\n?","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6ff0a56aced5d2def235075f4c4d380d22e18010","unresolved":false,"context_lines":[{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":584,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":585,"context_line":""},{"line_number":586,"context_line":"    return part_number"}],"source_content_type":"text/x-python","patch_set":49,"id":"fa629b27_fd50d461","line":583,"range":{"start_line":583,"start_character":33,"end_line":583,"end_character":37},"in_reply_to":"aaa9aeb3_e41996de","updated":"2023-11-13 21:47:06.000000000","message":"Done","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":584,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":585,"context_line":""},{"line_number":586,"context_line":"    return part_number"}],"source_content_type":"text/x-python","patch_set":49,"id":"c31fd63e_45ff88cd","line":583,"range":{"start_line":583,"start_character":33,"end_line":583,"end_character":37},"in_reply_to":"aaa9aeb3_e41996de","updated":"2023-11-13 12:17:47.000000000","message":"where does the 1000 limit come from?\n\n``max_parts_listing`` defaults to 1000, but could be configured differently, and that is just a *listing* limit.\n\ns3API allows up to 10000 parts (https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). This is SLO, not s3api, but I guess that\u0027s a reasonable starting place.","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":580,"context_line":"                \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":581,"context_line":"    except ValueError:"},{"line_number":582,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":583,"context_line":"                  \u0027between 1 and 1000, inclusive\u0027"},{"line_number":584,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":585,"context_line":""},{"line_number":586,"context_line":"    return part_number"}],"source_content_type":"text/x-python","patch_set":49,"id":"e52398ca_c89017bb","line":583,"range":{"start_line":583,"start_character":33,"end_line":583,"end_character":37},"in_reply_to":"fa629b27_fd50d461","updated":"2023-11-13 23:30:43.000000000","message":"I am leaning towards Alistair\u0027s suggestion that we do as s3api does when it comes to reporting errors when we supply a part number that is out of bounds(in cases when its negative, zero or exceeds the s3api\u0027s constraints)","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5a76c5e33b17b819190df876f5186f146b359b9a","unresolved":true,"context_lines":[{"line_number":981,"context_line":"                parts_count \u003d len(slo_attrs.segments)"},{"line_number":982,"context_line":"            part_number \u003d int(part_number_param)"},{"line_number":983,"context_line":"        except ValueError:"},{"line_number":984,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":985,"context_line":"        part_number \u003d _validate_part_number(part_number,"},{"line_number":986,"context_line":"                                            parts_count)"},{"line_number":987,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":49,"id":"673acb98_0794ecbd","line":984,"updated":"2023-11-07 21:43:17.000000000","message":"It\u0027s a little funny having part-number validation split between here and `_validate_part_number` -- would it make sense to combine the functions?","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":981,"context_line":"                parts_count \u003d len(slo_attrs.segments)"},{"line_number":982,"context_line":"            part_number \u003d int(part_number_param)"},{"line_number":983,"context_line":"        except ValueError:"},{"line_number":984,"context_line":"            raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":985,"context_line":"        part_number \u003d _validate_part_number(part_number,"},{"line_number":986,"context_line":"                                            parts_count)"},{"line_number":987,"context_line":"        return part_number"}],"source_content_type":"text/x-python","patch_set":49,"id":"36fa92b2_bc5adb3c","line":984,"in_reply_to":"673acb98_0794ecbd","updated":"2023-11-13 23:30:43.000000000","message":"Done","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5a76c5e33b17b819190df876f5186f146b359b9a","unresolved":true,"context_lines":[{"line_number":1145,"context_line":"        if req.range and part_num:"},{"line_number":1146,"context_line":"            raise HTTPBadRequest(req\u003dreq,"},{"line_number":1147,"context_line":"                                 body\u003d\u0027Range requests are not supported \u0027"},{"line_number":1148,"context_line":"                                      \u0027with part-number queries\u0027)"},{"line_number":1149,"context_line":"        elif req.range:"},{"line_number":1150,"context_line":"            byteranges \u003d ["},{"line_number":1151,"context_line":"                # For some reason, swob.Range.ranges_for_length adds 1 to the"}],"source_content_type":"text/x-python","patch_set":49,"id":"e466396f_fbecaf68","line":1148,"updated":"2023-11-07 21:43:17.000000000","message":"Seems like a funny restriction -- does S3 have a similar prohibition? I would have expected something like\n```\nGET /v1/a/c/o?part-number\u003d3\nRange: bytes\u003d300-400\n```\nto return just those bytes from that one part.\n\nI think I\u0027m fine with it for now, though -- makes it easier for us to add support later, I think, since one obvious alternative would be to ignore the `Range` header. Going error \u003d\u003e success is much easier than success \u003d\u003e different-notion-of-success.","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":1145,"context_line":"        if req.range and part_num:"},{"line_number":1146,"context_line":"            raise HTTPBadRequest(req\u003dreq,"},{"line_number":1147,"context_line":"                                 body\u003d\u0027Range requests are not supported \u0027"},{"line_number":1148,"context_line":"                                      \u0027with part-number queries\u0027)"},{"line_number":1149,"context_line":"        elif req.range:"},{"line_number":1150,"context_line":"            byteranges \u003d ["},{"line_number":1151,"context_line":"                # For some reason, swob.Range.ranges_for_length adds 1 to the"}],"source_content_type":"text/x-python","patch_set":49,"id":"2036b99a_3b372cb0","line":1148,"in_reply_to":"e466396f_fbecaf68","updated":"2023-11-13 23:30:43.000000000","message":"Done","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1ae68858408051d3a0861e0d77b5ab62a5ac1cf7","unresolved":true,"context_lines":[{"line_number":1018,"context_line":"        part_num \u003d self._get_part_num(req, resp_attrs)"},{"line_number":1019,"context_line":"        if part_num is not None:"},{"line_number":1020,"context_line":"            headers[\u0027X-Parts-Count\u0027] \u003d len(resp_attrs.segments)"},{"line_number":1021,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1022,"context_line":"            # swob calculates the content-length for GETs with"},{"line_number":1023,"context_line":"            # swift.common.swob.Range#ranges_for_length but not HEADs"},{"line_number":1024,"context_line":"            # for HEADs  we need to assign value separately"}],"source_content_type":"text/x-python","patch_set":50,"id":"9644692d_7aec4725","line":1021,"range":{"start_line":1021,"start_character":8,"end_line":1021,"end_character":19},"updated":"2023-11-10 15:15:15.000000000","message":"is this deliberately a different condition w.r.t. line 1019\n\nIIUC part_num can only be None or \u003e0 so we\u0027re safe to write\n\n```\nif part_num:\n```\n\ninstead of \n\n```\nif part_num is None:\n```\n\nbut either way, use the same condition for consistency","commit_id":"49cdb8da3a02d432f9977d0229265c991a076516"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":false,"context_lines":[{"line_number":1018,"context_line":"        part_num \u003d self._get_part_num(req, resp_attrs)"},{"line_number":1019,"context_line":"        if part_num is not None:"},{"line_number":1020,"context_line":"            headers[\u0027X-Parts-Count\u0027] \u003d len(resp_attrs.segments)"},{"line_number":1021,"context_line":"        if part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1022,"context_line":"            # swob calculates the content-length for GETs with"},{"line_number":1023,"context_line":"            # swift.common.swob.Range#ranges_for_length but not HEADs"},{"line_number":1024,"context_line":"            # for HEADs  we need to assign value separately"}],"source_content_type":"text/x-python","patch_set":50,"id":"55321425_56480e90","line":1021,"range":{"start_line":1021,"start_character":8,"end_line":1021,"end_character":19},"in_reply_to":"9644692d_7aec4725","updated":"2023-11-13 12:17:47.000000000","message":"Done","commit_id":"49cdb8da3a02d432f9977d0229265c991a076516"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":568,"context_line":"def get_valid_part_num(req, segments):"},{"line_number":569,"context_line":"    \"\"\""},{"line_number":570,"context_line":"    Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":571,"context_line":"    part-number paramter in it\u0027s query string.  If the passed in request"},{"line_number":572,"context_line":"    includes a part-number paramater it will be parsed into an valid integer"},{"line_number":573,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":574,"context_line":"    param we will return None.  If the part-number paramater is invalid for the"}],"source_content_type":"text/x-python","patch_set":51,"id":"a89df6ef_754362dc","line":571,"range":{"start_line":571,"start_character":16,"end_line":571,"end_character":24},"updated":"2023-11-13 12:17:47.000000000","message":"typo: \"paramter\", also the spelling should be \"parameter\" throughout","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6ff0a56aced5d2def235075f4c4d380d22e18010","unresolved":false,"context_lines":[{"line_number":568,"context_line":"def get_valid_part_num(req, segments):"},{"line_number":569,"context_line":"    \"\"\""},{"line_number":570,"context_line":"    Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":571,"context_line":"    part-number paramter in it\u0027s query string.  If the passed in request"},{"line_number":572,"context_line":"    includes a part-number paramater it will be parsed into an valid integer"},{"line_number":573,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":574,"context_line":"    param we will return None.  If the part-number paramater is invalid for the"}],"source_content_type":"text/x-python","patch_set":51,"id":"3064aece_5688acf7","line":571,"range":{"start_line":571,"start_character":16,"end_line":571,"end_character":24},"in_reply_to":"a89df6ef_754362dc","updated":"2023-11-13 21:47:06.000000000","message":"Ack","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":578,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"    :returns: validated part-number value or None"},{"line_number":581,"context_line":"    :raises HTTPRequestedRangeNotSatisfiable: if part-number is 0"},{"line_number":582,"context_line":"    :raises HTTPBadRequest: if request or part-number param is not valid"},{"line_number":583,"context_line":"    \"\"\""},{"line_number":584,"context_line":"    part_number_param \u003d get_param(req, \u0027part-number\u0027)"}],"source_content_type":"text/x-python","patch_set":51,"id":"98d06770_5f300a61","line":581,"updated":"2023-11-13 12:17:47.000000000","message":"this doesn\u0027t match the code: 0 is a BadRequest\n\nAlso, ``\u003e10000`` should probably be a BadRequest.\n\nHTTPRequestedRangeNotSatisfiable should probably be used just when the requested part num is greater than the number of parts that the object actually has, as opposed to the max number of parts that the API supports.","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":578,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"    :returns: validated part-number value or None"},{"line_number":581,"context_line":"    :raises HTTPRequestedRangeNotSatisfiable: if part-number is 0"},{"line_number":582,"context_line":"    :raises HTTPBadRequest: if request or part-number param is not valid"},{"line_number":583,"context_line":"    \"\"\""},{"line_number":584,"context_line":"    part_number_param \u003d get_param(req, \u0027part-number\u0027)"}],"source_content_type":"text/x-python","patch_set":51,"id":"dc575d21_1bba209f","line":581,"in_reply_to":"98d06770_5f300a61","updated":"2023-11-13 23:30:43.000000000","message":"Done","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":588,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":589,"context_line":"    except ValueError:"},{"line_number":590,"context_line":"        raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":591,"context_line":"    try:"},{"line_number":592,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":593,"context_line":"            raise ValueError()"},{"line_number":594,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":51,"id":"bc55f391_cad1aa4b","line":591,"updated":"2023-11-13 12:17:47.000000000","message":"this doesn\u0027t need to be a try/except\n\n```\nif part_number \u003c\u003d 0:\n   raise HTTPBadRequest etc\n```","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"6ff0a56aced5d2def235075f4c4d380d22e18010","unresolved":false,"context_lines":[{"line_number":588,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":589,"context_line":"    except ValueError:"},{"line_number":590,"context_line":"        raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":591,"context_line":"    try:"},{"line_number":592,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":593,"context_line":"            raise ValueError()"},{"line_number":594,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":51,"id":"c4aeb3c1_f49da15f","line":591,"in_reply_to":"bc55f391_cad1aa4b","updated":"2023-11-13 21:47:06.000000000","message":"Done","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":598,"context_line":"    parts_count \u003d len(segments)"},{"line_number":599,"context_line":"    if part_number \u003e parts_count:"},{"line_number":600,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":601,"context_line":"            \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"}],"source_content_type":"text/x-python","patch_set":51,"id":"3d2f815d_5520612b","line":601,"range":{"start_line":601,"start_character":27,"end_line":601,"end_character":37},"updated":"2023-11-13 12:17:47.000000000","message":"typo: s/partnumber/part number/","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":true,"context_lines":[{"line_number":598,"context_line":"    parts_count \u003d len(segments)"},{"line_number":599,"context_line":"    if part_number \u003e parts_count:"},{"line_number":600,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":601,"context_line":"            \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"}],"source_content_type":"text/x-python","patch_set":51,"id":"c6aa470c_5af88444","line":601,"range":{"start_line":601,"start_character":27,"end_line":601,"end_character":37},"in_reply_to":"3d2f815d_5520612b","updated":"2023-11-13 23:30:43.000000000","message":"This wasn\u0027t a typo but deliberately intended to be compliant with the error response in a similar situation when we run this against s3api, although since we have our request param as \"part-number\" and not \"partNumber\" maybe we can do the translation in s3response.py which is in the subsequent patchset.","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"db196796fb3d2060fe7970b63580b8f77810a5f2","unresolved":false,"context_lines":[{"line_number":598,"context_line":"    parts_count \u003d len(segments)"},{"line_number":599,"context_line":"    if part_number \u003e parts_count:"},{"line_number":600,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":601,"context_line":"            \u0027The requested partnumber is not satisfiable\u0027)"},{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"}],"source_content_type":"text/x-python","patch_set":51,"id":"08fb4074_06c93200","line":601,"range":{"start_line":601,"start_character":27,"end_line":601,"end_character":37},"in_reply_to":"c6aa470c_5af88444","updated":"2023-11-15 20:43:50.000000000","message":"Done","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":605,"context_line":"                                  \u0027with part-number queries\u0027)"},{"line_number":606,"context_line":"    return part_number"},{"line_number":607,"context_line":""},{"line_number":608,"context_line":""}],"source_content_type":"text/x-python","patch_set":51,"id":"811058c4_7533c2cd","line":605,"range":{"start_line":605,"start_character":40,"end_line":605,"end_character":51},"updated":"2023-11-13 12:17:47.000000000","message":"nit: the response bodies variously use \"partnumber\", \"part number\" and \"part-number\". Let\u0027s pick one and be consistent. I\u0027d suggest \"part number\" - if only because that\u0027s how the s3api refers to them https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":605,"context_line":"                                  \u0027with part-number queries\u0027)"},{"line_number":606,"context_line":"    return part_number"},{"line_number":607,"context_line":""},{"line_number":608,"context_line":""}],"source_content_type":"text/x-python","patch_set":51,"id":"4ed27d89_2918986d","line":605,"range":{"start_line":605,"start_character":40,"end_line":605,"end_character":51},"in_reply_to":"811058c4_7533c2cd","updated":"2023-11-13 23:30:43.000000000","message":"I agree and s3api refers it to as \"Part number\"and sometimes \"partnumber\" so it hasn\u0027t been very consistent either as illustrated below:\n```\nashnair@ashnair-mlt ~ % aws s3api get-object --bucket ash-test-mpu --key test.mp4 --part-number 0  outfile\n\nAn error occurred (InvalidArgument) when calling the GetObject operation: Part number must be an integer between 1 and 10000, inclusive\nashnair@ashnair-mlt ~ % aws s3api get-object --bucket ash-test-mpu --key test.mp4 --part-number 17  outfile\n\nAn error occurred (InvalidPartNumber) when calling the GetObject operation: The requested partnumber is not satisfiable\n```","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":635,"context_line":"        byteranges \u003d [(start, last - 1)]"},{"line_number":636,"context_line":"        req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":637,"context_line":"    else:"},{"line_number":638,"context_line":"        byteranges \u003d [(0, resp_attrs.slo_size - 1)]"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    return byteranges"},{"line_number":641,"context_line":""}],"source_content_type":"text/x-python","patch_set":51,"id":"0380a2d6_98a4cd53","line":638,"range":{"start_line":638,"start_character":26,"end_line":638,"end_character":45},"updated":"2023-11-13 12:17:47.000000000","message":"we only get here *after* resp_attrs.update_from_segments has been called, so slo_size has been set","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":true,"context_lines":[{"line_number":635,"context_line":"        byteranges \u003d [(start, last - 1)]"},{"line_number":636,"context_line":"        req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":637,"context_line":"    else:"},{"line_number":638,"context_line":"        byteranges \u003d [(0, resp_attrs.slo_size - 1)]"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    return byteranges"},{"line_number":641,"context_line":""}],"source_content_type":"text/x-python","patch_set":51,"id":"429e8580_e5cac2c8","line":638,"range":{"start_line":638,"start_character":26,"end_line":638,"end_character":45},"in_reply_to":"0380a2d6_98a4cd53","updated":"2023-11-13 23:30:43.000000000","message":"Yes so did you want me adding a comment here?","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5b0a55f3d7160c579a349466948b2f26a6d50be3","unresolved":false,"context_lines":[{"line_number":635,"context_line":"        byteranges \u003d [(start, last - 1)]"},{"line_number":636,"context_line":"        req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":637,"context_line":"    else:"},{"line_number":638,"context_line":"        byteranges \u003d [(0, resp_attrs.slo_size - 1)]"},{"line_number":639,"context_line":""},{"line_number":640,"context_line":"    return byteranges"},{"line_number":641,"context_line":""}],"source_content_type":"text/x-python","patch_set":51,"id":"5c5253dc_7e492aec","line":638,"range":{"start_line":638,"start_character":26,"end_line":638,"end_character":45},"in_reply_to":"429e8580_e5cac2c8","updated":"2023-11-22 18:56:12.000000000","message":"no it was just a note to self","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1ac7aa6ea782bd3b6c742f081ac332a98fd7ef77","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"            # ignore bogus content-range, make swob figure it out"},{"line_number":1074,"context_line":"            \u0027Content-Range\u0027: None"},{"line_number":1075,"context_line":"        }"},{"line_number":1076,"context_line":"        headers.update(part_num_headers)"},{"line_number":1077,"context_line":"        return self._return_response(req, start_response, resp_iter,"},{"line_number":1078,"context_line":"                                     replace_headers\u003dheaders)"},{"line_number":1079,"context_line":""}],"source_content_type":"text/x-python","patch_set":51,"id":"1326f1e8_8bb5be6e","line":1076,"updated":"2023-11-10 21:51:44.000000000","message":"a few things annoy me here - i could not find a way to resolve them\n\n1) it\u0027d be easy to get confused about content-length\n2) we sometimes can\u0027t update headers until after resp_attrs.update_from_segment\n3) you can\u0027t reference a validated part_num w/o segments under segments needed\n4) both x-parts-count and conten-length partnum headers require segments\n5) we only add x-parts-count to part-num responses\n6) we only overwrite content-lenght on part-num head responses\n\nI\u0027d be happy to let someone ELSE waste some more time here; I think this is a good as it gets - at least it\u0027s contained!","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":1126,"context_line":"        \"\"\""},{"line_number":1127,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1128,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1129,"context_line":"        is_part_num \u003d get_param(req, \u0027part-number\u0027) is not None"},{"line_number":1130,"context_line":""},{"line_number":1131,"context_line":"        if not is_manifest_get:"},{"line_number":1132,"context_line":"            # If this object is an SLO manifest, we may have saved off the"}],"source_content_type":"text/x-python","patch_set":51,"id":"ab80d38e_a65dc92e","line":1129,"updated":"2023-11-13 12:17:47.000000000","message":"we could validate the part number here and return BadRequest ``if not (0 \u003c part_number \u003c\u003d 10000)``, before doing backend requests.\n\nalso, note that a valid part_num is always \"true\" (\u003e0)","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":1126,"context_line":"        \"\"\""},{"line_number":1127,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1128,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1129,"context_line":"        is_part_num \u003d get_param(req, \u0027part-number\u0027) is not None"},{"line_number":1130,"context_line":""},{"line_number":1131,"context_line":"        if not is_manifest_get:"},{"line_number":1132,"context_line":"            # If this object is an SLO manifest, we may have saved off the"}],"source_content_type":"text/x-python","patch_set":51,"id":"d31edab3_fd84cf24","line":1129,"in_reply_to":"ab80d38e_a65dc92e","updated":"2023-11-13 23:30:43.000000000","message":"Done","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2ba0d9b56765aaf95ef51c96b2edaca9c4392d1c","unresolved":true,"context_lines":[{"line_number":366,"context_line":""},{"line_number":367,"context_line":"DEFAULT_RATE_LIMIT_UNDER_SIZE \u003d 1024 ** 2  # 1 MiB"},{"line_number":368,"context_line":"DEFAULT_MAX_MANIFEST_SEGMENTS \u003d 1000"},{"line_number":369,"context_line":"DEFAULT_MAX_SEGMENTS \u003d 10000"},{"line_number":370,"context_line":"DEFAULT_MAX_MANIFEST_SIZE \u003d 8 * (1024 ** 2)  # 8 MiB"},{"line_number":371,"context_line":"DEFAULT_YIELD_FREQUENCY \u003d 10"},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"fc192d63_4d741c15","line":369,"updated":"2023-11-14 19:49:49.000000000","message":"I\u0027m fine with `s3api` doing some separate validation, but I think `slo` ought to just look at what\u0027s actually available.\n\nWhat if an operator configured their cluster with `max_manifest_segments \u003d 20000` for some reason? Why should only half of those be fetchable via the part-number API?\n\nWe can\u0027t even use the currently-configured `max_manifest_segments`, as the operator may have lowered the limit, but still has data out on disk that\u0027s above it.","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"832c745b7948912d939cc99560941ca398e1191e","unresolved":false,"context_lines":[{"line_number":366,"context_line":""},{"line_number":367,"context_line":"DEFAULT_RATE_LIMIT_UNDER_SIZE \u003d 1024 ** 2  # 1 MiB"},{"line_number":368,"context_line":"DEFAULT_MAX_MANIFEST_SEGMENTS \u003d 1000"},{"line_number":369,"context_line":"DEFAULT_MAX_SEGMENTS \u003d 10000"},{"line_number":370,"context_line":"DEFAULT_MAX_MANIFEST_SIZE \u003d 8 * (1024 ** 2)  # 8 MiB"},{"line_number":371,"context_line":"DEFAULT_YIELD_FREQUENCY \u003d 10"},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"b97cb80a_fdc7a943","line":369,"in_reply_to":"fc192d63_4d741c15","updated":"2023-11-18 21:45:42.000000000","message":"Done","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"6f3aa7b41daaef124d6a191bc028ca0d6c31ea9c","unresolved":true,"context_lines":[{"line_number":366,"context_line":""},{"line_number":367,"context_line":"DEFAULT_RATE_LIMIT_UNDER_SIZE \u003d 1024 ** 2  # 1 MiB"},{"line_number":368,"context_line":"DEFAULT_MAX_MANIFEST_SEGMENTS \u003d 1000"},{"line_number":369,"context_line":"DEFAULT_MAX_SEGMENTS \u003d 10000"},{"line_number":370,"context_line":"DEFAULT_MAX_MANIFEST_SIZE \u003d 8 * (1024 ** 2)  # 8 MiB"},{"line_number":371,"context_line":"DEFAULT_YIELD_FREQUENCY \u003d 10"},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"eaab8e4a_10cb90ca","line":369,"in_reply_to":"fc192d63_4d741c15","updated":"2023-11-16 05:28:44.000000000","message":"If the operator lowered the max_manifest_segments while objects exist that have more then they can raise it back up, if it\u0027s desired to access that data (through this API). We only need to report the reason why the request was rejected unambiguously. So, I think this is not a good argument against using the currently configured max_manifest_segments for validation.","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2ba0d9b56765aaf95ef51c96b2edaca9c4392d1c","unresolved":true,"context_lines":[{"line_number":599,"context_line":"    if part_number \u003e parts_count:"},{"line_number":600,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":601,"context_line":"            \u0027The requested part number is not satisfiable\u0027)"},{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":605,"context_line":"                                  \u0027with part number queries\u0027)"}],"source_content_type":"text/x-python","patch_set":55,"id":"384a0dcc_36e91a59","line":602,"range":{"start_line":602,"start_character":21,"end_line":602,"end_character":32},"updated":"2023-11-14 19:49:49.000000000","message":"FWIW, we already know `part_number` is truthy: L586 checks for `None`; L593 checks for `0`.","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"97f7c1bb40b9a58885112a186b99a4ed0951f622","unresolved":false,"context_lines":[{"line_number":599,"context_line":"    if part_number \u003e parts_count:"},{"line_number":600,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":601,"context_line":"            \u0027The requested part number is not satisfiable\u0027)"},{"line_number":602,"context_line":"    if req.range and part_number:"},{"line_number":603,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":604,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":605,"context_line":"                                  \u0027with part number queries\u0027)"}],"source_content_type":"text/x-python","patch_set":55,"id":"18d96af5_00535567","line":602,"range":{"start_line":602,"start_character":21,"end_line":602,"end_character":32},"in_reply_to":"384a0dcc_36e91a59","updated":"2023-11-15 16:41:47.000000000","message":"Ack","commit_id":"0f329bb8e65934302e5928aeb64287da3f77f291"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5b0a55f3d7160c579a349466948b2f26a6d50be3","unresolved":true,"context_lines":[{"line_number":565,"context_line":"        seg_dict[\u0027segment_length\u0027] \u003d segment_length"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":""},{"line_number":568,"context_line":"def get_valid_part_num(req, segments\u003dNone):"},{"line_number":569,"context_line":"    \"\"\""},{"line_number":570,"context_line":"    Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":571,"context_line":"    part-number parameter in query string.  If the passed in request"}],"source_content_type":"text/x-python","patch_set":61,"id":"fc397f80_8a931a0f","line":568,"updated":"2023-11-22 18:56:12.000000000","message":"I think there may be differing opinions in previous reviews, but I\u0027d prefer to have 2 functions:\n\nget_valid_part_num(req) returns an int \u003e 0 or raises BadRequest (including when request has range)\n\ncheck_part_num(part_num, segments) raises HTTPRequestedRangeNotSatisfiable if partnum \u003e len(segments)","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c889751717afd2a70a3fa1929ccf5ffb8db4d149","unresolved":false,"context_lines":[{"line_number":565,"context_line":"        seg_dict[\u0027segment_length\u0027] \u003d segment_length"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":""},{"line_number":568,"context_line":"def get_valid_part_num(req, segments\u003dNone):"},{"line_number":569,"context_line":"    \"\"\""},{"line_number":570,"context_line":"    Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":571,"context_line":"    part-number parameter in query string.  If the passed in request"}],"source_content_type":"text/x-python","patch_set":61,"id":"ffa6cf4d_c10944f1","line":568,"in_reply_to":"fc397f80_8a931a0f","updated":"2023-11-27 20:14:33.000000000","message":"Done","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5b0a55f3d7160c579a349466948b2f26a6d50be3","unresolved":true,"context_lines":[{"line_number":578,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"    :returns: validated part-number value or None"},{"line_number":581,"context_line":"    :raises HTTPRequestedRangeNotSatisfiable: if part-number is 0"},{"line_number":582,"context_line":"    :raises HTTPBadRequest: if request or part-number param is not valid"},{"line_number":583,"context_line":"    \"\"\""},{"line_number":584,"context_line":"    part_number_param \u003d get_param(req, \u0027part-number\u0027)"}],"source_content_type":"text/x-python","patch_set":61,"id":"bae099e8_40fc63f8","line":581,"range":{"start_line":581,"start_character":46,"end_line":581,"end_character":65},"updated":"2023-11-22 18:56:12.000000000","message":"this doesn\u0027t match the code","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c889751717afd2a70a3fa1929ccf5ffb8db4d149","unresolved":false,"context_lines":[{"line_number":578,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"    :returns: validated part-number value or None"},{"line_number":581,"context_line":"    :raises HTTPRequestedRangeNotSatisfiable: if part-number is 0"},{"line_number":582,"context_line":"    :raises HTTPBadRequest: if request or part-number param is not valid"},{"line_number":583,"context_line":"    \"\"\""},{"line_number":584,"context_line":"    part_number_param \u003d get_param(req, \u0027part-number\u0027)"}],"source_content_type":"text/x-python","patch_set":61,"id":"2366ed4c_e141f362","line":581,"range":{"start_line":581,"start_character":46,"end_line":581,"end_character":65},"in_reply_to":"bae099e8_40fc63f8","updated":"2023-11-27 20:14:33.000000000","message":"Done","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5b0a55f3d7160c579a349466948b2f26a6d50be3","unresolved":true,"context_lines":[{"line_number":593,"context_line":"    if part_number \u003c\u003d 0 or part_number \u003e 10000:"},{"line_number":594,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":595,"context_line":"                  \u0027between 1 and %d, inclusive\u0027 % parts_count"},{"line_number":596,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":597,"context_line":""},{"line_number":598,"context_line":"    err_resp_headers \u003d []"},{"line_number":599,"context_line":"    if part_number \u003e parts_count:"}],"source_content_type":"text/x-python","patch_set":61,"id":"e12bc9bb_e4ddf72f","line":596,"updated":"2023-11-22 18:56:12.000000000","message":"I still don\u0027t understand either the goal or the implementation:\n\nthe max is hard coded 10000 - why? and then the error messages says the max is parts_count ,which could be \u003e10000, but also defaults to DEFAULT_MAX_MANIFEST_SEGMENTS, which may not be what is configured.\n\nI can see there has been some discussion of what max to apply, and I\u0027m not sure I agree:\nhttps://review.opendev.org/c/openstack/swift/+/894570/comment/fc192d63_4d741c15/\n\nIMHO...\n\nIf the operator allowed an SLO to be created with 20000 segments then the client should be able to set partnum\u003d20000 on a GET or HEAD, regardless of the operator having subsequently reduced the max_manifest_segments. Presumably the op reduced the limit for a good reason and therefore will not want to increase it when the client complains that they cannot access their data using partnum API, so it\u0027s only reasonable to honour the original.\n\ncf. I don\u0027t think we check manifest size during a GET/HEAD and fail if the existing manifest is larger than the current max_manifest_size\n\nSo my opinion is:\n\n* when we first validate the request (i.e. segments \u003dNone) there is no max, partnum just needs to be an int\u003e0\n\n* when we later validate and do have segments, partnum \u003c\u003d len(segments) (we already know it is \u003e 0)","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"bbf56c25d030988e40ed390cf797362e5f54e9a9","unresolved":false,"context_lines":[{"line_number":593,"context_line":"    if part_number \u003c\u003d 0 or part_number \u003e 10000:"},{"line_number":594,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":595,"context_line":"                  \u0027between 1 and %d, inclusive\u0027 % parts_count"},{"line_number":596,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":597,"context_line":""},{"line_number":598,"context_line":"    err_resp_headers \u003d []"},{"line_number":599,"context_line":"    if part_number \u003e parts_count:"}],"source_content_type":"text/x-python","patch_set":61,"id":"7d7be6b8_77fe2ef4","line":596,"in_reply_to":"e12bc9bb_e4ddf72f","updated":"2023-11-27 23:25:47.000000000","message":"Done","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5b0a55f3d7160c579a349466948b2f26a6d50be3","unresolved":true,"context_lines":[{"line_number":607,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":608,"context_line":"    elif part_number \u003d\u003d parts_count \u003d\u003d 1:"},{"line_number":609,"context_line":"        # when we have a static large object manifest with only one segment"},{"line_number":610,"context_line":"        return part_number"},{"line_number":611,"context_line":"    if req.range:"},{"line_number":612,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":613,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"}],"source_content_type":"text/x-python","patch_set":61,"id":"74a28b10_2692e284","line":610,"updated":"2023-11-22 18:56:12.000000000","message":"is this a deliberate special case that it\u0027s ok to have req.range and partnum \u003d\u003d 1, but not to have req.range and partnum \u003e 1 ?\n\nI suspect it is not intended, but if so, it would be clearer to write:\n\n```\nif req.range and partnum !\u003d 1:\n    raise HTTPBadRequest\n```","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c889751717afd2a70a3fa1929ccf5ffb8db4d149","unresolved":false,"context_lines":[{"line_number":607,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":608,"context_line":"    elif part_number \u003d\u003d parts_count \u003d\u003d 1:"},{"line_number":609,"context_line":"        # when we have a static large object manifest with only one segment"},{"line_number":610,"context_line":"        return part_number"},{"line_number":611,"context_line":"    if req.range:"},{"line_number":612,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":613,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"}],"source_content_type":"text/x-python","patch_set":61,"id":"99cb1e43_31e93dc4","line":610,"in_reply_to":"74a28b10_2692e284","updated":"2023-11-27 20:14:33.000000000","message":"I wasn\u0027t it was when i was suspecting whether my code was robust enough to handle a corner case since then which isn\u0027t needed any more. I have gone ahead and deleted it","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5b0a55f3d7160c579a349466948b2f26a6d50be3","unresolved":true,"context_lines":[{"line_number":1057,"context_line":"            # consume existing resp_iter; we\u0027ll create a new one"},{"line_number":1058,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1059,"context_line":"            resp_attrs.update_from_segments(segments)"},{"line_number":1060,"context_line":"            part_num \u003d get_valid_part_num(req, segments)"},{"line_number":1061,"context_line":"            if part_num:"},{"line_number":1062,"context_line":"                part_num_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1063,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"}],"source_content_type":"text/x-python","patch_set":61,"id":"e0f70b0f_c47bc68a","line":1060,"updated":"2023-11-22 18:56:12.000000000","message":"w.r.t. my comment at line 568, here we\u0027d have something like\n\n```\npart_num \u003d get_valid_part_num(req)\nif part_num:\n    check_part_num(part_num, segments)\n    part_num_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)\n```","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c889751717afd2a70a3fa1929ccf5ffb8db4d149","unresolved":false,"context_lines":[{"line_number":1057,"context_line":"            # consume existing resp_iter; we\u0027ll create a new one"},{"line_number":1058,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1059,"context_line":"            resp_attrs.update_from_segments(segments)"},{"line_number":1060,"context_line":"            part_num \u003d get_valid_part_num(req, segments)"},{"line_number":1061,"context_line":"            if part_num:"},{"line_number":1062,"context_line":"                part_num_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1063,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"}],"source_content_type":"text/x-python","patch_set":61,"id":"09820eb1_45cb2e29","line":1060,"in_reply_to":"e0f70b0f_c47bc68a","updated":"2023-11-27 20:14:33.000000000","message":"Done","commit_id":"2ed7088d1781a61a655208ba5a037b8d3518d8c6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":589,"context_line":""},{"line_number":590,"context_line":"    if part_number \u003c\u003d 0:"},{"line_number":591,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":592,"context_line":"                  \u0027between 1 and %d, inclusive\u0027 % DEFAULT_MAX_MANIFEST_SEGMENTS"},{"line_number":593,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":"    if req.range:"}],"source_content_type":"text/x-python","patch_set":69,"id":"1b861235_90b51f4a","line":592,"updated":"2023-11-28 22:02:17.000000000","message":"this should probably look at the configured SloContext.slo.max_manifest_segments","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":589,"context_line":""},{"line_number":590,"context_line":"    if part_number \u003c\u003d 0:"},{"line_number":591,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":592,"context_line":"                  \u0027between 1 and %d, inclusive\u0027 % DEFAULT_MAX_MANIFEST_SEGMENTS"},{"line_number":593,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":"    if req.range:"}],"source_content_type":"text/x-python","patch_set":69,"id":"c5f9c96b_108afe24","line":592,"in_reply_to":"1b861235_90b51f4a","updated":"2023-11-29 16:51:27.000000000","message":"why does the message even state an upper limit that is not enforced? At this point all we can say is part number must be int \u003e 0. \n\nThe previous discussion is no longer showing in gerrit, but FWIW I have advocated that the only upper limit to enforce is the actual part count of the existing manifest, later in check_part_num. So I am on board with the logic here, just not the message.","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":true,"context_lines":[{"line_number":589,"context_line":""},{"line_number":590,"context_line":"    if part_number \u003c\u003d 0:"},{"line_number":591,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":592,"context_line":"                  \u0027between 1 and %d, inclusive\u0027 % DEFAULT_MAX_MANIFEST_SEGMENTS"},{"line_number":593,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":"    if req.range:"}],"source_content_type":"text/x-python","patch_set":69,"id":"db8a571e_c68c0871","line":592,"in_reply_to":"c5f9c96b_108afe24","updated":"2023-11-30 20:40:00.000000000","message":"I think the message could be very important since thats what s3api does as well","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"812032cd848d10a52c9a73be386225fcd98586de","unresolved":false,"context_lines":[{"line_number":589,"context_line":""},{"line_number":590,"context_line":"    if part_number \u003c\u003d 0:"},{"line_number":591,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"},{"line_number":592,"context_line":"                  \u0027between 1 and %d, inclusive\u0027 % DEFAULT_MAX_MANIFEST_SEGMENTS"},{"line_number":593,"context_line":"        raise HTTPBadRequest(err_msg)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":"    if req.range:"}],"source_content_type":"text/x-python","patch_set":69,"id":"53316dd3_cadf51ec","line":592,"in_reply_to":"db8a571e_c68c0871","updated":"2023-12-01 19:58:01.000000000","message":"Acknowledged","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":583,"context_line":"    if part_number_param is None:"},{"line_number":584,"context_line":"        return None"},{"line_number":585,"context_line":"    try:"},{"line_number":586,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":587,"context_line":"    except ValueError:"},{"line_number":588,"context_line":"        raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":589,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"6017b740_1137444b","line":586,"updated":"2023-11-29 16:51:27.000000000","message":"the method could be a little more compact if here you wrote\n\n```\n    if part_number \u003c\u003d 0:\n        raise ValueError\n```\n\nthen delete lines 590 to 593","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":false,"context_lines":[{"line_number":583,"context_line":"    if part_number_param is None:"},{"line_number":584,"context_line":"        return None"},{"line_number":585,"context_line":"    try:"},{"line_number":586,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":587,"context_line":"    except ValueError:"},{"line_number":588,"context_line":"        raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":589,"context_line":""}],"source_content_type":"text/x-python","patch_set":70,"id":"df6f67f0_02db56b5","line":586,"in_reply_to":"6017b740_1137444b","updated":"2023-12-01 12:53:50.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":585,"context_line":"    try:"},{"line_number":586,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":587,"context_line":"    except ValueError:"},{"line_number":588,"context_line":"        raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":589,"context_line":""},{"line_number":590,"context_line":"    if part_number \u003c\u003d 0:"},{"line_number":591,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"}],"source_content_type":"text/x-python","patch_set":70,"id":"30a995f6_48b100d9","line":588,"range":{"start_line":588,"start_character":30,"end_line":588,"end_character":60},"updated":"2023-11-29 16:51:27.000000000","message":"this should state the more complete requirement i.e. \u0027Part number must be an integer greater than 0\u0027","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":585,"context_line":"    try:"},{"line_number":586,"context_line":"        part_number \u003d int(part_number_param)"},{"line_number":587,"context_line":"    except ValueError:"},{"line_number":588,"context_line":"        raise HTTPBadRequest(\u0027Part number must be an integer\u0027)"},{"line_number":589,"context_line":""},{"line_number":590,"context_line":"    if part_number \u003c\u003d 0:"},{"line_number":591,"context_line":"        err_msg \u003d \u0027Part number must be an integer \u0027 \\"}],"source_content_type":"text/x-python","patch_set":70,"id":"2ee0ab96_7482225f","line":588,"range":{"start_line":588,"start_character":30,"end_line":588,"end_character":60},"in_reply_to":"30a995f6_48b100d9","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":609,"context_line":"    \"\"\""},{"line_number":610,"context_line":"    parts_count \u003d len(segments)"},{"line_number":611,"context_line":""},{"line_number":612,"context_line":"    err_resp_headers \u003d []"},{"line_number":613,"context_line":"    if part_num \u003e parts_count:"},{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"}],"source_content_type":"text/x-python","patch_set":70,"id":"03dab1a6_e2553964","line":612,"updated":"2023-11-29 16:51:27.000000000","message":"this can be declared inside the if clause","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":609,"context_line":"    \"\"\""},{"line_number":610,"context_line":"    parts_count \u003d len(segments)"},{"line_number":611,"context_line":""},{"line_number":612,"context_line":"    err_resp_headers \u003d []"},{"line_number":613,"context_line":"    if part_num \u003e parts_count:"},{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"}],"source_content_type":"text/x-python","patch_set":70,"id":"ef6e6857_c2d431ba","line":612,"in_reply_to":"03dab1a6_e2553964","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":612,"context_line":"    err_resp_headers \u003d []"},{"line_number":613,"context_line":"    if part_num \u003e parts_count:"},{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"},{"line_number":616,"context_line":"        err_resp_headers.append((\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":617,"context_line":"            content_length,)))"},{"line_number":618,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("}],"source_content_type":"text/x-python","patch_set":70,"id":"6ff821bb_39209e39","line":615,"range":{"start_line":615,"start_character":7,"end_line":615,"end_character":22},"updated":"2023-11-29 16:51:27.000000000","message":"we already calculated this in RespAttrs.update_from_segments, so can we just use resp_attrs.slow_size here?\n\nAlso, this var name could be confusing: this is not the response content-length, but it is the object size","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":612,"context_line":"    err_resp_headers \u003d []"},{"line_number":613,"context_line":"    if part_num \u003e parts_count:"},{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"},{"line_number":616,"context_line":"        err_resp_headers.append((\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":617,"context_line":"            content_length,)))"},{"line_number":618,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("}],"source_content_type":"text/x-python","patch_set":70,"id":"dae24fe2_fb0ea309","line":615,"range":{"start_line":615,"start_character":7,"end_line":615,"end_character":22},"in_reply_to":"6ff821bb_39209e39","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"},{"line_number":616,"context_line":"        err_resp_headers.append((\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":617,"context_line":"            content_length,)))"},{"line_number":618,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":619,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":620,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"}],"source_content_type":"text/x-python","patch_set":70,"id":"dceb9957_990d8318","line":617,"updated":"2023-11-29 16:51:27.000000000","message":"this seems to makes sense according to https://www.rfc-editor.org/rfc/rfc9110#section-14.4-11 but it\u0027s not useful to the client in terms of fixing the request (whereas X-Parts-Count is useful)\n\nNB s3api does not include Content-Range in its 416 response:\n\n```\n2023-11-29 15:34:21,577 - MainThread - urllib3.connectionpool - DEBUG - https://acoles-test.s3.amazonaws.com:443 \"GET /LICENSE?partNumber\u003d2 HTTP/1.1\" 416 None\n2023-11-29 15:34:21,577 - MainThread - botocore.parsers - DEBUG - Response headers: {\u0027x-amz-request-id\u0027: \u0027832CXX086BNMM91P\u0027, \u0027x-amz-id-2\u0027: \u0027zNbMguvEg+U9HLxOXwSGz1vOzbeu0/+l8paDHUnY4ZcQgCY4FVHZhhkJf6QAOFzbMuHF/zeKykM\u003d\u0027, \u0027Content-Type\u0027: \u0027application/xml\u0027, \u0027Transfer-Encoding\u0027: \u0027chunked\u0027, \u0027Date\u0027: \u0027Wed, 29 Nov 2023 15:34:21 GMT\u0027, \u0027Server\u0027: \u0027AmazonS3\u0027}\n```","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":false,"context_lines":[{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"},{"line_number":616,"context_line":"        err_resp_headers.append((\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":617,"context_line":"            content_length,)))"},{"line_number":618,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":619,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":620,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"}],"source_content_type":"text/x-python","patch_set":70,"id":"62c2a9c5_8774d4b4","line":617,"in_reply_to":"2367d6ec_e73c0633","updated":"2023-12-01 12:53:50.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":true,"context_lines":[{"line_number":614,"context_line":"        err_resp_headers.append((\u0027X-Parts-Count\u0027, parts_count))"},{"line_number":615,"context_line":"        content_length \u003d sum(seg[\u0027segment_length\u0027] for seg in segments)"},{"line_number":616,"context_line":"        err_resp_headers.append((\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":617,"context_line":"            content_length,)))"},{"line_number":618,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":619,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":620,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"}],"source_content_type":"text/x-python","patch_set":70,"id":"2367d6ec_e73c0633","line":617,"in_reply_to":"dceb9957_990d8318","updated":"2023-11-30 20:40:00.000000000","message":"Yes, this was something we had discussed that we desired the content-range in the 416 response emit for the api since slo need not be constrained to s3api behavior","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":619,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":620,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":621,"context_line":""},{"line_number":622,"context_line":"    return part_num"},{"line_number":623,"context_line":""},{"line_number":624,"context_line":""},{"line_number":625,"context_line":"def calculate_byteranges(req, segments, resp_attrs, part_num):"}],"source_content_type":"text/x-python","patch_set":70,"id":"6e3a0a4a_ee7c1b67","line":622,"updated":"2023-11-29 16:51:27.000000000","message":"the return value isn\u0027t used, nor described in the docstring","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":619,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":620,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":621,"context_line":""},{"line_number":622,"context_line":"    return part_num"},{"line_number":623,"context_line":""},{"line_number":624,"context_line":""},{"line_number":625,"context_line":"def calculate_byteranges(req, segments, resp_attrs, part_num):"}],"source_content_type":"text/x-python","patch_set":70,"id":"531da6c3_00a545d9","line":622,"in_reply_to":"6e3a0a4a_ee7c1b67","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":633,"context_line":"    :param req: the request object"},{"line_number":634,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":635,"context_line":"    :param resp_attrs: the slo response attributes"},{"line_number":636,"context_line":"    :param part_num: the slo response attributes"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"    :returns: a list of tuples representing byteranges"},{"line_number":639,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":70,"id":"fd7a6a7c_f8134a67","line":636,"updated":"2023-11-29 16:51:27.000000000","message":"the description of part_num is wrong","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":633,"context_line":"    :param req: the request object"},{"line_number":634,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":635,"context_line":"    :param resp_attrs: the slo response attributes"},{"line_number":636,"context_line":"    :param part_num: the slo response attributes"},{"line_number":637,"context_line":""},{"line_number":638,"context_line":"    :returns: a list of tuples representing byteranges"},{"line_number":639,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":70,"id":"c91b73dc_5a018c7c","line":636,"in_reply_to":"fd7a6a7c_f8134a67","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":640,"context_line":"    if req.range:"},{"line_number":641,"context_line":"        byteranges \u003d ["},{"line_number":642,"context_line":"            # For some reason, swob.Range.ranges_for_length adds 1 to the"},{"line_number":643,"context_line":"            # last byte\u0027s position."},{"line_number":644,"context_line":"            (start, end - 1) for start, end"},{"line_number":645,"context_line":"            in req.range.ranges_for_length(resp_attrs.slo_size)]"},{"line_number":646,"context_line":"    elif part_num:"}],"source_content_type":"text/x-python","patch_set":70,"id":"4148d492_6fcb0d1d","line":643,"updated":"2023-11-29 16:51:27.000000000","message":"this piqued my interest...\n\nlooks like a webob Range object parses the range and adds 1 to the end to make it non-inclusive https://github.com/Pylons/webob/blob/main/src/webob/byterange.py#L82\n\nSwift\u0027s swob.Range does not do that, but ranges_for_length returns webob-like ranges ?! I can\u0027t find a webob ranges_for_length, just range_for_length (singular).\n\nSo we do this end - 1 thing every time we use the result of ranges_for_length.","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":640,"context_line":"    if req.range:"},{"line_number":641,"context_line":"        byteranges \u003d ["},{"line_number":642,"context_line":"            # For some reason, swob.Range.ranges_for_length adds 1 to the"},{"line_number":643,"context_line":"            # last byte\u0027s position."},{"line_number":644,"context_line":"            (start, end - 1) for start, end"},{"line_number":645,"context_line":"            in req.range.ranges_for_length(resp_attrs.slo_size)]"},{"line_number":646,"context_line":"    elif part_num:"}],"source_content_type":"text/x-python","patch_set":70,"id":"c670066f_6c95500d","line":643,"in_reply_to":"4148d492_6fcb0d1d","updated":"2024-01-23 00:46:12.000000000","message":"FWIW, the comment (and most of the body of this function) came from `_build_resp_iter` at the end of this file\u0027s diff.\n\n\u003e I can\u0027t find a webob ranges_for_length, just range_for_length (singular).\n\nPresumably, this is because webob doesn\u0027t support multi-range requests; at the very least, [their regex doesn\u0027t](https://github.com/Pylons/webob/blob/main/src/webob/byterange.py#L5).\n\nNeither does S3... I\u0027m tempted to try putting together a patch to add an option to disable it in Swift... how long would we need to make it off-by-default (and logging deprecation warnings if you turn it on saying to raise an issue with us if it\u0027s something that\u0027s actually important to you) before we\u0027d feel comfortable removing it?\n\n\u003e So we do this end - 1 thing every time we use the result of ranges_for_length.\n\n*Every* time? Or every time *in slo*? https://github.com/openstack/swift/blob/master/swift/common/swob.py#L1436-L1454\n\nI mean, I kinda appreciate the fact that you can calculate `content_length \u003d (end - start)`\n\n(Though I also appreciate the frustration of trying to think in both HTTP ranges and python slices, and tracking which kind we\u0027re thinking in where -- but I don\u0027t know that we can really avoid that.)","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"9301e5eac492993195082a010318b71d2b55f731","unresolved":false,"context_lines":[{"line_number":640,"context_line":"    if req.range:"},{"line_number":641,"context_line":"        byteranges \u003d ["},{"line_number":642,"context_line":"            # For some reason, swob.Range.ranges_for_length adds 1 to the"},{"line_number":643,"context_line":"            # last byte\u0027s position."},{"line_number":644,"context_line":"            (start, end - 1) for start, end"},{"line_number":645,"context_line":"            in req.range.ranges_for_length(resp_attrs.slo_size)]"},{"line_number":646,"context_line":"    elif part_num:"}],"source_content_type":"text/x-python","patch_set":70,"id":"123978b2_39c0b92b","line":643,"in_reply_to":"4148d492_6fcb0d1d","updated":"2024-01-05 17:52:36.000000000","message":"That is correct.","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":640,"context_line":"    if req.range:"},{"line_number":641,"context_line":"        byteranges \u003d ["},{"line_number":642,"context_line":"            # For some reason, swob.Range.ranges_for_length adds 1 to the"},{"line_number":643,"context_line":"            # last byte\u0027s position."},{"line_number":644,"context_line":"            (start, end - 1) for start, end"},{"line_number":645,"context_line":"            in req.range.ranges_for_length(resp_attrs.slo_size)]"},{"line_number":646,"context_line":"    elif part_num:"}],"source_content_type":"text/x-python","patch_set":70,"id":"66c7abe3_5d83f0da","line":643,"in_reply_to":"c670066f_6c95500d","updated":"2024-03-01 16:31:30.000000000","message":"Acknowledged","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":1071,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1072,"context_line":"                resp_iter \u003d []"},{"line_number":1073,"context_line":"                if part_num:"},{"line_number":1074,"context_line":"                    # swob will ignore the Range request header for HEAD"},{"line_number":1075,"context_line":"                    # responses and return the whole content-length, so swob"},{"line_number":1076,"context_line":"                    # only calculates the correct content-length for Range"},{"line_number":1077,"context_line":"                    # requests on GETs, but part-number HEADs MUST return the"}],"source_content_type":"text/x-python","patch_set":70,"id":"537f7ec9_c1abe4d6","line":1074,"updated":"2023-11-29 16:51:27.000000000","message":"I found it confusing that this comment starts as if the context is a Range request, whereas we definitely do not have a Range header. I understand that it\u0027s trying to draw a contrast. Maybe better worded as (assuming the status is also fixed to be 206):\n\n```\nA HEAD with a part-number param MUST return the\ncorrect content-length for the given part (for efficient segment checksum\nvalidation), so for HEADs we have to overwrite content-length with the correct calculated value and change the status to 206. This is in contrast to a HEAD with a Range header: the Range header is ignored and a 200 is returned with the content-length of the whole object.\n```","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":true,"context_lines":[{"line_number":1071,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1072,"context_line":"                resp_iter \u003d []"},{"line_number":1073,"context_line":"                if part_num:"},{"line_number":1074,"context_line":"                    # swob will ignore the Range request header for HEAD"},{"line_number":1075,"context_line":"                    # responses and return the whole content-length, so swob"},{"line_number":1076,"context_line":"                    # only calculates the correct content-length for Range"},{"line_number":1077,"context_line":"                    # requests on GETs, but part-number HEADs MUST return the"}],"source_content_type":"text/x-python","patch_set":70,"id":"cd270176_03c609ea","line":1074,"in_reply_to":"4495a7e5_1eca00ea","updated":"2023-12-01 12:53:50.000000000","message":"this is marked Done, but no change?","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":1071,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1072,"context_line":"                resp_iter \u003d []"},{"line_number":1073,"context_line":"                if part_num:"},{"line_number":1074,"context_line":"                    # swob will ignore the Range request header for HEAD"},{"line_number":1075,"context_line":"                    # responses and return the whole content-length, so swob"},{"line_number":1076,"context_line":"                    # only calculates the correct content-length for Range"},{"line_number":1077,"context_line":"                    # requests on GETs, but part-number HEADs MUST return the"}],"source_content_type":"text/x-python","patch_set":70,"id":"4495a7e5_1eca00ea","line":1074,"in_reply_to":"537f7ec9_c1abe4d6","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d577fc2b66f507903d9467f1150bab648164555d","unresolved":true,"context_lines":[{"line_number":1071,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1072,"context_line":"                resp_iter \u003d []"},{"line_number":1073,"context_line":"                if part_num:"},{"line_number":1074,"context_line":"                    # swob will ignore the Range request header for HEAD"},{"line_number":1075,"context_line":"                    # responses and return the whole content-length, so swob"},{"line_number":1076,"context_line":"                    # only calculates the correct content-length for Range"},{"line_number":1077,"context_line":"                    # requests on GETs, but part-number HEADs MUST return the"}],"source_content_type":"text/x-python","patch_set":70,"id":"d36fbe36_ab914080","line":1074,"in_reply_to":"cd270176_03c609ea","updated":"2023-12-01 17:14:35.000000000","message":"My bad i thought i had changed it","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"812032cd848d10a52c9a73be386225fcd98586de","unresolved":false,"context_lines":[{"line_number":1071,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1072,"context_line":"                resp_iter \u003d []"},{"line_number":1073,"context_line":"                if part_num:"},{"line_number":1074,"context_line":"                    # swob will ignore the Range request header for HEAD"},{"line_number":1075,"context_line":"                    # responses and return the whole content-length, so swob"},{"line_number":1076,"context_line":"                    # only calculates the correct content-length for Range"},{"line_number":1077,"context_line":"                    # requests on GETs, but part-number HEADs MUST return the"}],"source_content_type":"text/x-python","patch_set":70,"id":"3db8d692_e153041a","line":1074,"in_reply_to":"d36fbe36_ab914080","updated":"2023-12-01 19:58:01.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":1145,"context_line":"        \"\"\""},{"line_number":1146,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1147,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1148,"context_line":"        is_part_num \u003d get_valid_part_num(req) is not None"},{"line_number":1149,"context_line":""},{"line_number":1150,"context_line":"        if not is_manifest_get:"},{"line_number":1151,"context_line":"            # If this object is an SLO manifest, we may have saved off the"}],"source_content_type":"text/x-python","patch_set":70,"id":"1940c32f_ef85b23d","line":1148,"updated":"2023-11-29 16:51:27.000000000","message":"nit: the result of get_valid_part_num is truthy enough so we could just use part_num as the condition, similar to in _return_slo_response","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":1145,"context_line":"        \"\"\""},{"line_number":1146,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1147,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1148,"context_line":"        is_part_num \u003d get_valid_part_num(req) is not None"},{"line_number":1149,"context_line":""},{"line_number":1150,"context_line":"        if not is_manifest_get:"},{"line_number":1151,"context_line":"            # If this object is an SLO manifest, we may have saved off the"}],"source_content_type":"text/x-python","patch_set":70,"id":"5d1dc8b2_c000a82c","line":1148,"in_reply_to":"1940c32f_ef85b23d","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":true,"context_lines":[{"line_number":585,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":586,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":587,"context_line":""},{"line_number":588,"context_line":"    return part_num"},{"line_number":589,"context_line":""},{"line_number":590,"context_line":""},{"line_number":591,"context_line":"def calculate_byteranges_for_part_num(req, segments, part_num):"}],"source_content_type":"text/x-python","patch_set":72,"id":"ddb90189_e7ac80a2","line":588,"updated":"2023-12-01 12:53:50.000000000","message":"why is part_num returned? the caller gave it as an arg, it is not modified, and the caller does not assign the return value","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"157b7c9eba7d0a63af19a5a14224687e2485dcf1","unresolved":false,"context_lines":[{"line_number":585,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":586,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":587,"context_line":""},{"line_number":588,"context_line":"    return part_num"},{"line_number":589,"context_line":""},{"line_number":590,"context_line":""},{"line_number":591,"context_line":"def calculate_byteranges_for_part_num(req, segments, part_num):"}],"source_content_type":"text/x-python","patch_set":72,"id":"b47da939_e8138862","line":588,"in_reply_to":"ddb90189_e7ac80a2","updated":"2023-12-01 19:57:20.000000000","message":"Done","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":true,"context_lines":[{"line_number":1157,"context_line":""},{"line_number":1158,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":1159,"context_line":"            err_msg \u003d \u0027Part number must be an integer between 1 \u0027 \\"},{"line_number":1160,"context_line":"                \u0027and %d, inclusive\u0027 % self.slo.max_manifest_segments"},{"line_number":1161,"context_line":"            raise HTTPBadRequest(err_msg)"},{"line_number":1162,"context_line":""},{"line_number":1163,"context_line":"        if req.range:"}],"source_content_type":"text/x-python","patch_set":72,"id":"c784b730_b204fd12","line":1160,"updated":"2023-12-01 12:53:50.000000000","message":"IMHO this is still wrong.\n\n1. the message is different from line 1155\n2. it\u0027s not true, part num does not have be \u003c\u003d self.slo.max_manifest_segments","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"157b7c9eba7d0a63af19a5a14224687e2485dcf1","unresolved":false,"context_lines":[{"line_number":1157,"context_line":""},{"line_number":1158,"context_line":"        if part_number \u003c\u003d 0:"},{"line_number":1159,"context_line":"            err_msg \u003d \u0027Part number must be an integer between 1 \u0027 \\"},{"line_number":1160,"context_line":"                \u0027and %d, inclusive\u0027 % self.slo.max_manifest_segments"},{"line_number":1161,"context_line":"            raise HTTPBadRequest(err_msg)"},{"line_number":1162,"context_line":""},{"line_number":1163,"context_line":"        if req.range:"}],"source_content_type":"text/x-python","patch_set":72,"id":"8221688e_c37e710f","line":1160,"in_reply_to":"c784b730_b204fd12","updated":"2023-12-01 19:57:20.000000000","message":"Done","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":true,"context_lines":[{"line_number":1180,"context_line":"        \"\"\""},{"line_number":1181,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1182,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1183,"context_line":"        is_part_num \u003d self.get_valid_part_num(req)"},{"line_number":1184,"context_line":""},{"line_number":1185,"context_line":"        if not is_manifest_get:"},{"line_number":1186,"context_line":"            # If this object is an SLO manifest, we may have saved off the"}],"source_content_type":"text/x-python","patch_set":72,"id":"960008a9_8eed2413","line":1183,"updated":"2023-12-01 12:53:50.000000000","message":"I thought there was consensus that we should not validate part-num until we know this is an slo object request\n\nsee https://review.opendev.org/c/openstack/swift/+/902406","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"157b7c9eba7d0a63af19a5a14224687e2485dcf1","unresolved":false,"context_lines":[{"line_number":1180,"context_line":"        \"\"\""},{"line_number":1181,"context_line":"        is_manifest_get \u003d get_param(req, \u0027multipart-manifest\u0027) \u003d\u003d \u0027get\u0027"},{"line_number":1182,"context_line":"        is_format_raw \u003d is_manifest_get and get_param(req, \u0027format\u0027) \u003d\u003d \u0027raw\u0027"},{"line_number":1183,"context_line":"        is_part_num \u003d self.get_valid_part_num(req)"},{"line_number":1184,"context_line":""},{"line_number":1185,"context_line":"        if not is_manifest_get:"},{"line_number":1186,"context_line":"            # If this object is an SLO manifest, we may have saved off the"}],"source_content_type":"text/x-python","patch_set":72,"id":"a1bbe113_9b90d3fa","line":1183,"in_reply_to":"960008a9_8eed2413","updated":"2023-12-01 19:57:20.000000000","message":"Done","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":759,"context_line":"            headers\u003d{\u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)},"},{"line_number":760,"context_line":"            agent\u003d\u0027%(orig)s SLO MultipartGET\u0027, swift_source\u003d\u0027SLO\u0027)"},{"line_number":761,"context_line":"        params_copy.pop(\u0027part-number\u0027, None)"},{"line_number":762,"context_line":"        sub_req.params \u003d params_copy"},{"line_number":763,"context_line":"        sub_resp \u003d sub_req.get_response(self.slo.app)"},{"line_number":764,"context_line":""},{"line_number":765,"context_line":"        if not sub_resp.is_success:"}],"source_content_type":"text/x-python","patch_set":73,"id":"110b2d8d_a1887b89","line":762,"updated":"2024-01-23 00:46:12.000000000","message":"Why pop the `part-number` from the manifest request? We wouldn\u0027t do that for `multipart-manifest\u003dget` or anything, would we?","commit_id":"7af83e35174b17927a399e607c811ef114421b24"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":759,"context_line":"            headers\u003d{\u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)},"},{"line_number":760,"context_line":"            agent\u003d\u0027%(orig)s SLO MultipartGET\u0027, swift_source\u003d\u0027SLO\u0027)"},{"line_number":761,"context_line":"        params_copy.pop(\u0027part-number\u0027, None)"},{"line_number":762,"context_line":"        sub_req.params \u003d params_copy"},{"line_number":763,"context_line":"        sub_resp \u003d sub_req.get_response(self.slo.app)"},{"line_number":764,"context_line":""},{"line_number":765,"context_line":"        if not sub_resp.is_success:"}],"source_content_type":"text/x-python","patch_set":73,"id":"43530c95_d415f1ec","line":762,"in_reply_to":"07641adc_e37528f4","updated":"2024-03-01 16:31:30.000000000","message":"Done, I found out that the sub_slo tests were two specifically which were\n```\ntest_get_part_number_sub_slo\ntest_part_number_sub_ranges_manifest\n```\n\nall our assertions before were passing except the expect calls we expect our slo server to issue which was as follows:\n```\ntest/unit/common/middleware/test_slo.py:5813 (TestPartNumberLegacyManifest.test_get_part_number_sub_slo)\n[(\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d2\u0027),\n (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d2\u0027),\n (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027),\n (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/c_15?multipart-manifest\u003dget\u0027)] !\u003d [(\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d2\u0027),\n (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc\u0027),\n (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027),\n (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/c_15?multipart-manifest\u003dget\u0027)]\n```\n\nbut we want our sub_slos also be treated as slos and in the aforementioned case since manifest-bc is a `sub_slo` and we issue a request to it which is a parter of a larger object we want our server to have 2 part-num requests and not 1.","commit_id":"7af83e35174b17927a399e607c811ef114421b24"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"71e87eba2966bd418f4dfc25b8e8635bcb332f17","unresolved":true,"context_lines":[{"line_number":759,"context_line":"            headers\u003d{\u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)},"},{"line_number":760,"context_line":"            agent\u003d\u0027%(orig)s SLO MultipartGET\u0027, swift_source\u003d\u0027SLO\u0027)"},{"line_number":761,"context_line":"        params_copy.pop(\u0027part-number\u0027, None)"},{"line_number":762,"context_line":"        sub_req.params \u003d params_copy"},{"line_number":763,"context_line":"        sub_resp \u003d sub_req.get_response(self.slo.app)"},{"line_number":764,"context_line":""},{"line_number":765,"context_line":"        if not sub_resp.is_success:"}],"source_content_type":"text/x-python","patch_set":73,"id":"92f6e55b_84356ae0","line":762,"in_reply_to":"110b2d8d_a1887b89","updated":"2024-02-28 06:49:53.000000000","message":"Good question","commit_id":"7af83e35174b17927a399e607c811ef114421b24"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1ce4467c4da02d4bb0a17756baf88b0f5c7f993d","unresolved":false,"context_lines":[{"line_number":759,"context_line":"            headers\u003d{\u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)},"},{"line_number":760,"context_line":"            agent\u003d\u0027%(orig)s SLO MultipartGET\u0027, swift_source\u003d\u0027SLO\u0027)"},{"line_number":761,"context_line":"        params_copy.pop(\u0027part-number\u0027, None)"},{"line_number":762,"context_line":"        sub_req.params \u003d params_copy"},{"line_number":763,"context_line":"        sub_resp \u003d sub_req.get_response(self.slo.app)"},{"line_number":764,"context_line":""},{"line_number":765,"context_line":"        if not sub_resp.is_success:"}],"source_content_type":"text/x-python","patch_set":73,"id":"9263df63_a2dadec0","line":762,"in_reply_to":"43530c95_d415f1ec","updated":"2024-03-01 17:45:30.000000000","message":"oic, so the reason we have to pop is because we don\u0027t want to sub-index into sub-slos.  Doing the pop is correct.  The tests demonstrate why the pop is correct.","commit_id":"7af83e35174b17927a399e607c811ef114421b24"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9e4c9d308ab76512f573bb40e0aa5038fb0f5ab1","unresolved":true,"context_lines":[{"line_number":759,"context_line":"            headers\u003d{\u0027x-auth-token\u0027: req.headers.get(\u0027x-auth-token\u0027)},"},{"line_number":760,"context_line":"            agent\u003d\u0027%(orig)s SLO MultipartGET\u0027, swift_source\u003d\u0027SLO\u0027)"},{"line_number":761,"context_line":"        params_copy.pop(\u0027part-number\u0027, None)"},{"line_number":762,"context_line":"        sub_req.params \u003d params_copy"},{"line_number":763,"context_line":"        sub_resp \u003d sub_req.get_response(self.slo.app)"},{"line_number":764,"context_line":""},{"line_number":765,"context_line":"        if not sub_resp.is_success:"}],"source_content_type":"text/x-python","patch_set":73,"id":"07641adc_e37528f4","line":762,"in_reply_to":"92f6e55b_84356ae0","updated":"2024-02-28 17:11:37.000000000","message":"let\u0027s comment out this line and see what tests fail!","commit_id":"7af83e35174b17927a399e607c811ef114421b24"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba3d6be4e98f2059b18f183b1e92444ff8962806","unresolved":true,"context_lines":[{"line_number":577,"context_line":""},{"line_number":578,"context_line":"    if part_num \u003e parts_count:"},{"line_number":579,"context_line":"        err_resp_headers \u003d [(\u0027X-Parts-Count\u0027, parts_count),"},{"line_number":580,"context_line":"                            (\u0027X-Static-Large-Object\u0027, \u0027true\u0027),"},{"line_number":581,"context_line":"                            (\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":582,"context_line":"                                object_size,))]"},{"line_number":583,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("}],"source_content_type":"text/x-python","patch_set":76,"id":"c0ad5f75_a810fe42","line":580,"range":{"start_line":580,"start_character":54,"end_line":580,"end_character":60},"updated":"2023-12-08 18:07:15.000000000","message":"IIUC this will be \u0027True\u0027 (title case) when returned from the backend (and therefore in successful responses to the client). It would be good to be consistent here.","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":577,"context_line":""},{"line_number":578,"context_line":"    if part_num \u003e parts_count:"},{"line_number":579,"context_line":"        err_resp_headers \u003d [(\u0027X-Parts-Count\u0027, parts_count),"},{"line_number":580,"context_line":"                            (\u0027X-Static-Large-Object\u0027, \u0027true\u0027),"},{"line_number":581,"context_line":"                            (\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":582,"context_line":"                                object_size,))]"},{"line_number":583,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("}],"source_content_type":"text/x-python","patch_set":76,"id":"92da6fd6_bd2a0d15","line":580,"range":{"start_line":580,"start_character":54,"end_line":580,"end_character":60},"in_reply_to":"c0ad5f75_a810fe42","updated":"2024-01-03 19:18:02.000000000","message":"Done","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba3d6be4e98f2059b18f183b1e92444ff8962806","unresolved":true,"context_lines":[{"line_number":579,"context_line":"        err_resp_headers \u003d [(\u0027X-Parts-Count\u0027, parts_count),"},{"line_number":580,"context_line":"                            (\u0027X-Static-Large-Object\u0027, \u0027true\u0027),"},{"line_number":581,"context_line":"                            (\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":582,"context_line":"                                object_size,))]"},{"line_number":583,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":584,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":585,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"}],"source_content_type":"text/x-python","patch_set":76,"id":"cd8543d5_e339b697","line":582,"updated":"2023-12-08 18:07:15.000000000","message":"I compared this with a 416 from a regular object or slo and the Etag headers are missing","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"44fc7e2c978ab8970c70ac3ec41627ebd70cf018","unresolved":false,"context_lines":[{"line_number":579,"context_line":"        err_resp_headers \u003d [(\u0027X-Parts-Count\u0027, parts_count),"},{"line_number":580,"context_line":"                            (\u0027X-Static-Large-Object\u0027, \u0027true\u0027),"},{"line_number":581,"context_line":"                            (\u0027Content-Range\u0027, \u0027bytes */%d\u0027 % ("},{"line_number":582,"context_line":"                                object_size,))]"},{"line_number":583,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":584,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":585,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"}],"source_content_type":"text/x-python","patch_set":76,"id":"f4d06934_809bc5d0","line":582,"in_reply_to":"cd8543d5_e339b697","updated":"2023-12-19 00:01:06.000000000","message":"Done","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1f76590b8a767228c16f6767f708f7e44408d817","unresolved":true,"context_lines":[{"line_number":582,"context_line":"                                object_size,))]"},{"line_number":583,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":584,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":585,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":586,"context_line":""},{"line_number":587,"context_line":""},{"line_number":588,"context_line":"def calculate_byteranges_for_part_num(req, segments, part_num):"}],"source_content_type":"text/x-python","patch_set":76,"id":"0d8f40a5_eafd87d3","line":585,"updated":"2023-12-12 20:05:52.000000000","message":"a swob.Response keeps the original headers when morphing a response to 416","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":false,"context_lines":[{"line_number":582,"context_line":"                                object_size,))]"},{"line_number":583,"context_line":"        raise HTTPRequestedRangeNotSatisfiable("},{"line_number":584,"context_line":"            headers\u003derr_resp_headers,"},{"line_number":585,"context_line":"            body\u003d\u0027The requested part number is not satisfiable\u0027)"},{"line_number":586,"context_line":""},{"line_number":587,"context_line":""},{"line_number":588,"context_line":"def calculate_byteranges_for_part_num(req, segments, part_num):"}],"source_content_type":"text/x-python","patch_set":76,"id":"3890d571_4225f2bd","line":585,"in_reply_to":"0d8f40a5_eafd87d3","updated":"2023-12-15 16:04:06.000000000","message":"Done","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1f76590b8a767228c16f6767f708f7e44408d817","unresolved":true,"context_lines":[{"line_number":594,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":595,"context_line":"    :param part_num: the part number of the object to return"},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"    :returns: a list of tuples representing byteranges"},{"line_number":598,"context_line":"    \"\"\""},{"line_number":599,"context_line":"    start \u003d 0"},{"line_number":600,"context_line":"    for seg in segments[:part_num - 1]:"}],"source_content_type":"text/x-python","patch_set":76,"id":"8ec62bb1_d8562ca7","line":597,"updated":"2023-12-12 20:05:52.000000000","message":"this could just return the tuple","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":false,"context_lines":[{"line_number":594,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":595,"context_line":"    :param part_num: the part number of the object to return"},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"    :returns: a list of tuples representing byteranges"},{"line_number":598,"context_line":"    \"\"\""},{"line_number":599,"context_line":"    start \u003d 0"},{"line_number":600,"context_line":"    for seg in segments[:part_num - 1]:"}],"source_content_type":"text/x-python","patch_set":76,"id":"3338dfb2_f9b7f52c","line":597,"in_reply_to":"8ec62bb1_d8562ca7","updated":"2023-12-15 16:04:06.000000000","message":"Done","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"44fc7e2c978ab8970c70ac3ec41627ebd70cf018","unresolved":false,"context_lines":[{"line_number":594,"context_line":"    :param segments: the list of seg_dicts"},{"line_number":595,"context_line":"    :param part_num: the part number of the object to return"},{"line_number":596,"context_line":""},{"line_number":597,"context_line":"    :returns: a list of tuples representing byteranges"},{"line_number":598,"context_line":"    \"\"\""},{"line_number":599,"context_line":"    start \u003d 0"},{"line_number":600,"context_line":"    for seg in segments[:part_num - 1]:"}],"source_content_type":"text/x-python","patch_set":76,"id":"cb9715b7_ad326ad2","line":597,"in_reply_to":"8ec62bb1_d8562ca7","updated":"2023-12-19 00:01:06.000000000","message":"Done","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba3d6be4e98f2059b18f183b1e92444ff8962806","unresolved":true,"context_lines":[{"line_number":1042,"context_line":"                part_num_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1043,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1044,"context_line":"                resp_iter \u003d []"},{"line_number":1045,"context_line":"                if part_num:"},{"line_number":1046,"context_line":"                    # We\u0027re outside RFC with part numbers: 206 is specified in"},{"line_number":1047,"context_line":"                    # the context of Range requests, and Range headers MUST be"},{"line_number":1048,"context_line":"                    # ignored for HEADs"}],"source_content_type":"text/x-python","patch_set":76,"id":"8f174265_ea173646","line":1045,"updated":"2023-12-08 18:07:15.000000000","message":"it confused me (again) that we only do this for a HEAD - surely we need the same headers for a GET??? But then I reminded myself that swob takes care of it for a GET once we set a Range header on the request!!\n\nIDK if we could just set the headers here for HEAD AND GET?? or at least add a comment \"swob will do this for a GET\".  There is a comment at line 604 but this is where I stalled when reading the code.","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":1042,"context_line":"                part_num_headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1043,"context_line":"            if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1044,"context_line":"                resp_iter \u003d []"},{"line_number":1045,"context_line":"                if part_num:"},{"line_number":1046,"context_line":"                    # We\u0027re outside RFC with part numbers: 206 is specified in"},{"line_number":1047,"context_line":"                    # the context of Range requests, and Range headers MUST be"},{"line_number":1048,"context_line":"                    # ignored for HEADs"}],"source_content_type":"text/x-python","patch_set":76,"id":"caf4a296_0cf9dbe2","line":1045,"in_reply_to":"8f174265_ea173646","updated":"2024-01-03 19:18:02.000000000","message":"This is an outdated comment and has since been addressed with the specific pre-condition (if part_num and req.method \u003d\u003d \u0027HEAD\u0027) in `def _return_slo_response`","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba3d6be4e98f2059b18f183b1e92444ff8962806","unresolved":true,"context_lines":[{"line_number":1067,"context_line":"                resp_iter \u003d self._build_resp_iter(req, segments, byteranges)"},{"line_number":1068,"context_line":"        headers \u003d {"},{"line_number":1069,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % resp_attrs.slo_etag,"},{"line_number":1070,"context_line":"            \u0027X-Manifest-Etag\u0027: resp_attrs.json_md5,"},{"line_number":1071,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":1072,"context_line":"            \u0027Content-Length\u0027: str(resp_attrs.slo_size),"},{"line_number":1073,"context_line":"            # ignore bogus content-range, make swob figure it out"}],"source_content_type":"text/x-python","patch_set":76,"id":"1f4889f0_8721c0c1","line":1070,"updated":"2023-12-08 18:07:15.000000000","message":"I think we need some of these headers if we end up returning a 416 for bad partnum. I\u0027m trying to find a way to avoid repeating building them, but not there yet...","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":1067,"context_line":"                resp_iter \u003d self._build_resp_iter(req, segments, byteranges)"},{"line_number":1068,"context_line":"        headers \u003d {"},{"line_number":1069,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % resp_attrs.slo_etag,"},{"line_number":1070,"context_line":"            \u0027X-Manifest-Etag\u0027: resp_attrs.json_md5,"},{"line_number":1071,"context_line":"            # This isn\u0027t correct for range requests, but swob will fix it?"},{"line_number":1072,"context_line":"            \u0027Content-Length\u0027: str(resp_attrs.slo_size),"},{"line_number":1073,"context_line":"            # ignore bogus content-range, make swob figure it out"}],"source_content_type":"text/x-python","patch_set":76,"id":"afb77e94_3d6f1ee2","line":1070,"in_reply_to":"1f4889f0_8721c0c1","updated":"2024-01-03 19:18:02.000000000","message":"I believe we have managed to achieve that now with https://review.opendev.org/c/openstack/swift/+/894570/83/swift/common/middleware/slo.py#1038","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"17824a0f7c7398fe5197875460fb95f3d0032353","unresolved":true,"context_lines":[{"line_number":746,"context_line":"        :param con: native"},{"line_number":747,"context_line":"        :param obj: native"},{"line_number":748,"context_line":"        \"\"\""},{"line_number":749,"context_line":"        params_copy \u003d dict(req.params)"},{"line_number":750,"context_line":"        sub_req \u003d make_subrequest("},{"line_number":751,"context_line":"            req.environ,"},{"line_number":752,"context_line":"            path\u003dwsgi_quote(\u0027/\u0027.join(["}],"source_content_type":"text/x-python","patch_set":85,"id":"cf3081d8_cc9354d1","line":749,"updated":"2024-01-11 14:18:12.000000000","message":"nit: seems odd to have this separate from lines 758-759","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"98ad5921046205f4f2223d266ac6d90f44496cc1","unresolved":false,"context_lines":[{"line_number":746,"context_line":"        :param con: native"},{"line_number":747,"context_line":"        :param obj: native"},{"line_number":748,"context_line":"        \"\"\""},{"line_number":749,"context_line":"        params_copy \u003d dict(req.params)"},{"line_number":750,"context_line":"        sub_req \u003d make_subrequest("},{"line_number":751,"context_line":"            req.environ,"},{"line_number":752,"context_line":"            path\u003dwsgi_quote(\u0027/\u0027.join(["}],"source_content_type":"text/x-python","patch_set":85,"id":"376122a3_dc79fb7e","line":749,"in_reply_to":"cf3081d8_cc9354d1","updated":"2024-01-11 14:18:51.000000000","message":"Done","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"17824a0f7c7398fe5197875460fb95f3d0032353","unresolved":true,"context_lines":[{"line_number":1117,"context_line":"        )"},{"line_number":1118,"context_line":"        return resp(req.environ, start_response)"},{"line_number":1119,"context_line":""},{"line_number":1120,"context_line":"    def get_valid_part_num(self, req):"},{"line_number":1121,"context_line":"        \"\"\""},{"line_number":1122,"context_line":"        Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":1123,"context_line":"        part-number parameter in query string.  If the passed in request"}],"source_content_type":"text/x-python","patch_set":85,"id":"83c5a38e_adbd8240","line":1120,"updated":"2024-01-11 14:18:12.000000000","message":"Ideally this would be earlier be in the file, ahead of where it is first called. In fact, it can be a module function.","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"98ad5921046205f4f2223d266ac6d90f44496cc1","unresolved":false,"context_lines":[{"line_number":1117,"context_line":"        )"},{"line_number":1118,"context_line":"        return resp(req.environ, start_response)"},{"line_number":1119,"context_line":""},{"line_number":1120,"context_line":"    def get_valid_part_num(self, req):"},{"line_number":1121,"context_line":"        \"\"\""},{"line_number":1122,"context_line":"        Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":1123,"context_line":"        part-number parameter in query string.  If the passed in request"}],"source_content_type":"text/x-python","patch_set":85,"id":"e6796a55_02e0cabf","line":1120,"in_reply_to":"83c5a38e_adbd8240","updated":"2024-01-11 14:18:51.000000000","message":"Done","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"17824a0f7c7398fe5197875460fb95f3d0032353","unresolved":true,"context_lines":[{"line_number":1198,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1199,"context_line":"                    req, resp_attrs, part_num):"},{"line_number":1200,"context_line":"                # reset path in case it was modified during original request"},{"line_number":1201,"context_line":"                # (e.g. object versioning might re-write the path)"},{"line_number":1202,"context_line":"                req.path_info \u003d orig_path_info"},{"line_number":1203,"context_line":"                resp_attrs, resp_iter \u003d self._refetch_manifest("},{"line_number":1204,"context_line":"                    req, resp_iter, resp_attrs)"}],"source_content_type":"text/x-python","patch_set":85,"id":"68026ad0_7b420705","line":1201,"updated":"2024-01-11 14:18:12.000000000","message":"was this a pre-existing bug? might be worth fixing in a pre-patch","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":true,"context_lines":[{"line_number":1198,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1199,"context_line":"                    req, resp_attrs, part_num):"},{"line_number":1200,"context_line":"                # reset path in case it was modified during original request"},{"line_number":1201,"context_line":"                # (e.g. object versioning might re-write the path)"},{"line_number":1202,"context_line":"                req.path_info \u003d orig_path_info"},{"line_number":1203,"context_line":"                resp_attrs, resp_iter \u003d self._refetch_manifest("},{"line_number":1204,"context_line":"                    req, resp_iter, resp_attrs)"}],"source_content_type":"text/x-python","patch_set":85,"id":"e186de2e_c9e2cfd5","line":1201,"in_reply_to":"68026ad0_7b420705","updated":"2024-03-01 16:31:30.000000000","message":"We recently had a situation where we had a corner case in versioning and part-num didn\u0027t work quite so well together so this might be worth looking into.","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"bd269a1b8c41af7f5a08a18d7a80964d5ce1b604","unresolved":false,"context_lines":[{"line_number":1198,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1199,"context_line":"                    req, resp_attrs, part_num):"},{"line_number":1200,"context_line":"                # reset path in case it was modified during original request"},{"line_number":1201,"context_line":"                # (e.g. object versioning might re-write the path)"},{"line_number":1202,"context_line":"                req.path_info \u003d orig_path_info"},{"line_number":1203,"context_line":"                resp_attrs, resp_iter \u003d self._refetch_manifest("},{"line_number":1204,"context_line":"                    req, resp_iter, resp_attrs)"}],"source_content_type":"text/x-python","patch_set":85,"id":"6244f0a3_fbd12def","line":1201,"in_reply_to":"e186de2e_c9e2cfd5","updated":"2024-03-01 20:38:56.000000000","message":"The comment above was on a different corner case entirely related to `x-open-expired` and `part-num` req","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1ce4467c4da02d4bb0a17756baf88b0f5c7f993d","unresolved":true,"context_lines":[{"line_number":1198,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1199,"context_line":"                    req, resp_attrs, part_num):"},{"line_number":1200,"context_line":"                # reset path in case it was modified during original request"},{"line_number":1201,"context_line":"                # (e.g. object versioning might re-write the path)"},{"line_number":1202,"context_line":"                req.path_info \u003d orig_path_info"},{"line_number":1203,"context_line":"                resp_attrs, resp_iter \u003d self._refetch_manifest("},{"line_number":1204,"context_line":"                    req, resp_iter, resp_attrs)"}],"source_content_type":"text/x-python","patch_set":85,"id":"71efd5a3_48da8a99","line":1201,"in_reply_to":"e186de2e_c9e2cfd5","updated":"2024-03-01 17:45:30.000000000","message":"there was an issue with part-num and x-open-expired that had to do with forwarding query strings, the versioning-path-rewrite issue may yet be pre-existing and we\u0027re going to write a test.","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":600,"context_line":"    last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":601,"context_line":"    # We need to mutate the request\u0027s Range header so that swob knows to"},{"line_number":602,"context_line":"    # handle these partial content requests correctly."},{"line_number":603,"context_line":"    req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":604,"context_line":"    return start, last - 1"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":""}],"source_content_type":"text/x-python","patch_set":86,"id":"973b1051_e8df0328","line":603,"updated":"2024-01-23 00:46:12.000000000","message":"The mutation feels a little funny -- how bad is it to move this part to the caller?\n\nAlso, we might want to use swob\u0027s `content_range_header_value`","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":false,"context_lines":[{"line_number":600,"context_line":"    last \u003d start + segments[part_num - 1][\u0027segment_length\u0027]"},{"line_number":601,"context_line":"    # We need to mutate the request\u0027s Range header so that swob knows to"},{"line_number":602,"context_line":"    # handle these partial content requests correctly."},{"line_number":603,"context_line":"    req.range \u003d \"bytes\u003d%d-%d\" % (start, last - 1)"},{"line_number":604,"context_line":"    return start, last - 1"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":""}],"source_content_type":"text/x-python","patch_set":86,"id":"52b8eac0_c2d6722b","line":603,"in_reply_to":"973b1051_e8df0328","updated":"2024-02-20 19:23:59.000000000","message":"I believe i avoided it since swob\u0027s content_range_header_value requires the size of the full object and it will entertain the part-num request as NOT an independent entity. This workaround was adopted to avoid giving the full size of the object and have the length of the part itself utilized for the start and last bytes, as a result the content-length header of the returned object is not the full size of the object but the size of the part of the object.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":662,"context_line":"    if req.range:"},{"line_number":663,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":664,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":665,"context_line":"                                  \u0027with part number queries\u0027)"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    return part_number"},{"line_number":668,"context_line":""}],"source_content_type":"text/x-python","patch_set":86,"id":"0ec904da_b8141e05","line":665,"updated":"2024-01-23 00:46:12.000000000","message":"This still seems unfortunate to me -- I could see a way to have those interact and make sense. Have we tried it against AWS?\n\nI might see what I can do to support it in a follow-up...","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f251fd4037d95617bfa8eaed46bd13574a67a24a","unresolved":true,"context_lines":[{"line_number":662,"context_line":"    if req.range:"},{"line_number":663,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":664,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":665,"context_line":"                                  \u0027with part number queries\u0027)"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    return part_number"},{"line_number":668,"context_line":""}],"source_content_type":"text/x-python","patch_set":86,"id":"ecdf9281_47582037","line":665,"in_reply_to":"0ec904da_b8141e05","updated":"2024-02-22 01:25:43.000000000","message":"We could add it as a follow-on patch in the future should the need arise ?","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"fd0845685b80f4ab968b4a0a3adeada5d3d26a4c","unresolved":false,"context_lines":[{"line_number":662,"context_line":"    if req.range:"},{"line_number":663,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":664,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":665,"context_line":"                                  \u0027with part number queries\u0027)"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    return part_number"},{"line_number":668,"context_line":""}],"source_content_type":"text/x-python","patch_set":86,"id":"6620a547_aaa845cd","line":665,"in_reply_to":"14f3094d_40797858","updated":"2024-02-27 18:44:27.000000000","message":"Done","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7a33ee7d7efb643abd891d20af8868d972458c50","unresolved":true,"context_lines":[{"line_number":662,"context_line":"    if req.range:"},{"line_number":663,"context_line":"        raise HTTPBadRequest(req\u003dreq,"},{"line_number":664,"context_line":"                             body\u003d\u0027Range requests are not supported \u0027"},{"line_number":665,"context_line":"                                  \u0027with part number queries\u0027)"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    return part_number"},{"line_number":668,"context_line":""}],"source_content_type":"text/x-python","patch_set":86,"id":"14f3094d_40797858","line":665,"in_reply_to":"ecdf9281_47582037","updated":"2024-02-27 16:37:29.000000000","message":"IIUC this is now addressed by the follow-up patch https://review.opendev.org/c/openstack/swift/+/906391/3?usp\u003drelated-change","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":964,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":965,"context_line":"            # There may be some cases in the future where a HEAD resp on even a"},{"line_number":966,"context_line":"            # modern manifest should refetch, e.g. lp bug #2029174"},{"line_number":967,"context_line":"            self.segment_listing_needed \u003d resp_attrs.is_legacy or part_num"},{"line_number":968,"context_line":"            # it will always be the case that a HEAD must re-fetch iff"},{"line_number":969,"context_line":"            # segment_listing_needed"},{"line_number":970,"context_line":"            return self.segment_listing_needed"}],"source_content_type":"text/x-python","patch_set":86,"id":"3f27dae8_6b468817","line":967,"range":{"start_line":967,"start_character":63,"end_line":967,"end_character":74},"updated":"2024-01-23 00:46:12.000000000","message":"OK, so we don\u0027t actually care _which_ `part-number` was requested, just that one was. And the subtle thing is, we\u0027re relying not only on the fact that `part_num` may be `None`, but _also_ that it *won\u0027t* be zero.\n\nThat might be a little more clear if we name the param here `is_part_num_request`, then pass it as `part_num is not None`.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":false,"context_lines":[{"line_number":964,"context_line":"        if req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":965,"context_line":"            # There may be some cases in the future where a HEAD resp on even a"},{"line_number":966,"context_line":"            # modern manifest should refetch, e.g. lp bug #2029174"},{"line_number":967,"context_line":"            self.segment_listing_needed \u003d resp_attrs.is_legacy or part_num"},{"line_number":968,"context_line":"            # it will always be the case that a HEAD must re-fetch iff"},{"line_number":969,"context_line":"            # segment_listing_needed"},{"line_number":970,"context_line":"            return self.segment_listing_needed"}],"source_content_type":"text/x-python","patch_set":86,"id":"f48047a6_5e225d3d","line":967,"range":{"start_line":967,"start_character":63,"end_line":967,"end_character":74},"in_reply_to":"3f27dae8_6b468817","updated":"2024-02-20 19:23:59.000000000","message":"Done","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1063,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, resp_attrs):"},{"line_number":1064,"context_line":"        headers \u003d {"},{"line_number":1065,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % resp_attrs.slo_etag,"},{"line_number":1066,"context_line":"            \u0027X-Manifest-Etag\u0027: resp_attrs.json_md5,"},{"line_number":1067,"context_line":"            # swob will fix this for a GET with Range"},{"line_number":1068,"context_line":"            \u0027Content-Length\u0027: str(resp_attrs.slo_size),"},{"line_number":1069,"context_line":"            # ignore bogus content-range, make swob figure it out"}],"source_content_type":"text/x-python","patch_set":86,"id":"66b1b769_94804b22","line":1066,"updated":"2024-01-23 00:46:12.000000000","message":"Considering how the driver for this is client-side validation, it\u0027s a little unfortunate that we don\u0027t have any way of validating just this one part -- WDYT about adding a `Content-MD5` header for `?part-number` responses?\n\nUgh... but I suppose the underlying segment requests are all being handled by `SegmentedIterable`, so we don\u0027t really _have_ the underlying ETag in hand to try to send that...\n\nSpeaking of `SegmentedIterable` ... how do we feel about this?\n```\nvagrant@saio:~/swift$ curl http://saio:8090/v1/AUTH_test/test/tox.ini?part-number\u003d2 -I\nHTTP/1.1 206 Partial Content\nContent-Type: application/octet-stream\nX-Object-Meta-Mtime: 1705701295.575089\nX-Static-Large-Object: True\nEtag: \"5af4d74b3bb98258d3c600a41dd52bf5\"\nLast-Modified: Fri, 19 Jan 2024 22:32:18 GMT\nX-Timestamp: 1705703537.92039\nAccept-Ranges: bytes\nContent-Length: 1024\nX-Manifest-Etag: 256a179accf26b46f13dfd2042ef2802\nContent-Range: bytes 1024-2047/2935\nX-Parts-Count: 3\nX-Trans-Id: tx1d945d3643e54d6eb6047-0065aeeee7\nX-Openstack-Request-Id: tx1d945d3643e54d6eb6047-0065aeeee7\nDate: Mon, 22 Jan 2024 22:40:39 GMT\n\nvagrant@saio:~/swift$ curl http://saio:8090/v1/AUTH_test/test/tox.ini?part-number\u003d2 -i\nHTTP/1.1 409 Conflict\nContent-Type: text/html; charset\u003dUTF-8\nContent-Length: 95\nX-Trans-Id: txae733272e5bc4ea18c4c1-0065aeeef2\nX-Openstack-Request-Id: txae733272e5bc4ea18c4c1-0065aeeef2\nDate: Mon, 22 Jan 2024 22:40:50 GMT\n\n\u003chtml\u003e\u003ch1\u003eConflict\u003c/h1\u003e\u003cp\u003eThere was a conflict when trying to complete your request.\u003c/p\u003e\u003c/html\u003e\n```\nI suppose it\u0027s no different from master, but I wonder if we\u0027d do better by validating the first segment on HEAD, too...","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":1063,"context_line":"    def _return_slo_response(self, req, start_response, resp_iter, resp_attrs):"},{"line_number":1064,"context_line":"        headers \u003d {"},{"line_number":1065,"context_line":"            \u0027Etag\u0027: \u0027\"%s\"\u0027 % resp_attrs.slo_etag,"},{"line_number":1066,"context_line":"            \u0027X-Manifest-Etag\u0027: resp_attrs.json_md5,"},{"line_number":1067,"context_line":"            # swob will fix this for a GET with Range"},{"line_number":1068,"context_line":"            \u0027Content-Length\u0027: str(resp_attrs.slo_size),"},{"line_number":1069,"context_line":"            # ignore bogus content-range, make swob figure it out"}],"source_content_type":"text/x-python","patch_set":86,"id":"2c1136bb_b9f33e3a","line":1066,"in_reply_to":"66b1b769_94804b22","updated":"2024-03-01 16:31:30.000000000","message":"Acknowledged","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1074,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1075,"context_line":"            resp_attrs.update_from_segments(segments)"},{"line_number":1076,"context_line":"            headers[\u0027Etag\u0027] \u003d \u0027\"%s\"\u0027 % resp_attrs.slo_etag"},{"line_number":1077,"context_line":"            headers[\u0027Content-Length\u0027] \u003d str(resp_attrs.slo_size)"},{"line_number":1078,"context_line":"            part_num \u003d get_valid_part_num(req)"},{"line_number":1079,"context_line":"            if part_num:"},{"line_number":1080,"context_line":"                headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"}],"source_content_type":"text/x-python","patch_set":86,"id":"f23bcaab_e997bacf","line":1077,"updated":"2024-01-23 00:46:12.000000000","message":"Right; since we moved the definition of `headers` up, we now need to do this update even for non-part-number requests...","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":false,"context_lines":[{"line_number":1074,"context_line":"            segments \u003d self._parse_segments(resp_iter)"},{"line_number":1075,"context_line":"            resp_attrs.update_from_segments(segments)"},{"line_number":1076,"context_line":"            headers[\u0027Etag\u0027] \u003d \u0027\"%s\"\u0027 % resp_attrs.slo_etag"},{"line_number":1077,"context_line":"            headers[\u0027Content-Length\u0027] \u003d str(resp_attrs.slo_size)"},{"line_number":1078,"context_line":"            part_num \u003d get_valid_part_num(req)"},{"line_number":1079,"context_line":"            if part_num:"},{"line_number":1080,"context_line":"                headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"}],"source_content_type":"text/x-python","patch_set":86,"id":"245f0519_a7031037","line":1077,"in_reply_to":"f23bcaab_e997bacf","updated":"2024-02-20 19:23:59.000000000","message":"Acknowledged","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1077,"context_line":"            headers[\u0027Content-Length\u0027] \u003d str(resp_attrs.slo_size)"},{"line_number":1078,"context_line":"            part_num \u003d get_valid_part_num(req)"},{"line_number":1079,"context_line":"            if part_num:"},{"line_number":1080,"context_line":"                headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1081,"context_line":""},{"line_number":1082,"context_line":"            if part_num and part_num \u003e len(segments):"},{"line_number":1083,"context_line":"                if req.method \u003d\u003d \u0027HEAD\u0027:"}],"source_content_type":"text/x-python","patch_set":86,"id":"23c08265_180449ec","line":1080,"updated":"2024-01-23 00:46:12.000000000","message":"I could see some value in us sending this even for non-part-number requests. Though I suppose we\u0027d need to start tracking it in metadata, and more manifests would need to refetch for HEADs...","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":false,"context_lines":[{"line_number":1077,"context_line":"            headers[\u0027Content-Length\u0027] \u003d str(resp_attrs.slo_size)"},{"line_number":1078,"context_line":"            part_num \u003d get_valid_part_num(req)"},{"line_number":1079,"context_line":"            if part_num:"},{"line_number":1080,"context_line":"                headers[\u0027X-Parts-Count\u0027] \u003d len(segments)"},{"line_number":1081,"context_line":""},{"line_number":1082,"context_line":"            if part_num and part_num \u003e len(segments):"},{"line_number":1083,"context_line":"                if req.method \u003d\u003d \u0027HEAD\u0027:"}],"source_content_type":"text/x-python","patch_set":86,"id":"3b83ce74_3400065d","line":1080,"in_reply_to":"23c08265_180449ec","updated":"2024-02-20 19:23:59.000000000","message":"Yes, that was our concern when brought up during initial discussions, so for now we can restrict `X-Parts-Count` for part-num reqs only. If we decide to include it later on, we could do so in a follow-up","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1096,"context_line":"                start, end \u003d calculate_byterange_for_part_num("},{"line_number":1097,"context_line":"                    req, segments, part_num)"},{"line_number":1098,"context_line":"                headers[\u0027Content-Range\u0027] \u003d \\"},{"line_number":1099,"context_line":"                    \u0027bytes {}-{}/{}\u0027.format(start, end,"},{"line_number":1100,"context_line":"                                            resp_attrs.slo_size)"},{"line_number":1101,"context_line":"                # The RFC specifies 206 in the context of Range requests, and"},{"line_number":1102,"context_line":"                # Range headers MUST be ignored for HEADs [1], so a HEAD will"}],"source_content_type":"text/x-python","patch_set":86,"id":"82526f0f_6f59117d","line":1099,"range":{"start_line":1099,"start_character":51,"end_line":1099,"end_character":54},"updated":"2024-01-23 00:46:12.000000000","message":"Right; no `- 1` since we already did that in `calculate_byterange_for_part_num`","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":false,"context_lines":[{"line_number":1096,"context_line":"                start, end \u003d calculate_byterange_for_part_num("},{"line_number":1097,"context_line":"                    req, segments, part_num)"},{"line_number":1098,"context_line":"                headers[\u0027Content-Range\u0027] \u003d \\"},{"line_number":1099,"context_line":"                    \u0027bytes {}-{}/{}\u0027.format(start, end,"},{"line_number":1100,"context_line":"                                            resp_attrs.slo_size)"},{"line_number":1101,"context_line":"                # The RFC specifies 206 in the context of Range requests, and"},{"line_number":1102,"context_line":"                # Range headers MUST be ignored for HEADs [1], so a HEAD will"}],"source_content_type":"text/x-python","patch_set":86,"id":"e4fd56ed_ead58900","line":1099,"range":{"start_line":1099,"start_character":51,"end_line":1099,"end_character":54},"in_reply_to":"82526f0f_6f59117d","updated":"2024-02-20 19:23:59.000000000","message":"Acknowledged","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1104,"context_line":"                # returns Content-Length equal to the part size, rather than"},{"line_number":1105,"context_line":"                # the whole object size, so in this case we do return 206."},{"line_number":1106,"context_line":"                # [1] https://www.rfc-editor.org/rfc/rfc9110#name-range"},{"line_number":1107,"context_line":"                self._response_status \u003d \u0027206 Partial Content\u0027"},{"line_number":1108,"context_line":"            elif req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1109,"context_line":"                resp_iter \u003d []"},{"line_number":1110,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":86,"id":"19c91615_55c45d36","line":1107,"updated":"2024-01-23 00:46:12.000000000","message":"Hmm... interesting that we don\u0027t do anything with `Range` headers for *non*-SLO HEADs...","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":true,"context_lines":[{"line_number":1104,"context_line":"                # returns Content-Length equal to the part size, rather than"},{"line_number":1105,"context_line":"                # the whole object size, so in this case we do return 206."},{"line_number":1106,"context_line":"                # [1] https://www.rfc-editor.org/rfc/rfc9110#name-range"},{"line_number":1107,"context_line":"                self._response_status \u003d \u0027206 Partial Content\u0027"},{"line_number":1108,"context_line":"            elif req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1109,"context_line":"                resp_iter \u003d []"},{"line_number":1110,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":86,"id":"a4e9d1fd_3bc67db0","line":1107,"in_reply_to":"19c91615_55c45d36","updated":"2024-02-20 19:23:59.000000000","message":"My understanding was that we don\u0027t need range headers for HEAD reqs since we are only using them for scenarios such as checking if a resource exists or determining metadata and including a Range header in a HEAD request would be redundant and unnecessary?","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f251fd4037d95617bfa8eaed46bd13574a67a24a","unresolved":false,"context_lines":[{"line_number":1104,"context_line":"                # returns Content-Length equal to the part size, rather than"},{"line_number":1105,"context_line":"                # the whole object size, so in this case we do return 206."},{"line_number":1106,"context_line":"                # [1] https://www.rfc-editor.org/rfc/rfc9110#name-range"},{"line_number":1107,"context_line":"                self._response_status \u003d \u0027206 Partial Content\u0027"},{"line_number":1108,"context_line":"            elif req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1109,"context_line":"                resp_iter \u003d []"},{"line_number":1110,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":86,"id":"5172bd48_463b309d","line":1107,"in_reply_to":"a4e9d1fd_3bc67db0","updated":"2024-02-22 01:25:43.000000000","message":"Done","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1188,"context_line":"        #    variables, partly because we *might* get back a NOT"},{"line_number":1189,"context_line":"        #    resp_attrs.is_slo response (even if we had one to start), but"},{"line_number":1190,"context_line":"        #    hopefully they\u0027re just the manifest resp we needed to refetch!"},{"line_number":1191,"context_line":"        if resp_attrs.is_slo and not is_manifest_get:"},{"line_number":1192,"context_line":"            try:"},{"line_number":1193,"context_line":"                # only validate part-number if the request is to an SLO"},{"line_number":1194,"context_line":"                part_num \u003d get_valid_part_num(req)"}],"source_content_type":"text/x-python","patch_set":86,"id":"9222ecf5_760b4bb5","line":1191,"range":{"start_line":1191,"start_character":11,"end_line":1191,"end_character":52},"updated":"2024-01-23 00:46:12.000000000","message":"This feels like it ought to be under the purview of `_is_manifest_and_need_to_refetch`... and I suppose it used to be. Maybe we should rename that back to `_need_to_refetch_manifest`, as before https://review.opendev.org/c/openstack/swift/+/893578/ ?\n\nMy complaint then was that it looked like we weren\u0027t checking our assumptions; that we were asking questions about something we assumed was a manifest before we checked that it was. Now, though, we have the explicit check here.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":false,"context_lines":[{"line_number":1188,"context_line":"        #    variables, partly because we *might* get back a NOT"},{"line_number":1189,"context_line":"        #    resp_attrs.is_slo response (even if we had one to start), but"},{"line_number":1190,"context_line":"        #    hopefully they\u0027re just the manifest resp we needed to refetch!"},{"line_number":1191,"context_line":"        if resp_attrs.is_slo and not is_manifest_get:"},{"line_number":1192,"context_line":"            try:"},{"line_number":1193,"context_line":"                # only validate part-number if the request is to an SLO"},{"line_number":1194,"context_line":"                part_num \u003d get_valid_part_num(req)"}],"source_content_type":"text/x-python","patch_set":86,"id":"42c6e03c_b0379416","line":1191,"range":{"start_line":1191,"start_character":11,"end_line":1191,"end_character":52},"in_reply_to":"9222ecf5_760b4bb5","updated":"2024-02-20 19:23:59.000000000","message":"I agree the latter is a more suitable name for the function.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d934608e50986c4659e5e336a8ccfa52fcb750a5","unresolved":true,"context_lines":[{"line_number":1194,"context_line":"                part_num \u003d get_valid_part_num(req)"},{"line_number":1195,"context_line":"            except HTTPException:"},{"line_number":1196,"context_line":"                friendly_close(resp_iter)"},{"line_number":1197,"context_line":"                raise"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1200,"context_line":"                    req, resp_attrs, part_num):"}],"source_content_type":"text/x-python","patch_set":86,"id":"4923eca2_ab88eeeb","line":1197,"updated":"2024-01-23 00:46:12.000000000","message":"There\u0027s something about this construction that rubs me wrong -- I get the necessity (given how `get_valid_part_num` currently works), but I feel like something more go-like, like\n```\npart_num, err_msg \u003d get_valid_part_num(req)\nif err_msg:\n    friendly_close(resp_iter)\n    raise HTTPBadRequest(request\u003dreq, body\u003derr_msg)\n```\nmight be better/easier to follow.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"3d6e742221a79f4afa1cd23525da787142998785","unresolved":true,"context_lines":[{"line_number":1194,"context_line":"                part_num \u003d get_valid_part_num(req)"},{"line_number":1195,"context_line":"            except HTTPException:"},{"line_number":1196,"context_line":"                friendly_close(resp_iter)"},{"line_number":1197,"context_line":"                raise"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1200,"context_line":"                    req, resp_attrs, part_num):"}],"source_content_type":"text/x-python","patch_set":86,"id":"bc825913_57e2f06e","line":1197,"in_reply_to":"4923eca2_ab88eeeb","updated":"2024-02-20 19:23:59.000000000","message":"I will have to look into this a bit more.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":1194,"context_line":"                part_num \u003d get_valid_part_num(req)"},{"line_number":1195,"context_line":"            except HTTPException:"},{"line_number":1196,"context_line":"                friendly_close(resp_iter)"},{"line_number":1197,"context_line":"                raise"},{"line_number":1198,"context_line":""},{"line_number":1199,"context_line":"            if self._is_manifest_and_need_to_refetch("},{"line_number":1200,"context_line":"                    req, resp_attrs, part_num):"}],"source_content_type":"text/x-python","patch_set":86,"id":"2706b380_1787053b","line":1197,"in_reply_to":"bc825913_57e2f06e","updated":"2024-03-01 16:31:30.000000000","message":"Now i see that when we move this outside of the try-except block a situation arises in which all our unit-tests start failing stating we have unclosed requests which i suspect is because of the way we are handling HTTPBadRequest but we have that error handling branch out into two scenarios in which one is completely different form the other which is as follows:\n```\n\n    except ValueError:\n        raise HTTPBadRequest(\u0027Part number must be an integer greater \u0027\n                             \u0027than 0\u0027)\n\n    if req.range:\n        raise HTTPBadRequest(req\u003dreq,\n                             body\u003d\u0027Range requests are not supported \u0027\n                                  \u0027with part number queries\u0027)\n```\n\nso conclusively I don\u0027t think we can go ahead with this error handling here but its a good thought to implement it in the future.","commit_id":"4a321be2853d2838069d8f0c28419fe8e3bd6e66"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"71e87eba2966bd418f4dfc25b8e8635bcb332f17","unresolved":true,"context_lines":[{"line_number":277,"context_line":"will return the contents of the ``nth`` segment. Segments are indexed from 1,"},{"line_number":278,"context_line":"so ``n`` must be an integer between 1 and the total number of segments in the"},{"line_number":279,"context_line":"manifest. The response status will be ``206 Partial Content`` and its headers"},{"line_number":280,"context_line":"will include: an ``X-Parts-Count`` header equal to the total number of"},{"line_number":281,"context_line":"segments; a ``Content-Length`` header equal to the length of the specified"},{"line_number":282,"context_line":"segment; a ``Content-Range`` header describing the byte range of the specified"},{"line_number":283,"context_line":"part within the SLO. A HEAD request with a ``part-number`` parameter will also"}],"source_content_type":"text/x-python","patch_set":88,"id":"6d3986f9_729df967","line":280,"range":{"start_line":280,"start_character":19,"end_line":280,"end_character":32},"updated":"2024-02-28 06:49:53.000000000","message":"Just thinking out loud, but I wonder if we should always return the parts count on a HEAD of a SLO. That why you\u0027d know how many you could call if you want to use this API.. I guess you could just call part-number\u003d1 and then know how many left you have :hmm:\n\nIn anycase, if we decide to do this, it can easily be a follow up.","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":277,"context_line":"will return the contents of the ``nth`` segment. Segments are indexed from 1,"},{"line_number":278,"context_line":"so ``n`` must be an integer between 1 and the total number of segments in the"},{"line_number":279,"context_line":"manifest. The response status will be ``206 Partial Content`` and its headers"},{"line_number":280,"context_line":"will include: an ``X-Parts-Count`` header equal to the total number of"},{"line_number":281,"context_line":"segments; a ``Content-Length`` header equal to the length of the specified"},{"line_number":282,"context_line":"segment; a ``Content-Range`` header describing the byte range of the specified"},{"line_number":283,"context_line":"part within the SLO. A HEAD request with a ``part-number`` parameter will also"}],"source_content_type":"text/x-python","patch_set":88,"id":"1faabb2e_7d43bc92","line":280,"range":{"start_line":280,"start_character":19,"end_line":280,"end_character":32},"in_reply_to":"6d3986f9_729df967","updated":"2024-03-01 16:31:30.000000000","message":"Acknowledged","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"71e87eba2966bd418f4dfc25b8e8635bcb332f17","unresolved":true,"context_lines":[{"line_number":281,"context_line":"segments; a ``Content-Length`` header equal to the length of the specified"},{"line_number":282,"context_line":"segment; a ``Content-Range`` header describing the byte range of the specified"},{"line_number":283,"context_line":"part within the SLO. A HEAD request with a ``part-number`` parameter will also"},{"line_number":284,"context_line":"return a response with status ``206 Partial Content`` and the same headers."},{"line_number":285,"context_line":""},{"line_number":286,"context_line":".. note::"},{"line_number":287,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"c081a047_2d017952","line":284,"range":{"start_line":284,"start_character":54,"end_line":284,"end_character":75},"updated":"2024-02-28 06:49:53.000000000","message":"Ahh I can get the x-parts-count from a header with the part-number querystring. I guess that\u0027s cool.\nBut still we return X-Static-Large-Object so maybe X-Parts-Count would be useful to always know too. I meaan we get to make up our own partnumber api for swift slos right ;)\nSo long as we\u0027re always calulating this number anyway.","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":281,"context_line":"segments; a ``Content-Length`` header equal to the length of the specified"},{"line_number":282,"context_line":"segment; a ``Content-Range`` header describing the byte range of the specified"},{"line_number":283,"context_line":"part within the SLO. A HEAD request with a ``part-number`` parameter will also"},{"line_number":284,"context_line":"return a response with status ``206 Partial Content`` and the same headers."},{"line_number":285,"context_line":""},{"line_number":286,"context_line":".. note::"},{"line_number":287,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"873b830d_01b43cc8","line":284,"range":{"start_line":284,"start_character":54,"end_line":284,"end_character":75},"in_reply_to":"c081a047_2d017952","updated":"2024-03-01 16:31:30.000000000","message":"Done","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"71e87eba2966bd418f4dfc25b8e8635bcb332f17","unresolved":true,"context_lines":[{"line_number":641,"context_line":"    includes a part-number parameter it will be parsed into a valid integer"},{"line_number":642,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":643,"context_line":"    param we will return None.  If the part-number parameter is invalid for"},{"line_number":644,"context_line":"    the given request we will raise the appropriate HTTP exception"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":"    :param req: the request object"},{"line_number":647,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"52ae62fd_0c6f174b","line":644,"updated":"2024-02-28 06:49:53.000000000","message":"Do we need to talk about having a range also raises a bad request?","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"71e87eba2966bd418f4dfc25b8e8635bcb332f17","unresolved":true,"context_lines":[{"line_number":640,"context_line":"    part-number parameter in query string.  If the passed in request"},{"line_number":641,"context_line":"    includes a part-number parameter it will be parsed into a valid integer"},{"line_number":642,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":643,"context_line":"    param we will return None.  If the part-number parameter is invalid for"},{"line_number":644,"context_line":"    the given request we will raise the appropriate HTTP exception"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":"    :param req: the request object"},{"line_number":647,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"747f07f1_660603ea","line":644,"range":{"start_line":643,"start_character":65,"end_line":644,"end_character":21},"updated":"2024-02-28 06:49:53.000000000","message":"What do you mean invalid, if say we ask for a part outside the scope or are you talking about the reasons we raise a BadRequest below?","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":641,"context_line":"    includes a part-number parameter it will be parsed into a valid integer"},{"line_number":642,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":643,"context_line":"    param we will return None.  If the part-number parameter is invalid for"},{"line_number":644,"context_line":"    the given request we will raise the appropriate HTTP exception"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":"    :param req: the request object"},{"line_number":647,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"edd9be2a_dcfac16b","line":644,"in_reply_to":"52ae62fd_0c6f174b","updated":"2024-03-01 16:31:30.000000000","message":"This has been addressed in a follow-on patch.","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d9df2910db35ff3da9a9fde393c67b40c313122f","unresolved":false,"context_lines":[{"line_number":640,"context_line":"    part-number parameter in query string.  If the passed in request"},{"line_number":641,"context_line":"    includes a part-number parameter it will be parsed into a valid integer"},{"line_number":642,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":643,"context_line":"    param we will return None.  If the part-number parameter is invalid for"},{"line_number":644,"context_line":"    the given request we will raise the appropriate HTTP exception"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":"    :param req: the request object"},{"line_number":647,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9bb5679c_1110f0a2","line":644,"range":{"start_line":643,"start_character":65,"end_line":644,"end_character":21},"in_reply_to":"747f07f1_660603ea","updated":"2024-03-01 16:31:30.000000000","message":"Yes precisely.","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"d28ec72a0284832e43722dd82921746e77620772","unresolved":false,"context_lines":[{"line_number":641,"context_line":"    includes a part-number parameter it will be parsed into a valid integer"},{"line_number":642,"context_line":"    and returned.  If the passed in request does not include a part-number"},{"line_number":643,"context_line":"    param we will return None.  If the part-number parameter is invalid for"},{"line_number":644,"context_line":"    the given request we will raise the appropriate HTTP exception"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":"    :param req: the request object"},{"line_number":647,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"78c36b1b_943a9576","line":644,"in_reply_to":"edd9be2a_dcfac16b","updated":"2024-03-01 16:35:27.000000000","message":"https://review.opendev.org/c/openstack/swift/+/906391","commit_id":"db1c5977a935da79804a71631ab1d734316dcab0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94f5d5ebb808aef3587515aafc2b50995fa1f889","unresolved":true,"context_lines":[{"line_number":634,"context_line":"    return byteranges"},{"line_number":635,"context_line":""},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"def get_valid_part_num(req):"},{"line_number":638,"context_line":"    \"\"\""},{"line_number":639,"context_line":"    Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":640,"context_line":"    part-number parameter in query string.  If the passed in request"}],"source_content_type":"text/x-python","patch_set":90,"id":"698b3908_e0dfec9c","line":637,"updated":"2024-03-08 12:22:17.000000000","message":"nit: this could belong in request_helpers.py","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4398bb3f99f320617f028697b9e2bb6317a90fab","unresolved":false,"context_lines":[{"line_number":634,"context_line":"    return byteranges"},{"line_number":635,"context_line":""},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"def get_valid_part_num(req):"},{"line_number":638,"context_line":"    \"\"\""},{"line_number":639,"context_line":"    Any non-range GET or HEAD request for a SLO object may include a"},{"line_number":640,"context_line":"    part-number parameter in query string.  If the passed in request"}],"source_content_type":"text/x-python","patch_set":90,"id":"e962d567_a00f51e5","line":637,"in_reply_to":"698b3908_e0dfec9c","updated":"2024-03-12 13:47:44.000000000","message":"Done","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94f5d5ebb808aef3587515aafc2b50995fa1f889","unresolved":true,"context_lines":[{"line_number":954,"context_line":"        return first_byte \u003d\u003d 0 and last_byte \u003d\u003d length - 1"},{"line_number":955,"context_line":""},{"line_number":956,"context_line":"    def _need_to_refetch_manifest(self, req, resp_attrs,"},{"line_number":957,"context_line":"                                  is_part_num_request):"},{"line_number":958,"context_line":"        \"\"\""},{"line_number":959,"context_line":"        Check if the segments will be needed to service the request and update"},{"line_number":960,"context_line":"        the segment_listing_needed attribute."}],"source_content_type":"text/x-python","patch_set":90,"id":"cd9c54c8_67fc4a7a","line":957,"updated":"2024-03-08 12:22:17.000000000","message":"nit: this can be on one line","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4398bb3f99f320617f028697b9e2bb6317a90fab","unresolved":false,"context_lines":[{"line_number":954,"context_line":"        return first_byte \u003d\u003d 0 and last_byte \u003d\u003d length - 1"},{"line_number":955,"context_line":""},{"line_number":956,"context_line":"    def _need_to_refetch_manifest(self, req, resp_attrs,"},{"line_number":957,"context_line":"                                  is_part_num_request):"},{"line_number":958,"context_line":"        \"\"\""},{"line_number":959,"context_line":"        Check if the segments will be needed to service the request and update"},{"line_number":960,"context_line":"        the segment_listing_needed attribute."}],"source_content_type":"text/x-python","patch_set":90,"id":"64cbcd5d_23df120e","line":957,"in_reply_to":"cd9c54c8_67fc4a7a","updated":"2024-03-12 13:47:44.000000000","message":"Done","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b331a5bba081897d49da6dd9eaf5aad6b202b55b","unresolved":true,"context_lines":[{"line_number":1090,"context_line":"                    resp_iter \u003d [body]"},{"line_number":1091,"context_line":"                    headers[\u0027Content-Length\u0027] \u003d len(body)"},{"line_number":1092,"context_line":"                headers[\u0027Content-Range\u0027] \u003d \u0027bytes */%d\u0027 % resp_attrs.slo_size"},{"line_number":1093,"context_line":"                self._response_status \u003d \u0027416 Requested Range Not Satisfiable\u0027"},{"line_number":1094,"context_line":"            elif part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1095,"context_line":"                resp_iter \u003d []"},{"line_number":1096,"context_line":"                headers[\u0027Content-Length\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":90,"id":"a5fbe992_757499e6","line":1093,"range":{"start_line":1093,"start_character":40,"end_line":1093,"end_character":77},"updated":"2024-03-12 05:53:45.000000000","message":"Seems odd that we hard code these when these are also defined in swob. We could use something like, heck we already import RESPONSE_REASONS:\n \n   self._response_status \u003d RESPONSE_REASONS[416][0]\n\nBut seeing as we have +2 here already might just leave this as a NIT or follow up","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"75141c147a1f7db56d5fb4a491ba7e44547a19c2","unresolved":false,"context_lines":[{"line_number":1090,"context_line":"                    resp_iter \u003d [body]"},{"line_number":1091,"context_line":"                    headers[\u0027Content-Length\u0027] \u003d len(body)"},{"line_number":1092,"context_line":"                headers[\u0027Content-Range\u0027] \u003d \u0027bytes */%d\u0027 % resp_attrs.slo_size"},{"line_number":1093,"context_line":"                self._response_status \u003d \u0027416 Requested Range Not Satisfiable\u0027"},{"line_number":1094,"context_line":"            elif part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1095,"context_line":"                resp_iter \u003d []"},{"line_number":1096,"context_line":"                headers[\u0027Content-Length\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":90,"id":"6ca5f2b8_895a7204","line":1093,"range":{"start_line":1093,"start_character":40,"end_line":1093,"end_character":77},"in_reply_to":"343abd34_f63653bf","updated":"2024-03-12 22:52:21.000000000","message":"Well my point was we have the same text we keep in a status number to text dictionary that has already been imported into this file. So instead of redefining the test we could just use the one already defined... but I guess it\u0027s just a NIT because it\u0027s not like we\u0027re going to change it.","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4398bb3f99f320617f028697b9e2bb6317a90fab","unresolved":false,"context_lines":[{"line_number":1090,"context_line":"                    resp_iter \u003d [body]"},{"line_number":1091,"context_line":"                    headers[\u0027Content-Length\u0027] \u003d len(body)"},{"line_number":1092,"context_line":"                headers[\u0027Content-Range\u0027] \u003d \u0027bytes */%d\u0027 % resp_attrs.slo_size"},{"line_number":1093,"context_line":"                self._response_status \u003d \u0027416 Requested Range Not Satisfiable\u0027"},{"line_number":1094,"context_line":"            elif part_num and req.method \u003d\u003d \u0027HEAD\u0027:"},{"line_number":1095,"context_line":"                resp_iter \u003d []"},{"line_number":1096,"context_line":"                headers[\u0027Content-Length\u0027] \u003d \\"}],"source_content_type":"text/x-python","patch_set":90,"id":"343abd34_f63653bf","line":1093,"range":{"start_line":1093,"start_character":40,"end_line":1093,"end_character":77},"in_reply_to":"a5fbe992_757499e6","updated":"2024-03-12 13:47:44.000000000","message":"This was does in order to be s3-response compatible and have slo handle the error in this situation more efficiently and allow us to bail out of the code more quickly than having to rely on the swift-s3api error translation layer","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b331a5bba081897d49da6dd9eaf5aad6b202b55b","unresolved":true,"context_lines":[{"line_number":1181,"context_line":"        orig_path_info \u003d req.path_info"},{"line_number":1182,"context_line":"        resp_iter \u003d self._app_call(req.environ)"},{"line_number":1183,"context_line":"        resp_attrs \u003d RespAttrs.from_headers(self._response_headers)"},{"line_number":1184,"context_line":"        # the next two calls hide a couple side-effects, sorry:"},{"line_number":1185,"context_line":"        #"},{"line_number":1186,"context_line":"        # 1) regardless of the return value the \"need_to_refetch\" check *may*"},{"line_number":1187,"context_line":"        #    also set self.segment_listing_needed \u003d True (it\u0027s commented to"},{"line_number":1188,"context_line":"        #    help you wrap your head around that one, good luck)"},{"line_number":1189,"context_line":"        # 2) if we refetch, we overwrite the current resp_iter and resp_attrs"},{"line_number":1190,"context_line":"        #    variables, partly because we *might* get back a NOT"},{"line_number":1191,"context_line":"        #    resp_attrs.is_slo response (even if we had one to start), but"},{"line_number":1192,"context_line":"        #    hopefully they\u0027re just the manifest resp we needed to refetch!"},{"line_number":1193,"context_line":"        if resp_attrs.is_slo and not is_manifest_get:"},{"line_number":1194,"context_line":"            try:"},{"line_number":1195,"context_line":"                # only validate part-number if the request is to an SLO"}],"source_content_type":"text/x-python","patch_set":90,"id":"bdae00b5_a44f229a","line":1192,"range":{"start_line":1184,"start_character":9,"end_line":1192,"end_character":75},"updated":"2024-03-12 05:53:45.000000000","message":"Ahh, I don\u0027t think this comment is suppose to be here anymore. Seems it should\u0027ve been moved down to around line 1200 before the `self._need_to_refetch_manifest`, because that\u0027s where `self.segment_listing_needed` could be set.","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4398bb3f99f320617f028697b9e2bb6317a90fab","unresolved":false,"context_lines":[{"line_number":1181,"context_line":"        orig_path_info \u003d req.path_info"},{"line_number":1182,"context_line":"        resp_iter \u003d self._app_call(req.environ)"},{"line_number":1183,"context_line":"        resp_attrs \u003d RespAttrs.from_headers(self._response_headers)"},{"line_number":1184,"context_line":"        # the next two calls hide a couple side-effects, sorry:"},{"line_number":1185,"context_line":"        #"},{"line_number":1186,"context_line":"        # 1) regardless of the return value the \"need_to_refetch\" check *may*"},{"line_number":1187,"context_line":"        #    also set self.segment_listing_needed \u003d True (it\u0027s commented to"},{"line_number":1188,"context_line":"        #    help you wrap your head around that one, good luck)"},{"line_number":1189,"context_line":"        # 2) if we refetch, we overwrite the current resp_iter and resp_attrs"},{"line_number":1190,"context_line":"        #    variables, partly because we *might* get back a NOT"},{"line_number":1191,"context_line":"        #    resp_attrs.is_slo response (even if we had one to start), but"},{"line_number":1192,"context_line":"        #    hopefully they\u0027re just the manifest resp we needed to refetch!"},{"line_number":1193,"context_line":"        if resp_attrs.is_slo and not is_manifest_get:"},{"line_number":1194,"context_line":"            try:"},{"line_number":1195,"context_line":"                # only validate part-number if the request is to an SLO"}],"source_content_type":"text/x-python","patch_set":90,"id":"b211de35_16cf77e0","line":1192,"range":{"start_line":1184,"start_character":9,"end_line":1192,"end_character":75},"in_reply_to":"bdae00b5_a44f229a","updated":"2024-03-12 13:47:44.000000000","message":"Done","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94f5d5ebb808aef3587515aafc2b50995fa1f889","unresolved":true,"context_lines":[{"line_number":1199,"context_line":"                raise"},{"line_number":1200,"context_line":""},{"line_number":1201,"context_line":"            if self._need_to_refetch_manifest("},{"line_number":1202,"context_line":"                    req, resp_attrs, part_num):"},{"line_number":1203,"context_line":"                # reset path in case it was modified during original request"},{"line_number":1204,"context_line":"                # (e.g. object versioning might re-write the path)"},{"line_number":1205,"context_line":"                req.path_info \u003d orig_path_info"}],"source_content_type":"text/x-python","patch_set":90,"id":"8138606c_937e4cb5","line":1202,"updated":"2024-03-08 12:22:17.000000000","message":"nit: can be one line","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4398bb3f99f320617f028697b9e2bb6317a90fab","unresolved":false,"context_lines":[{"line_number":1199,"context_line":"                raise"},{"line_number":1200,"context_line":""},{"line_number":1201,"context_line":"            if self._need_to_refetch_manifest("},{"line_number":1202,"context_line":"                    req, resp_attrs, part_num):"},{"line_number":1203,"context_line":"                # reset path in case it was modified during original request"},{"line_number":1204,"context_line":"                # (e.g. object versioning might re-write the path)"},{"line_number":1205,"context_line":"                req.path_info \u003d orig_path_info"}],"source_content_type":"text/x-python","patch_set":90,"id":"4e7b3840_1483350f","line":1202,"in_reply_to":"8138606c_937e4cb5","updated":"2024-03-12 13:47:44.000000000","message":"Done","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"}],"test/functional/test_slo.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5211fc2c3ba77066137c614d4e08ed7c531c1d98","unresolved":true,"context_lines":[{"line_number":322,"context_line":"                for h, v in file_item.conn.response.getheaders())"},{"line_number":323,"context_line":"            self.assertEqual(headers[\u0027content-length\u0027],"},{"line_number":324,"context_line":"                             str(seg_info[\u0027size_bytes\u0027]))"},{"line_number":325,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], \u0027\"%s\"\u0027 % slo_etag)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def test_slo_container_listing(self):"},{"line_number":328,"context_line":"        # the listing object size should equal the sum of the size of the"}],"source_content_type":"text/x-python","patch_set":7,"id":"cb9b7247_94072a35","line":325,"updated":"2023-09-21 18:23:30.000000000","message":"We should include some assertions around `X-Parts-Count` and `Content-Range` here.\n\nWhat happens when you request `?part-number\u003d6`? Or `?part-number\u003d1` but for a non-SLO?","commit_id":"1bee22f039141b6a695453dbeaa9333489ee1db7"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4a5ed7b9eb5e25b3aefb4cf80a5d0cfba2f04b94","unresolved":false,"context_lines":[{"line_number":322,"context_line":"                for h, v in file_item.conn.response.getheaders())"},{"line_number":323,"context_line":"            self.assertEqual(headers[\u0027content-length\u0027],"},{"line_number":324,"context_line":"                             str(seg_info[\u0027size_bytes\u0027]))"},{"line_number":325,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], \u0027\"%s\"\u0027 % slo_etag)"},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"    def test_slo_container_listing(self):"},{"line_number":328,"context_line":"        # the listing object size should equal the sum of the size of the"}],"source_content_type":"text/x-python","patch_set":7,"id":"bc123cef_32f5fa2d","line":325,"in_reply_to":"cb9b7247_94072a35","updated":"2023-09-25 22:44:56.000000000","message":"Thanks for noting that, because we didn\u0027t have assertions in our functional tests, we saw the issues we saw in our S3 cross-compat tests ref:https://review.opendev.org/c/openstack/swift/+/894580","commit_id":"1bee22f039141b6a695453dbeaa9333489ee1db7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":315,"context_line":"            checksum.update(seg_info[\u0027etag\u0027].encode(\u0027ascii\u0027))"},{"line_number":316,"context_line":"        slo_etag \u003d checksum.hexdigest()"},{"line_number":317,"context_line":"        for i, seg_info in enumerate(seg_info_list, start\u003d1):"},{"line_number":318,"context_line":"            part_contents \u003d file_item.read(parms\u003d{\u0027part-number\u0027: i})"},{"line_number":319,"context_line":"            self.assertEqual(len(part_contents), seg_info[\u0027size_bytes\u0027])"},{"line_number":320,"context_line":"            headers \u003d dict("},{"line_number":321,"context_line":"                (h.lower(), v)"}],"source_content_type":"text/x-python","patch_set":25,"id":"0794a5bf_a11092d7","line":318,"updated":"2023-10-10 17:22:15.000000000","message":"maybe add some functional tests for HEAD requests too?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"1cb078b5273ad57fa296b0d63b4bcf79d9ac5581","unresolved":false,"context_lines":[{"line_number":315,"context_line":"            checksum.update(seg_info[\u0027etag\u0027].encode(\u0027ascii\u0027))"},{"line_number":316,"context_line":"        slo_etag \u003d checksum.hexdigest()"},{"line_number":317,"context_line":"        for i, seg_info in enumerate(seg_info_list, start\u003d1):"},{"line_number":318,"context_line":"            part_contents \u003d file_item.read(parms\u003d{\u0027part-number\u0027: i})"},{"line_number":319,"context_line":"            self.assertEqual(len(part_contents), seg_info[\u0027size_bytes\u0027])"},{"line_number":320,"context_line":"            headers \u003d dict("},{"line_number":321,"context_line":"                (h.lower(), v)"}],"source_content_type":"text/x-python","patch_set":25,"id":"d9b82d9b_ea6b9da5","line":318,"in_reply_to":"0794a5bf_a11092d7","updated":"2023-10-14 02:19:46.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5a76c5e33b17b819190df876f5186f146b359b9a","unresolved":true,"context_lines":[{"line_number":340,"context_line":"                             str(part_info[\u0027content_length\u0027]))"},{"line_number":341,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], part_info[\u0027etag\u0027])"},{"line_number":342,"context_line":"            self.assertEqual(headers[\u0027x-manifest-etag\u0027],"},{"line_number":343,"context_line":"                             part_info[\u0027x_manifest_etag\u0027])"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def test_slo_container_listing(self):"},{"line_number":346,"context_line":"        # the listing object size should equal the sum of the size of the"}],"source_content_type":"text/x-python","patch_set":49,"id":"2f270534_e2f14373","line":343,"updated":"2023-11-07 21:43:17.000000000","message":"I\u0027d be interested in seeing some tests with (at least) `?part-number\u003d1` and `?part-number\u003d2` but directed at a normal object. The first I\u0027d expect to 200; the second, it might be nice if it\u0027d 416 (similar to what would happen if it was a SLO with exactly one segment).","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"832c745b7948912d939cc99560941ca398e1191e","unresolved":true,"context_lines":[{"line_number":340,"context_line":"                             str(part_info[\u0027content_length\u0027]))"},{"line_number":341,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], part_info[\u0027etag\u0027])"},{"line_number":342,"context_line":"            self.assertEqual(headers[\u0027x-manifest-etag\u0027],"},{"line_number":343,"context_line":"                             part_info[\u0027x_manifest_etag\u0027])"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def test_slo_container_listing(self):"},{"line_number":346,"context_line":"        # the listing object size should equal the sum of the size of the"}],"source_content_type":"text/x-python","patch_set":49,"id":"6790cd4e_b0b45d0d","line":343,"in_reply_to":"2f270534_e2f14373","updated":"2023-11-18 21:45:42.000000000","message":"This is a very important point to note, We will have to also implement a part of the API in the ObjectController, and we should be expecting a 206 and not a 200 since aws does the same in the aforementioned scenario:\n\n```\nashnair@ashnair-mlt ~ % aws s3api get-object --bucket ash-test-mpu --key java --part-number 1 outfile\n{\n    \"AcceptRanges\": \"bytes\",\n    \"LastModified\": \"Wed, 15 Nov 2023 17:52:47 GMT\",\n    \"ContentLength\": 261801,\n    \"ETag\": \"\\\"9a8ac0c1e077634e73cce476636a72af\\\"\",\n    \"VersionId\": \"Kb2HUt2UKCe5o5CfcEIaiu.gXcV80otK\",\n    \"ContentRange\": \"bytes 0-261800/261801\",\n    \"ContentType\": \"binary/octet-stream\",\n    \"ServerSideEncryption\": \"AES256\",\n    \"Metadata\": {}\n}\nashnair@ashnair-mlt ~ % aws s3api get-object --bucket ash-test-mpu --key java --part-number 2 outfile\n\nAn error occurred (InvalidPartNumber) when calling the GetObject operation: The requested partnumber is not satisfiable\n```","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"9078ffc3559124311bc588803e3d5280b54513bd","unresolved":false,"context_lines":[{"line_number":340,"context_line":"                             str(part_info[\u0027content_length\u0027]))"},{"line_number":341,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], part_info[\u0027etag\u0027])"},{"line_number":342,"context_line":"            self.assertEqual(headers[\u0027x-manifest-etag\u0027],"},{"line_number":343,"context_line":"                             part_info[\u0027x_manifest_etag\u0027])"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    def test_slo_container_listing(self):"},{"line_number":346,"context_line":"        # the listing object size should equal the sum of the size of the"}],"source_content_type":"text/x-python","patch_set":49,"id":"7ca9bfa7_ef3ec7a2","line":343,"in_reply_to":"6790cd4e_b0b45d0d","updated":"2023-11-25 17:39:45.000000000","message":"Done","commit_id":"0d3a8fd02c658ea7e41fc4eb1b5e1a86ec07e578"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":302,"context_line":"        self.assertEqual(400, file_item.conn.response.status, resp_body)"},{"line_number":303,"context_line":"        self.assertEqual(b\u0027Part number must be an integer between 1 and 1000, \u0027"},{"line_number":304,"context_line":"                         b\u0027inclusive\u0027,"},{"line_number":305,"context_line":"                         resp_body)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def test_get_part_number_simple_manifest(self):"},{"line_number":308,"context_line":"        # this is coupled with created_segments, but all these tests are"}],"source_content_type":"text/x-python","patch_set":51,"id":"4917e777_a0215fde","line":305,"updated":"2023-11-13 12:17:47.000000000","message":"It would be good to similarly test the upper bounds - both the API supported limit and the number of parts in \u0027manifest-abcde\u0027","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":302,"context_line":"        self.assertEqual(400, file_item.conn.response.status, resp_body)"},{"line_number":303,"context_line":"        self.assertEqual(b\u0027Part number must be an integer between 1 and 1000, \u0027"},{"line_number":304,"context_line":"                         b\u0027inclusive\u0027,"},{"line_number":305,"context_line":"                         resp_body)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def test_get_part_number_simple_manifest(self):"},{"line_number":308,"context_line":"        # this is coupled with created_segments, but all these tests are"}],"source_content_type":"text/x-python","patch_set":51,"id":"03c256e4_29946bad","line":305,"in_reply_to":"4917e777_a0215fde","updated":"2023-11-13 23:30:43.000000000","message":"Done","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de9e6ba5253b23c318254790685e3f95e82c2f","unresolved":true,"context_lines":[{"line_number":305,"context_line":"                         resp_body)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def test_get_part_number_simple_manifest(self):"},{"line_number":308,"context_line":"        # this is coupled with created_segments, but all these tests are"},{"line_number":309,"context_line":"        file_item \u003d self.env.container.file(\u0027manifest-abcde\u0027)"},{"line_number":310,"context_line":"        seg_info_list \u003d ["},{"line_number":311,"context_line":"            self.env.seg_info[\"seg_%s\" % letter]"}],"source_content_type":"text/x-python","patch_set":51,"id":"19e00fb3_e7ba842d","line":308,"updated":"2023-11-13 12:17:47.000000000","message":"I don\u0027t understand the comment: what is ``created_segments``?\n\noh, do you mean the test *assumes* ``create_segments`` in TestSloEnv? I wonder if there\u0027s any special reason to call that out in this test vs all the others","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"0ce00c5e7efc6f6705e5e5774f7dfe08ffa66670","unresolved":false,"context_lines":[{"line_number":305,"context_line":"                         resp_body)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    def test_get_part_number_simple_manifest(self):"},{"line_number":308,"context_line":"        # this is coupled with created_segments, but all these tests are"},{"line_number":309,"context_line":"        file_item \u003d self.env.container.file(\u0027manifest-abcde\u0027)"},{"line_number":310,"context_line":"        seg_info_list \u003d ["},{"line_number":311,"context_line":"            self.env.seg_info[\"seg_%s\" % letter]"}],"source_content_type":"text/x-python","patch_set":51,"id":"ddc0786f_1d5ec47d","line":308,"in_reply_to":"19e00fb3_e7ba842d","updated":"2023-11-13 23:30:43.000000000","message":"I will remove that comment since it looks confusing!","commit_id":"f831de4fe112abc2a15e599bb6305858049afe39"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"01283767d778671ddc3571309a85aa673ff33c3a","unresolved":true,"context_lines":[{"line_number":359,"context_line":"            for letter in [\u0027a\u0027, \u0027b\u0027, \u0027c\u0027, \u0027d\u0027, \u0027e\u0027]"},{"line_number":360,"context_line":"        ]"},{"line_number":361,"context_line":"        for i, seg_info in enumerate(seg_info_list, start\u003d1):"},{"line_number":362,"context_line":"            part_info \u003d file_item.info(parms\u003d{\u0027part-number\u0027: i})"},{"line_number":363,"context_line":"            headers \u003d dict("},{"line_number":364,"context_line":"                (h.lower(), v)"},{"line_number":365,"context_line":"                for h, v in file_item.conn.response.getheaders())"}],"source_content_type":"text/x-python","patch_set":72,"id":"dc9e8736_d54f3491","line":362,"updated":"2023-12-01 12:53:50.000000000","message":"this will fail because File.info asserts that the response is 200, whereas for a part-num HEAD it is 206.","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"157b7c9eba7d0a63af19a5a14224687e2485dcf1","unresolved":false,"context_lines":[{"line_number":359,"context_line":"            for letter in [\u0027a\u0027, \u0027b\u0027, \u0027c\u0027, \u0027d\u0027, \u0027e\u0027]"},{"line_number":360,"context_line":"        ]"},{"line_number":361,"context_line":"        for i, seg_info in enumerate(seg_info_list, start\u003d1):"},{"line_number":362,"context_line":"            part_info \u003d file_item.info(parms\u003d{\u0027part-number\u0027: i})"},{"line_number":363,"context_line":"            headers \u003d dict("},{"line_number":364,"context_line":"                (h.lower(), v)"},{"line_number":365,"context_line":"                for h, v in file_item.conn.response.getheaders())"}],"source_content_type":"text/x-python","patch_set":72,"id":"1e06e497_ac3d3cbd","line":362,"in_reply_to":"dc9e8736_d54f3491","updated":"2023-12-01 19:57:20.000000000","message":"Done","commit_id":"e059f0f4fa83577d8da8dbec4813c37282333b9a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":true,"context_lines":[{"line_number":311,"context_line":"            (h.lower(), v)"},{"line_number":312,"context_line":"            for h, v in file_item.conn.response.getheaders())"},{"line_number":313,"context_line":"        self.assertEqual(b\u0027\u0027, resp_body)"},{"line_number":314,"context_line":"        self.assertEqual(headers[\u0027content-length\u0027], \u00270\u0027)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"    def test_get_part_number_errors(self):"},{"line_number":317,"context_line":"        file_item \u003d self.env.container.file(\u0027manifest-abcde\u0027)"}],"source_content_type":"text/x-python","patch_set":79,"id":"97f93e52_dd7b63d6","line":314,"updated":"2023-12-15 16:04:06.000000000","message":"this test seems to check that a delete with a part-number will ignore the part-number and succeed? there\u0027s nothing special about the object, I\u0027m not sure what we gain here other than verifying that part-number is ignore. Might be more interesting to verify that against an SLO","commit_id":"7c2f3bf4d15fc2939f8c42d59e47ffe8d343debc"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":311,"context_line":"            (h.lower(), v)"},{"line_number":312,"context_line":"            for h, v in file_item.conn.response.getheaders())"},{"line_number":313,"context_line":"        self.assertEqual(b\u0027\u0027, resp_body)"},{"line_number":314,"context_line":"        self.assertEqual(headers[\u0027content-length\u0027], \u00270\u0027)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"    def test_get_part_number_errors(self):"},{"line_number":317,"context_line":"        file_item \u003d self.env.container.file(\u0027manifest-abcde\u0027)"}],"source_content_type":"text/x-python","patch_set":79,"id":"d73dae48_fe2a4be8","line":314,"in_reply_to":"97f93e52_dd7b63d6","updated":"2024-01-03 19:18:02.000000000","message":"Done","commit_id":"7c2f3bf4d15fc2939f8c42d59e47ffe8d343debc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":true,"context_lines":[{"line_number":349,"context_line":"                for h, v in file_item.conn.response.getheaders())"},{"line_number":350,"context_line":"            self.assertEqual(headers[\u0027content-length\u0027],"},{"line_number":351,"context_line":"                             str(seg_info[\u0027size_bytes\u0027]))"},{"line_number":352,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], \u0027\"%s\"\u0027 % slo_etag)"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"    def test_head_part_number_simple_manifest(self):"},{"line_number":355,"context_line":"        file_item \u003d self.env.container.file(\u0027manifest-abcde\u0027)"}],"source_content_type":"text/x-python","patch_set":79,"id":"ea391afc_ccd888a6","line":352,"updated":"2023-12-15 16:04:06.000000000","message":"assert manifest-etag, content-range, x-parts-count","commit_id":"7c2f3bf4d15fc2939f8c42d59e47ffe8d343debc"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                for h, v in file_item.conn.response.getheaders())"},{"line_number":350,"context_line":"            self.assertEqual(headers[\u0027content-length\u0027],"},{"line_number":351,"context_line":"                             str(seg_info[\u0027size_bytes\u0027]))"},{"line_number":352,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], \u0027\"%s\"\u0027 % slo_etag)"},{"line_number":353,"context_line":""},{"line_number":354,"context_line":"    def test_head_part_number_simple_manifest(self):"},{"line_number":355,"context_line":"        file_item \u003d self.env.container.file(\u0027manifest-abcde\u0027)"}],"source_content_type":"text/x-python","patch_set":79,"id":"9c419870_d7a91f0e","line":352,"in_reply_to":"ea391afc_ccd888a6","updated":"2024-01-03 19:18:02.000000000","message":"Done","commit_id":"7c2f3bf4d15fc2939f8c42d59e47ffe8d343debc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":true,"context_lines":[{"line_number":364,"context_line":"                (h.lower(), v)"},{"line_number":365,"context_line":"                for h, v in file_item.conn.response.getheaders())"},{"line_number":366,"context_line":"            self.assertEqual(headers[\u0027content-length\u0027],"},{"line_number":367,"context_line":"                             str(part_info[\u0027content_length\u0027]))"},{"line_number":368,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], part_info[\u0027etag\u0027])"},{"line_number":369,"context_line":"            self.assertEqual(headers[\u0027x-manifest-etag\u0027],"},{"line_number":370,"context_line":"                             part_info[\u0027x_manifest_etag\u0027])"}],"source_content_type":"text/x-python","patch_set":79,"id":"9de64af1_e701e09b","line":367,"range":{"start_line":367,"start_character":33,"end_line":367,"end_character":42},"updated":"2023-12-15 16:04:06.000000000","message":"part_info is just the headers encapsulated in the File so this isn\u0027t really checking against an independent expected value","commit_id":"7c2f3bf4d15fc2939f8c42d59e47ffe8d343debc"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":364,"context_line":"                (h.lower(), v)"},{"line_number":365,"context_line":"                for h, v in file_item.conn.response.getheaders())"},{"line_number":366,"context_line":"            self.assertEqual(headers[\u0027content-length\u0027],"},{"line_number":367,"context_line":"                             str(part_info[\u0027content_length\u0027]))"},{"line_number":368,"context_line":"            self.assertEqual(headers[\u0027etag\u0027], part_info[\u0027etag\u0027])"},{"line_number":369,"context_line":"            self.assertEqual(headers[\u0027x-manifest-etag\u0027],"},{"line_number":370,"context_line":"                             part_info[\u0027x_manifest_etag\u0027])"}],"source_content_type":"text/x-python","patch_set":79,"id":"9d57d26a_17bb6f7e","line":367,"range":{"start_line":367,"start_character":33,"end_line":367,"end_character":42},"in_reply_to":"9de64af1_e701e09b","updated":"2024-01-03 19:18:02.000000000","message":"Done","commit_id":"7c2f3bf4d15fc2939f8c42d59e47ffe8d343debc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"17824a0f7c7398fe5197875460fb95f3d0032353","unresolved":true,"context_lines":[{"line_number":446,"context_line":"                self.assertEqual(headers[\u0027x-manifest-etag\u0027], manifest_etag)"},{"line_number":447,"context_line":"            end \u003d start + seg_info[\u0027size_bytes\u0027] - 1"},{"line_number":448,"context_line":"            self.assertEqual(headers[\u0027content-range\u0027],"},{"line_number":449,"context_line":"                             \u0027bytes %d-%d/%d\u0027 % (start, end, total_size), i)"},{"line_number":450,"context_line":"            start \u003d end + 1"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def test_slo_container_listing(self):"}],"source_content_type":"text/x-python","patch_set":85,"id":"b54a432b_2f742166","line":449,"updated":"2024-01-11 14:18:12.000000000","message":"assert x-parts-count","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"98ad5921046205f4f2223d266ac6d90f44496cc1","unresolved":false,"context_lines":[{"line_number":446,"context_line":"                self.assertEqual(headers[\u0027x-manifest-etag\u0027], manifest_etag)"},{"line_number":447,"context_line":"            end \u003d start + seg_info[\u0027size_bytes\u0027] - 1"},{"line_number":448,"context_line":"            self.assertEqual(headers[\u0027content-range\u0027],"},{"line_number":449,"context_line":"                             \u0027bytes %d-%d/%d\u0027 % (start, end, total_size), i)"},{"line_number":450,"context_line":"            start \u003d end + 1"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    def test_slo_container_listing(self):"}],"source_content_type":"text/x-python","patch_set":85,"id":"150602e1_47989a9f","line":449,"in_reply_to":"b54a432b_2f742166","updated":"2024-01-11 14:18:51.000000000","message":"Done","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"}],"test/functional/tests.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b331a5bba081897d49da6dd9eaf5aad6b202b55b","unresolved":true,"context_lines":[{"line_number":56,"context_line":"    @classmethod"},{"line_number":57,"context_line":"    def encode_if_py2(cls, value):"},{"line_number":58,"context_line":"        if six.PY2 and isinstance(value, six.text_type):"},{"line_number":59,"context_line":"            return value.encode(\u0027utf8\u0027)"},{"line_number":60,"context_line":"        return value"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":90,"id":"ddfce497_015bd55a","line":59,"updated":"2024-03-12 05:53:45.000000000","message":"I do wonder if we could just use:\n\n  six.ensure_binary(value)\n\nBut meh, soon I hope we can get rid of all this py2 stuff 😊","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4398bb3f99f320617f028697b9e2bb6317a90fab","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    @classmethod"},{"line_number":57,"context_line":"    def encode_if_py2(cls, value):"},{"line_number":58,"context_line":"        if six.PY2 and isinstance(value, six.text_type):"},{"line_number":59,"context_line":"            return value.encode(\u0027utf8\u0027)"},{"line_number":60,"context_line":"        return value"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":90,"id":"de7b06f0_1f2ecff4","line":59,"in_reply_to":"ddfce497_015bd55a","updated":"2024-03-12 13:47:44.000000000","message":"Acknowledged","commit_id":"66d2c5c45bb88ca53bde49c234a5df3ac6cf8538"}],"test/unit/common/middleware/test_slo.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4ab8908e1454a14496bbd3e06db11bb9100b923b","unresolved":true,"context_lines":[{"line_number":3395,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":3396,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":3397,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":3398,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":3399,"context_line":""},{"line_number":3400,"context_line":"    def test_get_subrange_manifest(self):"},{"line_number":3401,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":9,"id":"c424ff68_89660d11","line":3398,"updated":"2023-09-25 22:39:00.000000000","message":"I think this should all move into the TestPartNumber TestCase","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":false,"context_lines":[{"line_number":3395,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":3396,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":3397,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":3398,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":3399,"context_line":""},{"line_number":3400,"context_line":"    def test_get_subrange_manifest(self):"},{"line_number":3401,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":9,"id":"7b565a2a_863c1c8c","line":3398,"in_reply_to":"c424ff68_89660d11","updated":"2023-09-29 15:04:53.000000000","message":"Done","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4ab8908e1454a14496bbd3e06db11bb9100b923b","unresolved":true,"context_lines":[{"line_number":4875,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":4876,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":4877,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":4878,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":4879,"context_line":""},{"line_number":4880,"context_line":"    def test_get_part_number(self):"},{"line_number":4881,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":9,"id":"9bc70b2d_b70b5306","line":4878,"updated":"2023-09-25 22:39:00.000000000","message":"probably should assert the expected_calls include a HEAD and a GET","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":false,"context_lines":[{"line_number":4875,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":4876,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":4877,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":4878,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":4879,"context_line":""},{"line_number":4880,"context_line":"    def test_get_part_number(self):"},{"line_number":4881,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":9,"id":"f569e627_8ae1440c","line":4878,"in_reply_to":"9bc70b2d_b70b5306","updated":"2023-09-29 15:04:53.000000000","message":"Done","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4ab8908e1454a14496bbd3e06db11bb9100b923b","unresolved":true,"context_lines":[{"line_number":4965,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4966,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4967,"context_line":"        # XXX manifest json ETag?"},{"line_number":4968,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], self.manifest_abcd_ranges_json_etag)"},{"line_number":4969,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":4970,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":4971,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"02f73e76_3d817b8f","line":4968,"updated":"2023-09-25 22:39:00.000000000","message":"I think invalid range repsonses send back the slo_etag - I would guess s3api wants this etag to match the mpu-etag as well.","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4a5ed7b9eb5e25b3aefb4cf80a5d0cfba2f04b94","unresolved":true,"context_lines":[{"line_number":4965,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4966,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4967,"context_line":"        # XXX manifest json ETag?"},{"line_number":4968,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], self.manifest_abcd_ranges_json_etag)"},{"line_number":4969,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":4970,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":4971,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ba5227ce_fb368069","line":4968,"in_reply_to":"02f73e76_3d817b8f","updated":"2023-09-25 22:44:56.000000000","message":"TODO","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":false,"context_lines":[{"line_number":4965,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4966,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4967,"context_line":"        # XXX manifest json ETag?"},{"line_number":4968,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], self.manifest_abcd_ranges_json_etag)"},{"line_number":4969,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":4970,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":4971,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"9ef4d02a_53ff3a08","line":4968,"in_reply_to":"ba5227ce_fb368069","updated":"2023-09-29 15:04:53.000000000","message":"Done","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4ab8908e1454a14496bbd3e06db11bb9100b923b","unresolved":true,"context_lines":[{"line_number":4984,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":4985,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":4986,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":4987,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":4988,"context_line":""},{"line_number":4989,"context_line":""},{"line_number":4990,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"}],"source_content_type":"text/x-python","patch_set":9,"id":"1398f7b8_3fbc71cf","line":4987,"updated":"2023-09-25 22:39:00.000000000","message":"I much prefer to have smaller behavior oriented tests than one test that turns the crank multiple times and asserts all the things","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"374a8ea9fa0b298bc997c796d17fd5d681716041","unresolved":false,"context_lines":[{"line_number":4984,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":4985,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":4986,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":4987,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":4988,"context_line":""},{"line_number":4989,"context_line":""},{"line_number":4990,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"}],"source_content_type":"text/x-python","patch_set":9,"id":"73f29686_f173948b","line":4987,"in_reply_to":"1294bc75_87d2ca67","updated":"2023-09-29 15:04:53.000000000","message":"Done","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4a5ed7b9eb5e25b3aefb4cf80a5d0cfba2f04b94","unresolved":true,"context_lines":[{"line_number":4984,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":4985,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":4986,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":4987,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":4988,"context_line":""},{"line_number":4989,"context_line":""},{"line_number":4990,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"}],"source_content_type":"text/x-python","patch_set":9,"id":"1294bc75_87d2ca67","line":4987,"in_reply_to":"1398f7b8_3fbc71cf","updated":"2023-09-25 22:44:56.000000000","message":"TODO","commit_id":"f82e90272c7b8968910fa2e6d61e9b5e71640a67"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58a9e48c3a604ef9524d582c62cedce383265912","unresolved":true,"context_lines":[{"line_number":4818,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":4819,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4820,"context_line":""},{"line_number":4821,"context_line":"        self.assertEqual(status, \u0027206 Partial Content\u0027)"},{"line_number":4822,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], \u0027\"%s\"\u0027 % self.manifest_bc_slo_etag)"},{"line_number":4823,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002710\u0027)"},{"line_number":4824,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-9/25\u0027)"}],"source_content_type":"text/x-python","patch_set":12,"id":"c4914ece_02280602","line":4821,"updated":"2023-09-28 00:28:39.000000000","message":"We want the status responses to be 206 and not 200 as illustrated in the exaple here:\n\n```\n2023-09-27 17:28:02,989 - MainThread - urllib3.connectionpool - DEBUG - https://ash-test-mpu.s3.us-east-1.amazonaws.com:443 \"GET /test.mp4?partNumber\u003d2 HTTP/1.1\" 206 8388608\n2023-09-27 17:28:02,990 - MainThread - botocore.parsers - DEBUG - Response headers: {\u0027x-amz-id-2\u0027: \u0027kbZAXZus7Xtva8oESYw7CeRLzyestGq12LC901whBMvxuV4eRmbNu4200EXavHEBX/i0p1tppRo\u003d\u0027, \u0027x-amz-request-id\u0027: \u0027JT2B449K6WSHXTET\u0027, \u0027Date\u0027: \u0027Thu, 28 Sep 2023 00:28:03 GMT\u0027, \u0027Last-Modified\u0027: \u0027Wed, 28 Jun 2023 23:23:21 GMT\u0027, \u0027ETag\u0027: \u0027\"b6b71c18174097757f34243aae46b047-16\"\u0027, \u0027x-amz-mp-parts-count\u0027: \u002716\u0027, \u0027x-amz-server-side-encryption\u0027: \u0027AES256\u0027, \u0027Accept-Ranges\u0027: \u0027bytes\u0027, \u0027Content-Range\u0027: \u0027bytes 8388608-16777215/126501763\u0027, \u0027Content-Type\u0027: \u0027video/mp4\u0027, \u0027Server\u0027: \u0027AmazonS3\u0027, \u0027Content-Length\u0027: \u00278388608\u0027}\n```","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":4818,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":4819,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4820,"context_line":""},{"line_number":4821,"context_line":"        self.assertEqual(status, \u0027206 Partial Content\u0027)"},{"line_number":4822,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], \u0027\"%s\"\u0027 % self.manifest_bc_slo_etag)"},{"line_number":4823,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002710\u0027)"},{"line_number":4824,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-9/25\u0027)"}],"source_content_type":"text/x-python","patch_set":12,"id":"a6d88af9_74a0b570","line":4821,"in_reply_to":"c4914ece_02280602","updated":"2023-10-04 00:13:21.000000000","message":"Done","commit_id":"1afed97b3fd032a190ceeadf176df45842b8167a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e9fd8e3c1a276dcef2802484b5d3d8849ada1d13","unresolved":true,"context_lines":[{"line_number":4903,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4904,"context_line":""},{"line_number":4905,"context_line":"        self.assertEqual(status, \u0027416 Requested Range Not Satisfiable\u0027)"},{"line_number":4906,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":4907,"context_line":""},{"line_number":4908,"context_line":"    def test_head_part_number_zero_invalid(self):"},{"line_number":4909,"context_line":"        # you can HEAD part-number\u003d0 either"}],"source_content_type":"text/x-python","patch_set":21,"id":"1c4bea21_9faaf94a","line":4906,"updated":"2023-10-03 21:48:57.000000000","message":"what are content-length, etag, x-parts-count and x-static-large object headers in the error case?  not present?  empty?  invalid?  correct?  undefined?","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"c3396e3340b36b8c7c80196b8cfb4247df5e0dc0","unresolved":false,"context_lines":[{"line_number":4903,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4904,"context_line":""},{"line_number":4905,"context_line":"        self.assertEqual(status, \u0027416 Requested Range Not Satisfiable\u0027)"},{"line_number":4906,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":4907,"context_line":""},{"line_number":4908,"context_line":"    def test_head_part_number_zero_invalid(self):"},{"line_number":4909,"context_line":"        # you can HEAD part-number\u003d0 either"}],"source_content_type":"text/x-python","patch_set":21,"id":"89299989_8f690b00","line":4906,"in_reply_to":"14194ad1_a4b84d5c","updated":"2023-10-04 00:31:27.000000000","message":"Done","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":true,"context_lines":[{"line_number":4903,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4904,"context_line":""},{"line_number":4905,"context_line":"        self.assertEqual(status, \u0027416 Requested Range Not Satisfiable\u0027)"},{"line_number":4906,"context_line":"        self.assertEqual(body, b\u0027Invalid part-number query param\u0027)"},{"line_number":4907,"context_line":""},{"line_number":4908,"context_line":"    def test_head_part_number_zero_invalid(self):"},{"line_number":4909,"context_line":"        # you can HEAD part-number\u003d0 either"}],"source_content_type":"text/x-python","patch_set":21,"id":"14194ad1_a4b84d5c","line":4906,"in_reply_to":"1c4bea21_9faaf94a","updated":"2023-10-04 00:13:21.000000000","message":"Apparently we don\u0027t need any of those response headers if the request is invalid, all we need is the following:\n```\n{\u0027x-amz-request-id\u0027: \u00273SCMF7VX6BNXV6Z3\u0027, \u0027x-amz-id-2\u0027: \u002778aaJ2D2xP/AlAgbaQ5mwTI1wIPbuv8uGrdApt4OZswW1urJ3qK3YVGFhxKRtaBQBI5gCOgWDrM\u003d\u0027, \u0027Content-Type\u0027: \u0027application/xml\u0027, \u0027Date\u0027: \u0027Tue, 03 Oct 2023 23:29:39 GMT\u0027, \u0027Server\u0027: \u0027AmazonS3\u0027, \u0027Connection\u0027: \u0027close\u0027}\n```","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e9fd8e3c1a276dcef2802484b5d3d8849ada1d13","unresolved":true,"context_lines":[{"line_number":4981,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4982,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4983,"context_line":"        self.assertEqual(body, b\u0027Range requests are not supported with \u0027"},{"line_number":4984,"context_line":"                               b\u0027part-number queries\u0027)"},{"line_number":4985,"context_line":""},{"line_number":4986,"context_line":"    def test_head_part_number_subrange(self):"},{"line_number":4987,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":21,"id":"0fcc7579_b94b4aa4","line":4984,"updated":"2023-10-03 21:48:57.000000000","message":"please add asserts on the missing headers for the error condtions\n\nif the header is not in the respones (expected) then assertNotIn","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"58ade137feb93d4d1dbefa70ee1f89863f0b194b","unresolved":false,"context_lines":[{"line_number":4981,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4982,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4983,"context_line":"        self.assertEqual(body, b\u0027Range requests are not supported with \u0027"},{"line_number":4984,"context_line":"                               b\u0027part-number queries\u0027)"},{"line_number":4985,"context_line":""},{"line_number":4986,"context_line":"    def test_head_part_number_subrange(self):"},{"line_number":4987,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":21,"id":"a28ac16a_58ae81a8","line":4984,"in_reply_to":"0fcc7579_b94b4aa4","updated":"2023-10-04 00:13:21.000000000","message":"Ack","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"4ea1b4660bd9a310c63dfca3b40b3ccac07a8825","unresolved":false,"context_lines":[{"line_number":4981,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4982,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4983,"context_line":"        self.assertEqual(body, b\u0027Range requests are not supported with \u0027"},{"line_number":4984,"context_line":"                               b\u0027part-number queries\u0027)"},{"line_number":4985,"context_line":""},{"line_number":4986,"context_line":"    def test_head_part_number_subrange(self):"},{"line_number":4987,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":21,"id":"5733d541_08158590","line":4984,"in_reply_to":"a28ac16a_58ae81a8","updated":"2023-10-04 00:28:37.000000000","message":"It does however send out Content-Length in response which i fear is the default behavior swob has where it return the size of the error response body even when an error is raised","commit_id":"c04633ab612b0bfe25f905fb7e5ad8bc5a525086"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":4837,"context_line":"        self._setup_manifest_abcdefghijkl()"},{"line_number":4838,"context_line":"        self._setup_manifest_bc_ranges()"},{"line_number":4839,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":4840,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":4841,"context_line":""},{"line_number":4842,"context_line":"    def test_head_part_number(self):"},{"line_number":4843,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":25,"id":"43846a85_6405d325","line":4840,"updated":"2023-10-10 17:22:15.000000000","message":"I think you should some more happy path tests (200/206) on these other manifest objects.  I guess there\u0027s not a _setup_manifest with raw bytes segments yet, but you can at least validate GET part-number when the segment is a range-segment or sub-slo-segment","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"9b2f559d94af0595b12b92be101d16f3c9b1685a","unresolved":false,"context_lines":[{"line_number":4837,"context_line":"        self._setup_manifest_abcdefghijkl()"},{"line_number":4838,"context_line":"        self._setup_manifest_bc_ranges()"},{"line_number":4839,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":4840,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":4841,"context_line":""},{"line_number":4842,"context_line":"    def test_head_part_number(self):"},{"line_number":4843,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":25,"id":"b7ddb213_9b5bbe9c","line":4840,"in_reply_to":"43846a85_6405d325","updated":"2023-10-14 16:41:11.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":4867,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4868,"context_line":"        expected_calls \u003d ["},{"line_number":4869,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d1\u0027),"},{"line_number":4870,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027)"},{"line_number":4871,"context_line":"        ]"},{"line_number":4872,"context_line":""},{"line_number":4873,"context_line":"        self.assertEqual(status, \u0027206 Partial Content\u0027)"}],"source_content_type":"text/x-python","patch_set":25,"id":"017332bd_7c932ef6","line":4870,"updated":"2023-10-10 17:22:15.000000000","message":"this nice!","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"236fb38657f6636c91fce0bed37ca64a414fa509","unresolved":false,"context_lines":[{"line_number":4867,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":4868,"context_line":"        expected_calls \u003d ["},{"line_number":4869,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d1\u0027),"},{"line_number":4870,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027)"},{"line_number":4871,"context_line":"        ]"},{"line_number":4872,"context_line":""},{"line_number":4873,"context_line":"        self.assertEqual(status, \u0027206 Partial Content\u0027)"}],"source_content_type":"text/x-python","patch_set":25,"id":"f827c7ae_eb15f81b","line":4870,"in_reply_to":"017332bd_7c932ef6","updated":"2023-10-10 23:06:56.000000000","message":"Ack","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":4908,"context_line":"        self.assertNotIn(\u0027X-Static-Large-Object\u0027, headers)"},{"line_number":4909,"context_line":"        self.assertNotIn(\u0027X-Parts-Count\u0027, headers)"},{"line_number":4910,"context_line":"        self.assertEqual(body, b\u0027Part number must be an integer between 1 and \u0027"},{"line_number":4911,"context_line":"                               b\u00271000, inclusive\u0027)"},{"line_number":4912,"context_line":""},{"line_number":4913,"context_line":"    def test_head_part_number_zero_invalid(self):"},{"line_number":4914,"context_line":"        # you can HEAD part-number\u003d0 either"}],"source_content_type":"text/x-python","patch_set":25,"id":"134a2c47_c84054f0","line":4911,"updated":"2023-10-10 17:22:15.000000000","message":"nice, can you `assert app.calls \u003d\u003d []` when it makes sense?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba552ce0b054f0566f85d26223fc0d786ae186b8","unresolved":false,"context_lines":[{"line_number":4908,"context_line":"        self.assertNotIn(\u0027X-Static-Large-Object\u0027, headers)"},{"line_number":4909,"context_line":"        self.assertNotIn(\u0027X-Parts-Count\u0027, headers)"},{"line_number":4910,"context_line":"        self.assertEqual(body, b\u0027Part number must be an integer between 1 and \u0027"},{"line_number":4911,"context_line":"                               b\u00271000, inclusive\u0027)"},{"line_number":4912,"context_line":""},{"line_number":4913,"context_line":"    def test_head_part_number_zero_invalid(self):"},{"line_number":4914,"context_line":"        # you can HEAD part-number\u003d0 either"}],"source_content_type":"text/x-python","patch_set":25,"id":"cee2e310_d99d9dec","line":4911,"in_reply_to":"134a2c47_c84054f0","updated":"2023-10-11 00:15:47.000000000","message":"Done","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":4987,"context_line":"            params\u003d{\u0027part-number\u0027: 6})"},{"line_number":4988,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":4989,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4990,"context_line":"        self.assertEqual(body, b\u0027\u0027)"},{"line_number":4991,"context_line":""},{"line_number":4992,"context_line":"    def test_range_with_part_number_is_error(self):"},{"line_number":4993,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":25,"id":"31c890dd_d023bbe4","line":4990,"updated":"2023-10-10 17:22:15.000000000","message":"here I think we had to HEAD and GET the manifest right?","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"ba552ce0b054f0566f85d26223fc0d786ae186b8","unresolved":false,"context_lines":[{"line_number":4987,"context_line":"            params\u003d{\u0027part-number\u0027: 6})"},{"line_number":4988,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":4989,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":4990,"context_line":"        self.assertEqual(body, b\u0027\u0027)"},{"line_number":4991,"context_line":""},{"line_number":4992,"context_line":"    def test_range_with_part_number_is_error(self):"},{"line_number":4993,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":25,"id":"a943a250_aae2935c","line":4990,"in_reply_to":"31c890dd_d023bbe4","updated":"2023-10-11 00:15:47.000000000","message":"Yes, that is correct.","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2459aab99af2011db221e734f0237da5aa63b78","unresolved":true,"context_lines":[{"line_number":5023,"context_line":""},{"line_number":5024,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"},{"line_number":5025,"context_line":""},{"line_number":5026,"context_line":"    modern_manifest_headers \u003d False"},{"line_number":5027,"context_line":""},{"line_number":5028,"context_line":""},{"line_number":5029,"context_line":"class TestSloBulkDeleter(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":25,"id":"0970c9ef_0887a579","line":5026,"updated":"2023-10-10 17:22:15.000000000","message":"nice!","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"236fb38657f6636c91fce0bed37ca64a414fa509","unresolved":false,"context_lines":[{"line_number":5023,"context_line":""},{"line_number":5024,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"},{"line_number":5025,"context_line":""},{"line_number":5026,"context_line":"    modern_manifest_headers \u003d False"},{"line_number":5027,"context_line":""},{"line_number":5028,"context_line":""},{"line_number":5029,"context_line":"class TestSloBulkDeleter(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":25,"id":"f05e819a_0826c47f","line":5026,"in_reply_to":"0970c9ef_0887a579","updated":"2023-10-10 23:06:56.000000000","message":"Ack","commit_id":"47b6d426bced6f8dc25126fb4b65e0e338bc0135"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":1952,"context_line":"            # metadata; sitll I wouldn\u0027t assert on this value in these tests or"},{"line_number":1953,"context_line":"            # you may not be testing what you think you are - N.B. some tests"},{"line_number":1954,"context_line":"            # will override this value with the \"extra_headers\" param."},{"line_number":1955,"context_line":"            \u0027Content-Type\u0027: \u0027application/octet-stream\u0027,"},{"line_number":1956,"context_line":"        }"},{"line_number":1957,"context_line":"        if extra_headers is not None:"},{"line_number":1958,"context_line":"            manifest_headers.update(extra_headers)"}],"source_content_type":"text/x-python","patch_set":69,"id":"eec23a73_4ca28518","side":"PARENT","line":1955,"updated":"2023-11-28 22:02:17.000000000","message":"I think applicatoin/octet-stream is a better default content-type for an SLO object than application/json - SOME of the manifests are setup with application/json as the content-type for the large object but IMHO that\u0027s confusing since manifests are stored on disk as json but with the content-type of the large object.\n\nAFAIK we only force content-type application/json when we respond to ?multipart-manifest\u003dget\u0026format\u003draw and we\u0027re making up the json","commit_id":"190b8576ef89094a42b0852a91adfe06f7805daa"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"f7c346a3936c08c6e9fb9c55ac8b3fc02f36dc2f","unresolved":false,"context_lines":[{"line_number":1952,"context_line":"            # metadata; sitll I wouldn\u0027t assert on this value in these tests or"},{"line_number":1953,"context_line":"            # you may not be testing what you think you are - N.B. some tests"},{"line_number":1954,"context_line":"            # will override this value with the \"extra_headers\" param."},{"line_number":1955,"context_line":"            \u0027Content-Type\u0027: \u0027application/octet-stream\u0027,"},{"line_number":1956,"context_line":"        }"},{"line_number":1957,"context_line":"        if extra_headers is not None:"},{"line_number":1958,"context_line":"            manifest_headers.update(extra_headers)"}],"source_content_type":"text/x-python","patch_set":69,"id":"2d7d5970_02e82e44","side":"PARENT","line":1955,"in_reply_to":"eec23a73_4ca28518","updated":"2024-01-03 19:18:02.000000000","message":"Old comment which has since then been addressed.","commit_id":"190b8576ef89094a42b0852a91adfe06f7805daa"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5705,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027], self.manifest_bc_json_md5)"},{"line_number":5706,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":5707,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5708,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":5709,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":5710,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5711,"context_line":""}],"source_content_type":"text/x-python","patch_set":69,"id":"c038fde1_f7bde05a","line":5708,"updated":"2023-11-28 22:02:17.000000000","message":"since this manifest isn\u0027t created with a specific content-type during setup I don\u0027t think it\u0027s that helpful to assert the content-type in the response.","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"12e6bc18e0e8c904126f5e194b9ba000e9061c7f","unresolved":false,"context_lines":[{"line_number":5705,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027], self.manifest_bc_json_md5)"},{"line_number":5706,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":5707,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5708,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":5709,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":5710,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5711,"context_line":""}],"source_content_type":"text/x-python","patch_set":69,"id":"48653d62_963259d4","line":5708,"in_reply_to":"c038fde1_f7bde05a","updated":"2023-12-04 19:17:16.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5798,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5799,"context_line":"        expected_calls \u003d ["},{"line_number":5800,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d3\u0027),"},{"line_number":5801,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/d_20?multipart-manifest\u003dget\u0027),"},{"line_number":5802,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d2\u0027),"},{"line_number":5803,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d2\u0027),"},{"line_number":5804,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027),"}],"source_content_type":"text/x-python","patch_set":69,"id":"f8fe19e8_9435357b","line":5801,"updated":"2023-11-28 22:02:17.000000000","message":"It\u0027s annoying to see the epected calls from the previous request duplicated here - consider either splitting up the test so it only does one thing, or re-writing:\n\n    expected_calls +\u003d [\u003conly new requests\u003e]","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5798,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5799,"context_line":"        expected_calls \u003d ["},{"line_number":5800,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d3\u0027),"},{"line_number":5801,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/d_20?multipart-manifest\u003dget\u0027),"},{"line_number":5802,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d2\u0027),"},{"line_number":5803,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d2\u0027),"},{"line_number":5804,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027),"}],"source_content_type":"text/x-python","patch_set":69,"id":"7d1158c3_36923646","line":5801,"in_reply_to":"f8fe19e8_9435357b","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5800,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d3\u0027),"},{"line_number":5801,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/d_20?multipart-manifest\u003dget\u0027),"},{"line_number":5802,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d2\u0027),"},{"line_number":5803,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d2\u0027),"},{"line_number":5804,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027),"},{"line_number":5805,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/c_15?multipart-manifest\u003dget\u0027)"},{"line_number":5806,"context_line":"        ]"}],"source_content_type":"text/x-python","patch_set":69,"id":"9bc6cb9a_f64f82a8","line":5803,"updated":"2023-11-28 22:02:17.000000000","message":"seeing the part-number qs on the sub-slo request is unexpected and possibly confusing; I think we should sanitize the qs on the sub-slo request","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"12e6bc18e0e8c904126f5e194b9ba000e9061c7f","unresolved":false,"context_lines":[{"line_number":5800,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d3\u0027),"},{"line_number":5801,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/d_20?multipart-manifest\u003dget\u0027),"},{"line_number":5802,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcd?part-number\u003d2\u0027),"},{"line_number":5803,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d2\u0027),"},{"line_number":5804,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/b_10?multipart-manifest\u003dget\u0027),"},{"line_number":5805,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/c_15?multipart-manifest\u003dget\u0027)"},{"line_number":5806,"context_line":"        ]"}],"source_content_type":"text/x-python","patch_set":69,"id":"5d207df9_3a191263","line":5803,"in_reply_to":"9bc6cb9a_f64f82a8","updated":"2023-12-04 19:17:16.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5862,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-98/200\u0027)"},{"line_number":5863,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":5864,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5865,"context_line":"        # since the manifest has raw bytes, content-type downloaded is plain"},{"line_number":5866,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":5867,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5868,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"}],"source_content_type":"text/x-python","patch_set":69,"id":"3840f78a_e0224fcd","line":5865,"updated":"2023-11-28 22:02:17.000000000","message":"this comment is misleading; this (rather strange) \"raw\" manifest is setup explicitly with a text/plain content-type (probably to ensure we force application/json content-type when we return ?format\u003draw responses)","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"157b7c9eba7d0a63af19a5a14224687e2485dcf1","unresolved":false,"context_lines":[{"line_number":5862,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-98/200\u0027)"},{"line_number":5863,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":5864,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5865,"context_line":"        # since the manifest has raw bytes, content-type downloaded is plain"},{"line_number":5866,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":5867,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5868,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"}],"source_content_type":"text/x-python","patch_set":69,"id":"eecb359e_871074e5","line":5865,"in_reply_to":"3840f78a_e0224fcd","updated":"2023-12-01 19:57:20.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5867,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5868,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5869,"context_line":""},{"line_number":5870,"context_line":"    def test_part_number_sub_ranges_manifest(self):"},{"line_number":5871,"context_line":"        req \u003d Request.blank("},{"line_number":5872,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd-subranges?part-number\u003d3\u0027,"},{"line_number":5873,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":69,"id":"677e1882_ceb2ed89","line":5870,"updated":"2023-11-28 22:02:17.000000000","message":"this is a fairly complex example!  manifest-abcd-subranges is a 5 sub_slo+range-segment manifest; part-number 3 is a range right into the middle of the abcd-manifest who\u0027s bc segment is itself a sub_slo.  KUDOS!","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5867,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5868,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5869,"context_line":""},{"line_number":5870,"context_line":"    def test_part_number_sub_ranges_manifest(self):"},{"line_number":5871,"context_line":"        req \u003d Request.blank("},{"line_number":5872,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd-subranges?part-number\u003d3\u0027,"},{"line_number":5873,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":69,"id":"7b37a763_3e7b5df3","line":5870,"in_reply_to":"677e1882_ceb2ed89","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5867,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5868,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5869,"context_line":""},{"line_number":5870,"context_line":"    def test_part_number_sub_ranges_manifest(self):"},{"line_number":5871,"context_line":"        req \u003d Request.blank("},{"line_number":5872,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd-subranges?part-number\u003d3\u0027,"},{"line_number":5873,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"}],"source_content_type":"text/x-python","patch_set":69,"id":"cac8265c_a38d56bf","line":5870,"in_reply_to":"677e1882_ceb2ed89","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5927,"context_line":"        req \u003d Request.blank("},{"line_number":5928,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d0\u0027)"},{"line_number":5929,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5930,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5931,"context_line":""},{"line_number":5932,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5933,"context_line":"        self.assertNotIn(\u0027Content-Range\u0027, headers)"}],"source_content_type":"text/x-python","patch_set":69,"id":"54cb8303_7ab2473f","line":5930,"updated":"2023-11-28 22:02:17.000000000","message":"somewhere along the way the call_slo helper started wrapping headers in a HeaderKeyDict before returning them; this isn\u0027t needed or helpful.","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5927,"context_line":"        req \u003d Request.blank("},{"line_number":5928,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d0\u0027)"},{"line_number":5929,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5930,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5931,"context_line":""},{"line_number":5932,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5933,"context_line":"        self.assertNotIn(\u0027Content-Range\u0027, headers)"}],"source_content_type":"text/x-python","patch_set":69,"id":"19a71d7b_eaa330d9","line":5930,"in_reply_to":"54cb8303_7ab2473f","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5927,"context_line":"        req \u003d Request.blank("},{"line_number":5928,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d0\u0027)"},{"line_number":5929,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5930,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5931,"context_line":""},{"line_number":5932,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5933,"context_line":"        self.assertNotIn(\u0027Content-Range\u0027, headers)"}],"source_content_type":"text/x-python","patch_set":69,"id":"de554867_dfe07986","line":5930,"in_reply_to":"54cb8303_7ab2473f","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5945,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5946,"context_line":""},{"line_number":5947,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5948,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # HEAD repsonse, makes sense"},{"line_number":5949,"context_line":""},{"line_number":5950,"context_line":"    def test_part_number_zero_invalid_on_subrange(self):"},{"line_number":5951,"context_line":"        # either manifest, doesn\u0027t matter, part-number\u003d0 is always invalid"}],"source_content_type":"text/x-python","patch_set":69,"id":"f17a22a9_c8ad1946","line":5948,"updated":"2023-11-28 22:02:17.000000000","message":"it would be nice to add:\n\n    self.assertEqual(self.app.calls, [])","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5945,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5946,"context_line":""},{"line_number":5947,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5948,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # HEAD repsonse, makes sense"},{"line_number":5949,"context_line":""},{"line_number":5950,"context_line":"    def test_part_number_zero_invalid_on_subrange(self):"},{"line_number":5951,"context_line":"        # either manifest, doesn\u0027t matter, part-number\u003d0 is always invalid"}],"source_content_type":"text/x-python","patch_set":69,"id":"b00d1318_68ac605b","line":5948,"in_reply_to":"f17a22a9_c8ad1946","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5945,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5946,"context_line":""},{"line_number":5947,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5948,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # HEAD repsonse, makes sense"},{"line_number":5949,"context_line":""},{"line_number":5950,"context_line":"    def test_part_number_zero_invalid_on_subrange(self):"},{"line_number":5951,"context_line":"        # either manifest, doesn\u0027t matter, part-number\u003d0 is always invalid"}],"source_content_type":"text/x-python","patch_set":69,"id":"e6b92b08_8ae4d5cb","line":5948,"in_reply_to":"f17a22a9_c8ad1946","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5980,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd-subranges\u0027, method\u003d\u0027HEAD\u0027,"},{"line_number":5981,"context_line":"            params\u003d{\u0027part-number\u0027: \u0027-1\u0027})"},{"line_number":5982,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5983,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5984,"context_line":"        self.assertEqual(body, b\u0027\u0027)"},{"line_number":5985,"context_line":""},{"line_number":5986,"context_line":"    def test_non_integer_part_number_invalid(self):"}],"source_content_type":"text/x-python","patch_set":69,"id":"3e367da6_68ad0c39","line":5983,"updated":"2023-11-28 22:02:17.000000000","message":"why not assert headers here too?","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5980,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcd-subranges\u0027, method\u003d\u0027HEAD\u0027,"},{"line_number":5981,"context_line":"            params\u003d{\u0027part-number\u0027: \u0027-1\u0027})"},{"line_number":5982,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5983,"context_line":"        self.assertEqual(status, \u0027400 Bad Request\u0027)"},{"line_number":5984,"context_line":"        self.assertEqual(body, b\u0027\u0027)"},{"line_number":5985,"context_line":""},{"line_number":5986,"context_line":"    def test_non_integer_part_number_invalid(self):"}],"source_content_type":"text/x-python","patch_set":69,"id":"a1bec700_5181efca","line":5983,"in_reply_to":"3e367da6_68ad0c39","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":6010,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], str(object_size))"},{"line_number":6011,"context_line":"        self.assertNotIn(\u0027Etag\u0027, headers)"},{"line_number":6012,"context_line":"        self.assertNotIn(\u0027X-Static-Large-Object\u0027, headers)"},{"line_number":6013,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":6014,"context_line":"        self.assertEqual(body, b\u0027The requested part number is not \u0027"},{"line_number":6015,"context_line":"                               b\u0027satisfiable\u0027)"},{"line_number":6016,"context_line":""}],"source_content_type":"text/x-python","patch_set":69,"id":"d023e9bf_86991861","line":6013,"updated":"2023-11-28 22:02:17.000000000","message":"it looks strange to me that we don\u0027t include `x-static-large-object: true` header since we have the x-parts-count header.","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":6010,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], str(object_size))"},{"line_number":6011,"context_line":"        self.assertNotIn(\u0027Etag\u0027, headers)"},{"line_number":6012,"context_line":"        self.assertNotIn(\u0027X-Static-Large-Object\u0027, headers)"},{"line_number":6013,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":6014,"context_line":"        self.assertEqual(body, b\u0027The requested part number is not \u0027"},{"line_number":6015,"context_line":"                               b\u0027satisfiable\u0027)"},{"line_number":6016,"context_line":""}],"source_content_type":"text/x-python","patch_set":69,"id":"ece60cf6_29aad1d0","line":6013,"in_reply_to":"d023e9bf_86991861","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9f87d716ce45ce5f1a75054b4b52493bbda952be"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":1974,"context_line":"        ]"},{"line_number":1975,"context_line":"        self._setup_manifest(\u0027bb-regular\u0027, _bb_manifest, extra_headers\u003d{"},{"line_number":1976,"context_line":"            \u0027X-Object-Meta-Nature\u0027: \u0027Regular\u0027,"},{"line_number":1977,"context_line":"        }, container\u003d\u0027gettest\u0027)"},{"line_number":1978,"context_line":""},{"line_number":1979,"context_line":"    def _setup_manifest_bc(self):"},{"line_number":1980,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":70,"id":"440f5294_8cf170f2","line":1977,"updated":"2023-11-28 22:02:17.000000000","message":"I\u0027m not sure about the name \"bb-regular\"\n\n1) there\u0027s only one \"b\"\n2) it\u0027s not so much \"regular\" as \"single-segment\"\n\nmaybe we should elevate \"_setup_big_manifest\" from TestOldSwiftWithRanges - it has just a single (large) segment.","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"12e6bc18e0e8c904126f5e194b9ba000e9061c7f","unresolved":false,"context_lines":[{"line_number":1974,"context_line":"        ]"},{"line_number":1975,"context_line":"        self._setup_manifest(\u0027bb-regular\u0027, _bb_manifest, extra_headers\u003d{"},{"line_number":1976,"context_line":"            \u0027X-Object-Meta-Nature\u0027: \u0027Regular\u0027,"},{"line_number":1977,"context_line":"        }, container\u003d\u0027gettest\u0027)"},{"line_number":1978,"context_line":""},{"line_number":1979,"context_line":"    def _setup_manifest_bc(self):"},{"line_number":1980,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":70,"id":"f218e3dc_c0f22336","line":1977,"in_reply_to":"440f5294_8cf170f2","updated":"2023-12-04 19:17:16.000000000","message":"Acknowledged","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5686,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":5687,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":5688,"context_line":"        self._setup_manifest_aabbccdd()"},{"line_number":5689,"context_line":"        self._setup_manifest_raw_ranges()"},{"line_number":5690,"context_line":""},{"line_number":5691,"context_line":"    def test_head_part_number(self):"},{"line_number":5692,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":70,"id":"fe3d8f60_aa410c3b","line":5689,"updated":"2023-11-28 22:02:17.000000000","message":"We should pull the _setup_manifest_raw_* helpers into TestSloGetRawManifest so we don\u0027t accidently try to re-use them; they\u0027re really weird.","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":false,"context_lines":[{"line_number":5686,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":5687,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":5688,"context_line":"        self._setup_manifest_aabbccdd()"},{"line_number":5689,"context_line":"        self._setup_manifest_raw_ranges()"},{"line_number":5690,"context_line":""},{"line_number":5691,"context_line":"    def test_head_part_number(self):"},{"line_number":5692,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":70,"id":"5a9f3642_677f2e99","line":5689,"in_reply_to":"128d5384_70554e17","updated":"2023-12-15 16:04:06.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1f76590b8a767228c16f6767f708f7e44408d817","unresolved":true,"context_lines":[{"line_number":5686,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":5687,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":5688,"context_line":"        self._setup_manifest_aabbccdd()"},{"line_number":5689,"context_line":"        self._setup_manifest_raw_ranges()"},{"line_number":5690,"context_line":""},{"line_number":5691,"context_line":"    def test_head_part_number(self):"},{"line_number":5692,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":70,"id":"cd55a584_1f0117d3","line":5689,"in_reply_to":"c20254ff_9e14033f","updated":"2023-12-12 20:05:52.000000000","message":"are they deliberately weird? I \"fixed\" the ranges in https://review.opendev.org/c/openstack/swift/+/903539 but I\u0027m concerned they should be deliberately wrong to validate they aren\u0027t checked.","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e821688bdf08343e628625dccb65753e86fbe7d6","unresolved":true,"context_lines":[{"line_number":5686,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":5687,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":5688,"context_line":"        self._setup_manifest_aabbccdd()"},{"line_number":5689,"context_line":"        self._setup_manifest_raw_ranges()"},{"line_number":5690,"context_line":""},{"line_number":5691,"context_line":"    def test_head_part_number(self):"},{"line_number":5692,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":70,"id":"128d5384_70554e17","line":5689,"in_reply_to":"cd55a584_1f0117d3","updated":"2023-12-14 14:49:40.000000000","message":"yes we want to test against multiple valid manifests with working parts - these weren\u0027t desinged to have their segments used:\n\n903636: test: couple raw manifests with their TestCase | https://review.opendev.org/c/openstack/swift/+/903636","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"12e6bc18e0e8c904126f5e194b9ba000e9061c7f","unresolved":true,"context_lines":[{"line_number":5686,"context_line":"        self._setup_manifest_abcd_ranges()"},{"line_number":5687,"context_line":"        self._setup_manifest_abcd_subranges()"},{"line_number":5688,"context_line":"        self._setup_manifest_aabbccdd()"},{"line_number":5689,"context_line":"        self._setup_manifest_raw_ranges()"},{"line_number":5690,"context_line":""},{"line_number":5691,"context_line":"    def test_head_part_number(self):"},{"line_number":5692,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":70,"id":"c20254ff_9e14033f","line":5689,"in_reply_to":"fe3d8f60_aa410c3b","updated":"2023-12-04 19:17:16.000000000","message":"Didn\u0027t we want part-num tests against multiple kinds of manifests, this was the intent behind using the helper here ?","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":5699,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d1\u0027)"},{"line_number":5700,"context_line":"        ]"},{"line_number":5701,"context_line":""},{"line_number":5702,"context_line":"        self.assertEqual(status, \u0027200 OK\u0027)"},{"line_number":5703,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], \u0027\"%s\"\u0027 % self.manifest_bc_slo_etag)"},{"line_number":5704,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002710\u0027)"},{"line_number":5705,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027], self.manifest_bc_json_md5)"}],"source_content_type":"text/x-python","patch_set":70,"id":"1c136d9e_325c7f48","line":5702,"updated":"2023-11-28 22:02:17.000000000","message":"I don\u0027t understand why we return 200 status code for HEAD - that\u0027s a different status than a client would recieve for GET\n\nAWS seems to return 206 for any part-number request (including HEADs)","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":5699,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d1\u0027)"},{"line_number":5700,"context_line":"        ]"},{"line_number":5701,"context_line":""},{"line_number":5702,"context_line":"        self.assertEqual(status, \u0027200 OK\u0027)"},{"line_number":5703,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], \u0027\"%s\"\u0027 % self.manifest_bc_slo_etag)"},{"line_number":5704,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002710\u0027)"},{"line_number":5705,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027], self.manifest_bc_json_md5)"}],"source_content_type":"text/x-python","patch_set":70,"id":"72915771_ac498dc0","line":5702,"in_reply_to":"1c136d9e_325c7f48","updated":"2023-11-29 16:51:27.000000000","message":"I checked and yes, AWS does return 206 for a HEAD with partNumber.\n\nWe\u0027re outside RFC with part numbers: 206 is specified in the context of Range requests, and Range headers MUST be ignored for HEADs (https://www.rfc-editor.org/rfc/rfc9110#name-range). So a HEAD with Range usually returns 200.\n\nBut the key distinction here vs a Range HEAD is that the part-number HEAD request modifies the Content-Length so that justifies a 206.\n\nNote: a single part 206 response MUST have a Content-Range header (https://www.rfc-editor.org/rfc/rfc9110#name-single-part) which we don\u0027t currently include with the HEAD response. The same text says it MUST have content which obviously conflicts with a HEAD response, but...AWS does return the Content-Range for a HEAD, so we should too so that our s3API can be compliant:\n\n```\nhttps://acoles-test.s3.amazonaws.com:443 \"HEAD /LICENSE?partNumber\u003d1 HTTP/1.1\" 206 0\n2023-11-29 12:31:49,703 - MainThread - botocore.parsers - DEBUG - Response headers: {\u0027x-amz-id-2\u0027: \u0027UiF+sApMliK0qsHn/zzap0U2cQuj4Cm4GaLM//0uPF95BA46qrenjpLKleeWjZwGaCk5KcI3hUrwfdYghahFRb7EtTGxcCsYsNq53L83WwA\u003d\u0027, \u0027x-amz-request-id\u0027: \u0027RQHPPSKPE10DCEM1\u0027, \u0027Date\u0027: \u0027Wed, 29 Nov 2023 12:31:50 GMT\u0027, \u0027Last-Modified\u0027: \u0027Wed, 29 Nov 2023 12:24:34 GMT\u0027, \u0027ETag\u0027: \u0027\"3b83ef96387f14655fc854ddc3c6bd57\"\u0027, \u0027x-amz-server-side-encryption\u0027: \u0027AES256\u0027, \u0027Accept-Ranges\u0027: \u0027bytes\u0027, \u0027Content-Range\u0027: \u0027bytes 0-11357/11358\u0027, \u0027Content-Type\u0027: \u0027binary/octet-stream\u0027, \u0027Server\u0027: \u0027AmazonS3\u0027, \u0027Content-Length\u0027: \u002711358\u0027}\n```","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"202febb35f54fb41ee9bef113c738928d862b10c","unresolved":false,"context_lines":[{"line_number":5699,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-bc?part-number\u003d1\u0027)"},{"line_number":5700,"context_line":"        ]"},{"line_number":5701,"context_line":""},{"line_number":5702,"context_line":"        self.assertEqual(status, \u0027200 OK\u0027)"},{"line_number":5703,"context_line":"        self.assertEqual(headers[\u0027Etag\u0027], \u0027\"%s\"\u0027 % self.manifest_bc_slo_etag)"},{"line_number":5704,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002710\u0027)"},{"line_number":5705,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027], self.manifest_bc_json_md5)"}],"source_content_type":"text/x-python","patch_set":70,"id":"536082a4_20dcd76e","line":5702,"in_reply_to":"72915771_ac498dc0","updated":"2023-11-30 20:40:00.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"04ae7a7c5f767b5a4d0f97fb79b6baf0315f5dd8","unresolved":true,"context_lines":[{"line_number":5820,"context_line":"    def test_get_part_number_large_manifest(self):"},{"line_number":5821,"context_line":"        req \u003d Request.blank("},{"line_number":5822,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcdefghijkl?part-number\u003d10\u0027)"},{"line_number":5823,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5824,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5825,"context_line":"        expected_calls \u003d ["},{"line_number":5826,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcdefghijkl?\u0027"}],"source_content_type":"text/x-python","patch_set":70,"id":"6a508a24_dff3368e","line":5823,"updated":"2023-11-29 16:51:27.000000000","message":"it would be interesting to deliberately set the max_manifest_segments here to less than the actual manifest segments to verify that it doesn\u0027t prevent the part being read:\n e.g.\n \n```\nself.slo.max_manifest_segments \u003d 8\n```","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"157b7c9eba7d0a63af19a5a14224687e2485dcf1","unresolved":false,"context_lines":[{"line_number":5820,"context_line":"    def test_get_part_number_large_manifest(self):"},{"line_number":5821,"context_line":"        req \u003d Request.blank("},{"line_number":5822,"context_line":"            \u0027/v1/AUTH_test/gettest/manifest-abcdefghijkl?part-number\u003d10\u0027)"},{"line_number":5823,"context_line":"        status, headers, body \u003d self.call_slo(req)"},{"line_number":5824,"context_line":"        headers \u003d HeaderKeyDict(headers)"},{"line_number":5825,"context_line":"        expected_calls \u003d ["},{"line_number":5826,"context_line":"            (\u0027GET\u0027, \u0027/v1/AUTH_test/gettest/manifest-abcdefghijkl?\u0027"}],"source_content_type":"text/x-python","patch_set":70,"id":"6f0990d7_62361f97","line":5823,"in_reply_to":"6a508a24_dff3368e","updated":"2023-12-01 19:57:20.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a8c0bf128105d7001fd16569993e87a5c2824d09","unresolved":true,"context_lines":[{"line_number":6071,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":6072,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":6073,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":6074,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":6075,"context_line":""},{"line_number":6076,"context_line":""},{"line_number":6077,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"}],"source_content_type":"text/x-python","patch_set":70,"id":"e273f0c6_0c35485c","line":6074,"updated":"2023-11-28 22:02:17.000000000","message":"I think the significant test we\u0027re missing is hitting a manfiest with data-segments\n\n... but I don\u0027t see a convienent _setup_manifest helper that already creates a manifest with data segments; we\u0027d have to extract one from TestSloDataSegments","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"12e6bc18e0e8c904126f5e194b9ba000e9061c7f","unresolved":false,"context_lines":[{"line_number":6071,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"},{"line_number":6072,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027application/json\u0027)"},{"line_number":6073,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00275\u0027)"},{"line_number":6074,"context_line":"        self.assertEqual(body, b\u0027\u0027)  # it\u0027s a HEAD request, after all"},{"line_number":6075,"context_line":""},{"line_number":6076,"context_line":""},{"line_number":6077,"context_line":"class TestPartNumberLegacyManifest(TestPartNumber):"}],"source_content_type":"text/x-python","patch_set":70,"id":"550ef7f2_209d8e18","line":6074,"in_reply_to":"e273f0c6_0c35485c","updated":"2023-12-04 19:17:16.000000000","message":"Done","commit_id":"9c57584525b1d5f75ff2ebc98a2c7ba59568496a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1f76590b8a767228c16f6767f708f7e44408d817","unresolved":true,"context_lines":[{"line_number":5886,"context_line":"                         self.manifest_raw_ranges_slo_etag)"},{"line_number":5887,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027],"},{"line_number":5888,"context_line":"                         self.manifest_raw_ranges_json_md5)"},{"line_number":5889,"context_line":"        # XXX why doesn\u0027t this match len(body)"},{"line_number":5890,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002799\u0027)"},{"line_number":5891,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-98/200\u0027)"},{"line_number":5892,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"}],"source_content_type":"text/x-python","patch_set":76,"id":"b47633b2_4d734442","line":5889,"updated":"2023-12-12 20:05:52.000000000","message":"the ranges in the manifest are bigger than the segment sizes ?!?","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e821688bdf08343e628625dccb65753e86fbe7d6","unresolved":true,"context_lines":[{"line_number":5886,"context_line":"                         self.manifest_raw_ranges_slo_etag)"},{"line_number":5887,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027],"},{"line_number":5888,"context_line":"                         self.manifest_raw_ranges_json_md5)"},{"line_number":5889,"context_line":"        # XXX why doesn\u0027t this match len(body)"},{"line_number":5890,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002799\u0027)"},{"line_number":5891,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-98/200\u0027)"},{"line_number":5892,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"}],"source_content_type":"text/x-python","patch_set":76,"id":"e743f92f_4dbffb89","line":5889,"in_reply_to":"b47633b2_4d734442","updated":"2023-12-14 14:49:40.000000000","message":"correct, these are nuts and only needed to work for a niche use-case - they shouldn\u0027t be re-used.","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":false,"context_lines":[{"line_number":5886,"context_line":"                         self.manifest_raw_ranges_slo_etag)"},{"line_number":5887,"context_line":"        self.assertEqual(headers[\u0027X-Manifest-Etag\u0027],"},{"line_number":5888,"context_line":"                         self.manifest_raw_ranges_json_md5)"},{"line_number":5889,"context_line":"        # XXX why doesn\u0027t this match len(body)"},{"line_number":5890,"context_line":"        self.assertEqual(headers[\u0027Content-Length\u0027], \u002799\u0027)"},{"line_number":5891,"context_line":"        self.assertEqual(headers[\u0027Content-Range\u0027], \u0027bytes 0-98/200\u0027)"},{"line_number":5892,"context_line":"        self.assertEqual(headers[\u0027X-Static-Large-Object\u0027], \u0027true\u0027)"}],"source_content_type":"text/x-python","patch_set":76,"id":"8b995738_0f0eac4c","line":5889,"in_reply_to":"e743f92f_4dbffb89","updated":"2023-12-15 16:04:06.000000000","message":"Acknowledged","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1f76590b8a767228c16f6767f708f7e44408d817","unresolved":true,"context_lines":[{"line_number":5893,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5894,"context_line":"        # the raw-ranges manifest is setup w/ content-type text/plain"},{"line_number":5895,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":5896,"context_line":"        # XXX why do we only return 9 bytes?"},{"line_number":5897,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5898,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5899,"context_line":""}],"source_content_type":"text/x-python","patch_set":76,"id":"793d5486_270de933","line":5896,"updated":"2023-12-12 20:05:52.000000000","message":"something to do with the ranges being greater than the actual segment body length??\n\nsee https://review.opendev.org/c/openstack/swift/+/903539","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e821688bdf08343e628625dccb65753e86fbe7d6","unresolved":true,"context_lines":[{"line_number":5893,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5894,"context_line":"        # the raw-ranges manifest is setup w/ content-type text/plain"},{"line_number":5895,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":5896,"context_line":"        # XXX why do we only return 9 bytes?"},{"line_number":5897,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5898,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5899,"context_line":""}],"source_content_type":"text/x-python","patch_set":76,"id":"a5aed8dc_11e7aa3c","line":5896,"in_reply_to":"793d5486_270de933","updated":"2023-12-14 14:49:40.000000000","message":"definately, such a manifest could never actually be created - these were not great stubs; but they\u0027re *terrible* for generic re-use.","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed64dcd34f4e47c2318c479e570899972b392d73","unresolved":false,"context_lines":[{"line_number":5893,"context_line":"        self.assertEqual(headers[\u0027X-Parts-Count\u0027], \u00272\u0027)"},{"line_number":5894,"context_line":"        # the raw-ranges manifest is setup w/ content-type text/plain"},{"line_number":5895,"context_line":"        self.assertEqual(headers[\u0027Content-Type\u0027], \u0027text/plain\u0027)"},{"line_number":5896,"context_line":"        # XXX why do we only return 9 bytes?"},{"line_number":5897,"context_line":"        self.assertEqual(body, b\u0027b\u0027 * 9)"},{"line_number":5898,"context_line":"        self.assertEqual(self.app.calls, expected_calls)"},{"line_number":5899,"context_line":""}],"source_content_type":"text/x-python","patch_set":76,"id":"550193bf_fc51904c","line":5896,"in_reply_to":"a5aed8dc_11e7aa3c","updated":"2023-12-15 16:04:06.000000000","message":"Acknowledged","commit_id":"7ab63dc431d00b8ca0a62d49d89ba529eaa8960b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"17824a0f7c7398fe5197875460fb95f3d0032353","unresolved":true,"context_lines":[{"line_number":1972,"context_line":"        \"\"\""},{"line_number":1973,"context_line":"        This manifest\u0027s segments are all regular objects."},{"line_number":1974,"context_line":"        \"\"\""},{"line_number":1975,"context_line":"        _bb_manifest \u003d ["},{"line_number":1976,"context_line":"            {\u0027name\u0027: \u0027/gettest/b_50\u0027, \u0027hash\u0027: md5hex(\u0027b\u0027 * 50), \u0027bytes\u0027: \u002750\u0027,"},{"line_number":1977,"context_line":"             \u0027content_type\u0027: \u0027text/plain\u0027},"},{"line_number":1978,"context_line":"        ]"}],"source_content_type":"text/x-python","patch_set":85,"id":"05cc9322_7faba45f","line":1975,"updated":"2024-01-11 14:18:12.000000000","message":"nit: odd var name","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"98ad5921046205f4f2223d266ac6d90f44496cc1","unresolved":false,"context_lines":[{"line_number":1972,"context_line":"        \"\"\""},{"line_number":1973,"context_line":"        This manifest\u0027s segments are all regular objects."},{"line_number":1974,"context_line":"        \"\"\""},{"line_number":1975,"context_line":"        _bb_manifest \u003d ["},{"line_number":1976,"context_line":"            {\u0027name\u0027: \u0027/gettest/b_50\u0027, \u0027hash\u0027: md5hex(\u0027b\u0027 * 50), \u0027bytes\u0027: \u002750\u0027,"},{"line_number":1977,"context_line":"             \u0027content_type\u0027: \u0027text/plain\u0027},"},{"line_number":1978,"context_line":"        ]"}],"source_content_type":"text/x-python","patch_set":85,"id":"b4f32158_e7f32c31","line":1975,"in_reply_to":"05cc9322_7faba45f","updated":"2024-01-11 14:18:51.000000000","message":"Done","commit_id":"3591b0f59b07ecd96727575fa35c28b44faf047c"}]}
