)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"68ff2ca4dadb90f84e34373adefdd72eab5b8863","unresolved":true,"context_lines":[{"line_number":7,"context_line":"s3api errors for unsupported headers x-delete-at, x-delete-after"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"A s3api PUT with a \"bad\" x-delete-at should get the 4XX response from"},{"line_number":10,"context_line":"swift and emit an InvalidArgumentError for the client"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I2c5b18e52da7f33b31ba386cdbd042f90b69ef97"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"735eb0d5_56cdbd08","line":10,"updated":"2022-11-18 16:41:15.000000000","message":"... and a \"good\" x-delete-at must continue to keep working for s3 clients","commit_id":"e1c13ead9c0fcbf890545c8e030597f8332e7c7d"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"68ff2ca4dadb90f84e34373adefdd72eab5b8863","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"32137e74_d747aafc","updated":"2022-11-18 16:41:15.000000000","message":"thanks for taking this on - is there an upstream/launchpad bug for the traceback?  \n\nhave you been able to duplicate the traceback/503 using an s3api client and a bad x-delete-at?","commit_id":"e1c13ead9c0fcbf890545c8e030597f8332e7c7d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"63b79691e00f6d201fae036f2bd22995db31af04","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"287bd348_21685ac7","updated":"2022-11-28 18:31:39.000000000","message":"I don\u0027t think it\u0027s reasonable to assume if a request included x-delete-at that a 400 from swift means the x-delete-at was bad - what other reasons might swift return a 400 to a PUT or a POST?\n\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/middleware/s3api/controllers/multi_upload.py#L804-L813\n\nWe don\u0027t want to leave the `raise BadSwiftRequest` in there anymore, that\u0027s just NOT the correct way to translate a 400 from swift to a 400 for the s3 client - that code was wrong when we imported from swift3 and we need to fix THAT bug (not just x-delete-at)\n\nWe need some kind of new s3response.ErrorResponse that we can use generically for ANY 400 response from Swift.  I tried to use ErrorResponse directly but encourtered a dumb traceback:\n\n\tNov 28 18:09:40 saio proxy-server: invalid literal for int() with base 10: \u0027\u0027: \n\tTraceback (most recent call last):\n\t  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 345, in __call__\n\t    resp \u003d self.handle_request(req)\n\t  File \"/vagrant/swift/swift/common/middleware/s3api/s3api.py\", line 383, in handle_request\n\t    res \u003d handler(req)\n\t  File \"/vagrant/swift/swift/common/middleware/s3api/controllers/obj.py\", line 157, in PUT\n\t    resp \u003d req.get_response(self.app)\n\t  File \"/vagrant/swift/swift/common/middleware/s3api/s3request.py\", line 1435, in get_response\n\t    return self._get_response(app, method, container, obj,\n\t  File \"/vagrant/swift/swift/common/middleware/s3api/s3request.py\", line 1402, in _get_response\n\t    err \u003d ErrorResponse(err_msg.decode(\u0027utf8\u0027))\n\t  File \"/vagrant/swift/swift/common/middleware/s3api/s3response.py\", line 243, in __init__\n\t    swob.HTTPException.__init__(\n\t  File \"/vagrant/swift/swift/common/swob.py\", line 1561, in __init__\n\t    Response.__init__(self, *args, **kwargs)\n\t  File \"/vagrant/swift/swift/common/swob.py\", line 1273, in __init__\n\t    self.status \u003d status\n\t  File \"/vagrant/swift/swift/common/swob.py\", line 367, in setter\n\t    self.status_int \u003d int(value.split(\u0027 \u0027, 1)[0])\n\tValueError: invalid literal for int() with base 10: \u0027\u0027 (txn: tx06e0fee89da94019a1d91-006384f964) (client_ip: 127.0.0.1)\n\nWhen I borrowed InvalidResponse with made-up name/value all the new functests still passed, but then I noticed the multi_upload controller is doing additional translation on the BadSwiftRequest exception.  We\u0027ll have to fix that and want to write some more unittests for 400 responses from swift.","commit_id":"4a0b1751b3e867980542955930b9684f4cb449af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d19404daacb0395c3c8b9cf1cbc52be4f9953aca","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"b0a3cadc_9dca1dde","updated":"2022-11-30 18:45:12.000000000","message":"Test failures look legit.","commit_id":"316563f6d2b07bfaf8a91d6fcfedafb6aa520d21"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d4d9780eaf6009c5d925a7cd7aa4f263e7004d9e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"3bbdd40a_83c4558b","updated":"2022-12-05 18:59:14.000000000","message":"There\u0027s an argument to be had about whether we should require that these headers should be present in the canonical-request/string-to-sign in order to pass them to swift, but that doesn\u0027t need to be part of this patch.","commit_id":"d363236a245ed9112c19fdd5df5fff31fa24b865"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"605d600922265b20cd89af048449af7100a73217","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"fb7241fe_db6573ca","updated":"2022-12-02 16:27:02.000000000","message":"recheck\n\nProbe test failure looks like an eventual-consistency issue caused by a slow node.","commit_id":"d363236a245ed9112c19fdd5df5fff31fa24b865"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d19404daacb0395c3c8b9cf1cbc52be4f9953aca","unresolved":true,"context_lines":[{"line_number":801,"context_line":"                                msg\u003d\u0027\\n\u0027.join(\u0027: \u0027.join(err)"},{"line_number":802,"context_line":"                                              for err in body[\u0027Errors\u0027]))"},{"line_number":803,"context_line":"                except InvalidRequest as exception:"},{"line_number":804,"context_line":"                    msg \u003d str(exception)"},{"line_number":805,"context_line":"                    if too_small_message in msg:"},{"line_number":806,"context_line":"                        raise EntityTooSmall(msg)"},{"line_number":807,"context_line":"                    elif \u0027, Etag Mismatch\u0027 in msg:"}],"source_content_type":"text/x-python","patch_set":7,"id":"47bb7ea2_781089fa","line":804,"updated":"2022-11-30 18:45:12.000000000","message":"We want to look at the error body here -- str(InvalidRequest(\u0027swift error body\u0027)) is just going to give you \u0027400 Bad Request\u0027.","commit_id":"316563f6d2b07bfaf8a91d6fcfedafb6aa520d21"}],"swift/common/middleware/s3api/s3request.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"68ff2ca4dadb90f84e34373adefdd72eab5b8863","unresolved":true,"context_lines":[{"line_number":789,"context_line":"            msg \u003d \"invalid s3 request header\""},{"line_number":790,"context_line":"            raise InvalidArgument(\u0027X-Delete-After\u0027,"},{"line_number":791,"context_line":"                                  self.headers[\u0027X-Delete-After\u0027],"},{"line_number":792,"context_line":"                                  msg)"},{"line_number":793,"context_line":""},{"line_number":794,"context_line":"        if \u0027x-amz-metadata-directive\u0027 in self.headers:"},{"line_number":795,"context_line":"            value \u003d self.headers[\u0027x-amz-metadata-directive\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"4e7faeb1_b0d9143f","line":792,"updated":"2022-11-18 16:41:15.000000000","message":"this is no good - we know that PBSS clients are doing s3api PUT w/ delete-at and we can\u0027t just start rejecting them without notice.\n\nthe only time we want to return 400 is when we currently 503\n\nif swift will eat the provided x-delete-at with 201, then we want s3api to let it\n\nif swift rejects the PUT with 4XX (for x-delete-at or whatever) THEN we should try to return a 4XX that a s3 client can present to the user.","commit_id":"e1c13ead9c0fcbf890545c8e030597f8332e7c7d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"63b79691e00f6d201fae036f2bd22995db31af04","unresolved":true,"context_lines":[{"line_number":1398,"context_line":"                raise err_resp()"},{"line_number":1399,"context_line":""},{"line_number":1400,"context_line":"        if status \u003d\u003d HTTP_BAD_REQUEST:"},{"line_number":1401,"context_line":"            if \u0027X-Delete-At\u0027 in self.headers:"},{"line_number":1402,"context_line":"                raise InvalidArgument(\u0027X-Delete-At\u0027,"},{"line_number":1403,"context_line":"                                      self.headers[\u0027X-Delete-At\u0027],"},{"line_number":1404,"context_line":"                                      err_msg.decode(\u0027utf8\u0027))"}],"source_content_type":"text/x-python","patch_set":6,"id":"91a36053_b48c1cee","line":1401,"updated":"2022-11-28 18:31:39.000000000","message":"i wish test condition pointed at something in the err_msg response instead of in request.","commit_id":"4a0b1751b3e867980542955930b9684f4cb449af"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"63b79691e00f6d201fae036f2bd22995db31af04","unresolved":true,"context_lines":[{"line_number":1407,"context_line":"                                      self.headers[\u0027X-Delete-After\u0027],"},{"line_number":1408,"context_line":"                                      err_msg.decode(\u0027utf8\u0027))"},{"line_number":1409,"context_line":"            else:"},{"line_number":1410,"context_line":"                raise BadSwiftRequest(err_msg.decode(\u0027utf8\u0027))"},{"line_number":1411,"context_line":"        if status \u003d\u003d HTTP_UNAUTHORIZED:"},{"line_number":1412,"context_line":"            raise SignatureDoesNotMatch("},{"line_number":1413,"context_line":"                **self.signature_does_not_match_kwargs())"}],"source_content_type":"text/x-python","patch_set":6,"id":"9aab2c0c_b0f7ddb5","line":1410,"updated":"2022-11-28 18:31:39.000000000","message":"This bug finally makes sense - we need to raise some kind of ErrorResponse here and get rid of BadSwiftRequest.\n\n\t(vagrant-swift-all-in-one) clayg@banana:~/Workspace/vagrant-swift-all-in-one/swift$ git diff swift/common/middleware/s3api/s3request.py\n\tdiff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py\n\tindex 6f8963b5f..8d3340d1d 100644\n\t--- a/swift/common/middleware/s3api/s3request.py\n\t+++ b/swift/common/middleware/s3api/s3request.py\n\t@@ -57,8 +57,7 @@ from swift.common.middleware.s3api.s3response import AccessDenied, \\\n\t     MalformedXML, InvalidRequest, RequestTimeout, InvalidBucketName, \\\n\t     BadDigest, AuthorizationHeaderMalformed, SlowDown, \\\n\t     AuthorizationQueryParametersError, ServiceUnavailable, BrokenMPU\n\t-from swift.common.middleware.s3api.exception import NotS3Request, \\\n\t-    BadSwiftRequest\n\t+from swift.common.middleware.s3api.exception import NotS3Request\n\t from swift.common.middleware.s3api.utils import utf8encode, \\\n\t     S3Timestamp, mktime, MULTIUPLOAD_SUFFIX\n\t from swift.common.middleware.s3api.subresource import decode_acl, encode_acl\n\t@@ -1399,7 +1398,7 @@ class S3Request(swob.Request):\n\t\t\t raise err_resp()\n\t \n\t\t if status \u003d\u003d HTTP_BAD_REQUEST:\n\t-            raise BadSwiftRequest(err_msg.decode(\u0027utf8\u0027))\n\t+            raise InvalidArgument(\u0027foo\u0027, \u0027bar\u0027, err_msg.decode(\u0027utf8\u0027))\n\t\t if status \u003d\u003d HTTP_UNAUTHORIZED:\n\t\t     raise SignatureDoesNotMatch(\n\t\t\t **self.signature_does_not_match_kwargs())","commit_id":"4a0b1751b3e867980542955930b9684f4cb449af"}],"test/functional/s3api/test_object.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"68ff2ca4dadb90f84e34373adefdd72eab5b8863","unresolved":true,"context_lines":[{"line_number":436,"context_line":"        status, headers, body \u003d \\"},{"line_number":437,"context_line":"            self.conn.make_request(\u0027PUT\u0027, self.bucket, obj, headers, content)"},{"line_number":438,"context_line":"        self.assertEqual(status, 400)"},{"line_number":439,"context_line":"        self.assertEqual(get_error_code(body), \u0027InvalidArgument\u0027)"},{"line_number":440,"context_line":""},{"line_number":441,"context_line":"    def test_put_object_copy_source_params(self):"},{"line_number":442,"context_line":"        obj \u003d \u0027object\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"371f9af8_2612d28b","line":439,"updated":"2022-11-18 16:41:15.000000000","message":"these tests look fantastic - now write a test that sends a PUT w/ x-delete-at and gets a 201","commit_id":"e1c13ead9c0fcbf890545c8e030597f8332e7c7d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"63b79691e00f6d201fae036f2bd22995db31af04","unresolved":false,"context_lines":[{"line_number":436,"context_line":"        status, headers, body \u003d \\"},{"line_number":437,"context_line":"            self.conn.make_request(\u0027PUT\u0027, self.bucket, obj, headers, content)"},{"line_number":438,"context_line":"        self.assertEqual(status, 400)"},{"line_number":439,"context_line":"        self.assertEqual(get_error_code(body), \u0027InvalidArgument\u0027)"},{"line_number":440,"context_line":""},{"line_number":441,"context_line":"    def test_put_object_copy_source_params(self):"},{"line_number":442,"context_line":"        obj \u003d \u0027object\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"8bd3f253_008fefa6","line":439,"in_reply_to":"371f9af8_2612d28b","updated":"2022-11-28 18:31:39.000000000","message":"Done","commit_id":"e1c13ead9c0fcbf890545c8e030597f8332e7c7d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"63b79691e00f6d201fae036f2bd22995db31af04","unresolved":true,"context_lines":[{"line_number":431,"context_line":"        status, delete_after, body \u003d \\"},{"line_number":432,"context_line":"            self.conn.make_request(\u0027PUT\u0027, self.bucket, obj, delete_after,"},{"line_number":433,"context_line":"                                   content)"},{"line_number":434,"context_line":"        self.assertEqual(status, 200)"},{"line_number":435,"context_line":""},{"line_number":436,"context_line":"    def test_put_object_invalid_x_delete_at(self):"},{"line_number":437,"context_line":"        obj \u003d \u0027object\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"9bf0ab3c_ea4256b7","line":434,"updated":"2022-11-28 18:31:39.000000000","message":"and since these are functests, the self.conn here is a real swift - so we know it works!","commit_id":"4a0b1751b3e867980542955930b9684f4cb449af"}]}
