)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e5eb403f02b0f531de22b00349b513e460045bad","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"42544b5e_d69d6152","updated":"2026-05-11 16:00:52.000000000","message":"I don\u0027t really understand how this works; but if it passes against s3 it MUST be good!","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a37dc700b74425b3451fff61686c80014c34d4cc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"06508349_e5258849","updated":"2026-05-11 14:55:10.000000000","message":"Passes against S3 and Swift on my VSAIO. If I revert the fix in the parent patch then the test runs approx forever","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"cfdd2a7a8caf57360cb7406847116e5abae4e616","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"a0964249_4368edee","updated":"2026-05-12 04:07:22.000000000","message":"The fact that is tends to run forever in master is a little scary. Nice one Christian.","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c38228fdb6d4c308b544cabc6254115c8dd9da94","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"46052b11_91db0562","updated":"2026-05-22 20:57:57.000000000","message":"I think this is a great test, very similar to `test_strm_unsgnd_pyld_trl_te_chunked_ok` and demonstrates the problem","commit_id":"99e9948060c91065b0aea63c3e2ec4064aa89aa9"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy","status":"I\u0027m a Software Engineer at Red Hat and I love Open Source and connect with people! Feel free to DM through IRC, I\u0027ll be delighted to chat"},"change_message_id":"2b47f5be6f9c7b9cb34d883256e6f3366dd44d8b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"9c06d1a9_646d638b","updated":"2026-05-25 11:10:52.000000000","message":"The functional test precisely captures the bug and prevents future regressions, thank you!\n\nWhat I did to test this patch:\n- Reviewed parent patch (5ad23e2f6) to understand the bug: StreamingInput infinite loop on truncated aws-chunked input\n- Tested in SAIO:\n    - With fix: Test passes in ~7s\n    - Without fix (master only): Test hangs indefinitely\n    \nLeft one comment suggesting to add explicit timeout protection. Otherwise, looks good to me!","commit_id":"99e9948060c91065b0aea63c3e2ec4064aa89aa9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2858a34e393f7cca5b72ea76f6dc430720c547ac","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"d55e409f_c71b5364","updated":"2026-05-27 17:02:53.000000000","message":"LGTM, test passes against S3","commit_id":"0da44e9ea2ea5fd3ded31941318be71c676feb2e"}],"test/s3api/test_input_errors.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a37dc700b74425b3451fff61686c80014c34d4cc","unresolved":true,"context_lines":[{"line_number":2146,"context_line":"        # actually delivered before Content-Length is reached. The wsgi input"},{"line_number":2147,"context_line":"        # then returns b\u0027\u0027 mid-chunk. Ensure StreamingInput does not loop"},{"line_number":2148,"context_line":"        # forever on the empty read; the fix raises S3InputIncomplete and the"},{"line_number":2149,"context_line":"        # proxy maps that to 400 IncompleteBody."},{"line_number":2150,"context_line":"        chunk_size \u003d 8192"},{"line_number":2151,"context_line":"        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * 100"},{"line_number":2152,"context_line":"        request \u003d self.conn.build_request("}],"source_content_type":"text/x-python","patch_set":1,"id":"c342bb10_3007c179","line":2149,"updated":"2026-05-11 14:55:10.000000000","message":"nit: possibly overly secific implementation detail for a compat test","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"a8a62fe8ee9d37ea39f9e83c0850fdf8cd0e0867","unresolved":false,"context_lines":[{"line_number":2146,"context_line":"        # actually delivered before Content-Length is reached. The wsgi input"},{"line_number":2147,"context_line":"        # then returns b\u0027\u0027 mid-chunk. Ensure StreamingInput does not loop"},{"line_number":2148,"context_line":"        # forever on the empty read; the fix raises S3InputIncomplete and the"},{"line_number":2149,"context_line":"        # proxy maps that to 400 IncompleteBody."},{"line_number":2150,"context_line":"        chunk_size \u003d 8192"},{"line_number":2151,"context_line":"        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * 100"},{"line_number":2152,"context_line":"        request \u003d self.conn.build_request("}],"source_content_type":"text/x-python","patch_set":1,"id":"8ff4065c_9bcad696","line":2149,"in_reply_to":"c342bb10_3007c179","updated":"2026-05-12 14:28:40.000000000","message":"Acknowledged","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a37dc700b74425b3451fff61686c80014c34d4cc","unresolved":true,"context_lines":[{"line_number":2157,"context_line":"                \u0027x-amz-content-sha256\u0027: \u0027STREAMING-UNSIGNED-PAYLOAD-TRAILER\u0027,"},{"line_number":2158,"context_line":"                \u0027content-encoding\u0027: \u0027aws-chunked\u0027,"},{"line_number":2159,"context_line":"                \u0027x-amz-decoded-content-length\u0027: str(chunk_size),"},{"line_number":2160,"context_line":"                \u0027content-length\u0027: str(len(body)),"},{"line_number":2161,"context_line":"            },"},{"line_number":2162,"context_line":"        )"},{"line_number":2163,"context_line":"        self.conn.sign_request(request)"}],"source_content_type":"text/x-python","patch_set":1,"id":"e88a128b_ce1fdee8","line":2160,"updated":"2026-05-11 14:55:10.000000000","message":"ok, content-length is the length of the actual sent (truncated) body, so once that is all read the input will return b\u0027\u0027 but the aws-chunked payload will not have completed","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"cfdd2a7a8caf57360cb7406847116e5abae4e616","unresolved":true,"context_lines":[{"line_number":2157,"context_line":"                \u0027x-amz-content-sha256\u0027: \u0027STREAMING-UNSIGNED-PAYLOAD-TRAILER\u0027,"},{"line_number":2158,"context_line":"                \u0027content-encoding\u0027: \u0027aws-chunked\u0027,"},{"line_number":2159,"context_line":"                \u0027x-amz-decoded-content-length\u0027: str(chunk_size),"},{"line_number":2160,"context_line":"                \u0027content-length\u0027: str(len(body)),"},{"line_number":2161,"context_line":"            },"},{"line_number":2162,"context_line":"        )"},{"line_number":2163,"context_line":"        self.conn.sign_request(request)"}],"source_content_type":"text/x-python","patch_set":1,"id":"68aa7db8_d8774f9a","line":2160,"in_reply_to":"00ea80d5_d1dd1db3","updated":"2026-05-12 04:07:22.000000000","message":"I guess the crux is it isn\u0027t using `transfer-encoding: chunked` it\u0027s using aws\u0027s own `aws-chunked` which basically allows the sig v4 to be done in stages, but also implements their own chunked like scheme.. Which Christian is doing in the body incorrectly to cause the issue.","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c38228fdb6d4c308b544cabc6254115c8dd9da94","unresolved":false,"context_lines":[{"line_number":2157,"context_line":"                \u0027x-amz-content-sha256\u0027: \u0027STREAMING-UNSIGNED-PAYLOAD-TRAILER\u0027,"},{"line_number":2158,"context_line":"                \u0027content-encoding\u0027: \u0027aws-chunked\u0027,"},{"line_number":2159,"context_line":"                \u0027x-amz-decoded-content-length\u0027: str(chunk_size),"},{"line_number":2160,"context_line":"                \u0027content-length\u0027: str(len(body)),"},{"line_number":2161,"context_line":"            },"},{"line_number":2162,"context_line":"        )"},{"line_number":2163,"context_line":"        self.conn.sign_request(request)"}],"source_content_type":"text/x-python","patch_set":1,"id":"2bba9b5b_dae40904","line":2160,"in_reply_to":"68aa7db8_d8774f9a","updated":"2026-05-22 20:57:57.000000000","message":"Acknowledged","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e5eb403f02b0f531de22b00349b513e460045bad","unresolved":true,"context_lines":[{"line_number":2157,"context_line":"                \u0027x-amz-content-sha256\u0027: \u0027STREAMING-UNSIGNED-PAYLOAD-TRAILER\u0027,"},{"line_number":2158,"context_line":"                \u0027content-encoding\u0027: \u0027aws-chunked\u0027,"},{"line_number":2159,"context_line":"                \u0027x-amz-decoded-content-length\u0027: str(chunk_size),"},{"line_number":2160,"context_line":"                \u0027content-length\u0027: str(len(body)),"},{"line_number":2161,"context_line":"            },"},{"line_number":2162,"context_line":"        )"},{"line_number":2163,"context_line":"        self.conn.sign_request(request)"}],"source_content_type":"text/x-python","patch_set":1,"id":"00ea80d5_d1dd1db3","line":2160,"in_reply_to":"e88a128b_ce1fdee8","updated":"2026-05-11 16:00:52.000000000","message":"I don\u0027t really understand what\u0027s going on here; I would expect that we can send `content-length` AND `content-encoding: aws-chunked` - *I* thought that `content-encoding: aws-chunked` was limited to `transfer-encoding: chunked`","commit_id":"cccb6809e662bcd3925565883e0fbd043a1e72c9"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy","status":"I\u0027m a Software Engineer at Red Hat and I love Open Source and connect with people! Feel free to DM through IRC, I\u0027ll be delighted to chat"},"change_message_id":"2b47f5be6f9c7b9cb34d883256e6f3366dd44d8b","unresolved":true,"context_lines":[{"line_number":2141,"context_line":"        self.assertOK(resp, TEST_BODY)"},{"line_number":2142,"context_line":"        self.assertNotIn(\u0027Content-Encoding\u0027, resp.headers)"},{"line_number":2143,"context_line":""},{"line_number":2144,"context_line":"    def test_strm_unsgnd_pyld_trl_truncated_mid_chunk(self):"},{"line_number":2145,"context_line":"        chunk_size \u003d 8192"},{"line_number":2146,"context_line":"        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * (chunk_size - 1)"},{"line_number":2147,"context_line":"        resp \u003d self.conn.make_request("}],"source_content_type":"text/x-python","patch_set":2,"id":"c64a6067_19954d7d","line":2144,"updated":"2026-05-25 11:10:52.000000000","message":"Suggestion: In case of a regression introduced, the test hangs forever in infinite loop, without a proper failure, so it would rely on external timeout like CI timeout or a manual Ctrl+C. I verified this by running the test on master without the parent fix, it runs forever until manually killed. I am not sure if it was supposed to be like this, but a suggestion that I have is to add the `@pytest.mark.timeout` decorator:\n\n```\n@pytest.mark.timeout(30)\ndef test_strm_unsgnd_pyld_trl_truncated_mid_chunk(self):\n    ...\n```","commit_id":"ae749e1e160150195d0d2dcc1b79772fc674b430"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"2c999381778d394ce93d5122508169d836e8410e","unresolved":true,"context_lines":[{"line_number":2141,"context_line":"        self.assertOK(resp, TEST_BODY)"},{"line_number":2142,"context_line":"        self.assertNotIn(\u0027Content-Encoding\u0027, resp.headers)"},{"line_number":2143,"context_line":""},{"line_number":2144,"context_line":"    def test_strm_unsgnd_pyld_trl_truncated_mid_chunk(self):"},{"line_number":2145,"context_line":"        chunk_size \u003d 8192"},{"line_number":2146,"context_line":"        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * (chunk_size - 1)"},{"line_number":2147,"context_line":"        resp \u003d self.conn.make_request("}],"source_content_type":"text/x-python","patch_set":2,"id":"0f3b4462_81c388d4","line":2144,"in_reply_to":"c64a6067_19954d7d","updated":"2026-05-27 16:24:20.000000000","message":"Hmm, this requires an additional dependency (pytest-timeout) which is not even in openstack/requirements - not sure if this is really needed? It would be only required if the behavior regresses, so hopefully never?","commit_id":"ae749e1e160150195d0d2dcc1b79772fc674b430"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c38228fdb6d4c308b544cabc6254115c8dd9da94","unresolved":true,"context_lines":[{"line_number":2143,"context_line":""},{"line_number":2144,"context_line":"    def test_strm_unsgnd_pyld_trl_truncated_mid_chunk(self):"},{"line_number":2145,"context_line":"        chunk_size \u003d 8192"},{"line_number":2146,"context_line":"        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * (chunk_size - 1)"},{"line_number":2147,"context_line":"        resp \u003d self.conn.make_request("},{"line_number":2148,"context_line":"            self.bucket_name,"},{"line_number":2149,"context_line":"            \u0027test-obj\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"adb5a362_c9d6c962","line":2146,"updated":"2026-05-22 20:57:57.000000000","message":"ok, and b/c we\u0027re using `STREAMING-UNSIGNED-PAYLOAD-TRAILER` we don\u0027t expect the `;check-signature\u003d\u003csha256hash\u003e` or any of the hashes checksums inside of the chunk.  \n\ni.e. if you go to:\n\n```\n-        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * (chunk_size - 1)\n+        body \u003d b\u0027%x\\r\\n%s\\r\\n0\\r\\n\\r\\n\u0027 % (\n+            chunk_size, b\u0027A\u0027 * chunk_size)\n```\n\nyou\u0027re basically the next test \"chunked_ok\" but with a \"content-length: len(body)\" (implicit) instead of `transfer-encoding: chunked` (implicit) and that\u0027s explicitly allowed/valid/ok from the Note at the top of AWS docs:\n\nhttps://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html\n\n... regardless it\u0027s only the \"truncated_mid_chunk\" behavior that leads to the lockup, i.e.\n\n```\n-        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * (chunk_size - 1)\n+        body \u003d b\u0027%x\\r\\n\u0027 % chunk_size + b\u0027A\u0027 * chunk_size\n```\n\npasses on master b/c you\u0027re missing the `0\\r\\n\\r\\n` bit","commit_id":"99e9948060c91065b0aea63c3e2ec4064aa89aa9"}]}
