)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"66017a41031f23ba10d8b54d69bda6e7b8e4fb48","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"38fa2fc6_843f51f8","updated":"2023-07-31 21:41:53.000000000","message":"I can repro the bug locally off the parent commit:\n```\nJul 31 20:53:01 saio proxy-server: ERROR Unhandled exception in request: \nTraceback (most recent call last):\n  File \"/vagrant/swift/swift/proxy/server.py\", line 608, in handle_request\n    return handler(req)\n  File \"/vagrant/swift/swift/proxy/controllers/base.py\", line 386, in wrapped\n    return func(*a, **kw)\n  File \"/vagrant/swift/swift/proxy/controllers/obj.py\", line 864, in PUT\n    self._get_update_target(req, container_info)\n  File \"/vagrant/swift/swift/proxy/controllers/obj.py\", line 404, in _get_update_target\n    shard_range \u003d self._get_update_shard(\n  File \"/vagrant/swift/swift/proxy/controllers/obj.py\", line 361, in _get_update_shard\n    return self._get_update_shard_caching_disabled(\n  File \"/vagrant/swift/swift/proxy/controllers/obj.py\", line 337, in _get_update_shard_caching_disabled\n    shard_ranges, response \u003d self._get_shard_ranges(\n  File \"/vagrant/swift/swift/proxy/controllers/base.py\", line 2409, in _get_shard_ranges\n    listing, response \u003d self._get_container_listing(\n  File \"/vagrant/swift/swift/proxy/controllers/base.py\", line 2358, in _get_container_listing\n    subreq.params \u003d params  # swob demands WSGI strings!\n  File \"/vagrant/swift/swift/common/swob.py\", line 1017, in params\n    self.query_string \u003d urllib.parse.urlencode(param_pairs,\n  File \"/usr/lib/python3.10/urllib/parse.py\", line 969, in urlencode\n    v \u003d quote_via(str(v), safe, encoding, errors)\n  File \"/usr/lib/python3.10/urllib/parse.py\", line 892, in quote_plus\n    return quote(string, safe, encoding, errors)\n  File \"/usr/lib/python3.10/urllib/parse.py\", line 875, in quote\n    string \u003d string.encode(encoding, errors)\nUnicodeEncodeError: \u0027latin-1\u0027 codec can\u0027t encode character \u0027\\u1234\u0027 in position 9: ordinal not in range(256) (txn: tx0ad49c86ca9d4fa4a5c1f-0064c81f2d) (client_ip: 127.0.0.1)\n```\nYou\u0027ve gotta turn off shard range caching:\n```\nvagrant@saio:~/swift$ grep shard -B 4 /etc/swift/proxy-server/default.conf-template \n[app:proxy-server]\nuse \u003d egg:swift#proxy\nallow_account_management \u003d true\naccount_autocreate \u003d true\nrecheck_updating_shard_ranges \u003d 0\nrecheck_listing_shard_ranges \u003d 0\n```\nBut then `test/probe/test_sharder.py::TestContainerShardingUTF8::test_sharding_listing` fails -- though it\u0027s not the best failure; the warning capture gets flooded by messages like\n```\nWARNING  urllib3.connection:connection.py:466 Failed to parse headers (url\u003dhttps://saio:443/v1/AUTH_test/container-cb48ee99-ae7b-479d-8c3a-fcb24abe030a-%C3%A4%C3%AA%C3%AC%C3%B2%C3%BB%E1%88%B4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/obj-%C3%A4%C3%AA%C3%AC%C3%B2%C3%BB%E1%88%B4-0000oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo): expected httplib.Message, got \u003cclass \u0027http.client.HTTPMessage\u0027\u003e.\nTraceback (most recent call last):\n  File \"/usr/local/lib/python3.10/dist-packages/urllib3/connection.py\", line 464, in getresponse\n    assert_header_parsing(httplib_response.msg)\n  File \"/usr/local/lib/python3.10/dist-packages/urllib3/util/response.py\", line 56, in assert_header_parsing\n    raise TypeError(f\"expected httplib.Message, got {type(headers)}.\")\nTypeError: expected httplib.Message, got \u003cclass \u0027http.client.HTTPMessage\u0027\u003e.\n```\nThe container-server change feels off, though -- I\u0027m going to dig into it some more, see what I can figure out.","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8c5e6d03e82377a8b3ff80ffd813bcd9dcc7e8c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8eeef91d_241ee09f","updated":"2023-08-01 22:34:18.000000000","message":"I\u0027ll look at getting some unit tests going for the proxy change, and maybe add some comments around types.","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"071ac3914057004f8442597134b1f8e6e9a3395f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"f658d1c7_9b9b8615","updated":"2023-07-20 17:32:34.000000000","message":"i don\u0027t know, i still don\u0027t get it - maybe some tests would help","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4f0d030d826768e58589fc2586e80900d39b054a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c3a684b3_8df1549a","updated":"2023-08-09 14:39:58.000000000","message":"I stand corrected; thanks for working it out for us Tim!","commit_id":"b42d90a347f8f6c29e220e26b4e73ba9e4fe2b8e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"895c3a6aa6fec58f5073f87baeaf99566e5cd789","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"84b2f5dc_fd5a2091","updated":"2023-08-02 22:10:15.000000000","message":"Very targeted change now, and with the config changes to disable shard-range caching, probe tests fail before and pass after.","commit_id":"b42d90a347f8f6c29e220e26b4e73ba9e4fe2b8e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4c6a9371beb1eae5c5ac4b60af88d71ad02dde3d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"2f5b5e67_f14072dd","updated":"2023-08-10 20:05:38.000000000","message":"recheck\n\n503 in `test/probe/test_reconstructor_rebuild.py::TestReconstructorRebuild::test_sync_expired_object`","commit_id":"b42d90a347f8f6c29e220e26b4e73ba9e4fe2b8e"}],"swift/container/server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"66017a41031f23ba10d8b54d69bda6e7b8e4fb48","unresolved":true,"context_lines":[{"line_number":708,"context_line":"        :returns: an instance of :class:`swift.common.swob.Response`"},{"line_number":709,"context_line":"        \"\"\""},{"line_number":710,"context_line":"        drive, part, account, container, obj \u003d get_obj_name_and_placement(req)"},{"line_number":711,"context_line":"        params \u003d validate_container_params(req)"},{"line_number":712,"context_line":"        path \u003d params.get(\u0027path\u0027)"},{"line_number":713,"context_line":"        prefix \u003d params.get(\u0027prefix\u0027)"},{"line_number":714,"context_line":"        delimiter \u003d params.get(\u0027delimiter\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"651c84d3_3adabc32","line":711,"updated":"2023-07-31 21:41:53.000000000","message":"`validate_container_params` uses `validate_params` which uses `get_param` which should be returning native `str`s...","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"071ac3914057004f8442597134b1f8e6e9a3395f","unresolved":true,"context_lines":[{"line_number":713,"context_line":"        prefix \u003d params.get(\u0027prefix\u0027)"},{"line_number":714,"context_line":"        delimiter \u003d params.get(\u0027delimiter\u0027)"},{"line_number":715,"context_line":"        marker \u003d params.get(\u0027marker\u0027, \u0027\u0027)"},{"line_number":716,"context_line":"        end_marker \u003d params.get(\u0027end_marker\u0027)"},{"line_number":717,"context_line":"        limit \u003d params[\u0027limit\u0027]"},{"line_number":718,"context_line":"        reverse \u003d config_true_value(params.get(\u0027reverse\u0027))"},{"line_number":719,"context_line":"        out_content_type \u003d listing_formats.get_listing_content_type(req)"}],"source_content_type":"text/x-python","patch_set":2,"id":"d8ff64c9_66050bc3","line":716,"updated":"2023-07-20 17:32:34.000000000","message":"if this is needed for includes, I don\u0027t see why it wouldn\u0027t be needed here as well","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"66017a41031f23ba10d8b54d69bda6e7b8e4fb48","unresolved":true,"context_lines":[{"line_number":737,"context_line":"            if is_deleted and not override_deleted:"},{"line_number":738,"context_line":"                return HTTPNotFound(request\u003dreq, headers\u003dresp_headers)"},{"line_number":739,"context_line":"            resp_headers[\u0027X-Backend-Record-Type\u0027] \u003d \u0027shard\u0027"},{"line_number":740,"context_line":"            includes \u003d wsgi_to_str(params.get(\u0027includes\u0027))"},{"line_number":741,"context_line":"            override_filter_hdr \u003d req.headers.get("},{"line_number":742,"context_line":"                \u0027x-backend-override-shard-name-filter\u0027, \u0027\u0027).lower()"},{"line_number":743,"context_line":"            if override_filter_hdr \u003d\u003d db_state \u003d\u003d \u0027sharded\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"677c7034_506e42a8","line":740,"updated":"2023-07-31 21:41:53.000000000","message":"...so this should only be WSGI-fied (and need the `wsgi_to_str`) if the client messed up -- and if the client _didn\u0027t_ then it\u0027ll throw a decode error when some unicode doesn\u0027t fit in latin-1...","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8c5e6d03e82377a8b3ff80ffd813bcd9dcc7e8c","unresolved":true,"context_lines":[{"line_number":737,"context_line":"            if is_deleted and not override_deleted:"},{"line_number":738,"context_line":"                return HTTPNotFound(request\u003dreq, headers\u003dresp_headers)"},{"line_number":739,"context_line":"            resp_headers[\u0027X-Backend-Record-Type\u0027] \u003d \u0027shard\u0027"},{"line_number":740,"context_line":"            includes \u003d wsgi_to_str(params.get(\u0027includes\u0027))"},{"line_number":741,"context_line":"            override_filter_hdr \u003d req.headers.get("},{"line_number":742,"context_line":"                \u0027x-backend-override-shard-name-filter\u0027, \u0027\u0027).lower()"},{"line_number":743,"context_line":"            if override_filter_hdr \u003d\u003d db_state \u003d\u003d \u0027sharded\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"696490ef_a1b0f979","line":740,"in_reply_to":"677c7034_506e42a8","updated":"2023-08-01 22:34:18.000000000","message":"Confirmed, we don\u0027t want this: with the patch as-is, I get tracebacks like\n\n```\nAug  1 22:24:58 saio container-6041: ERROR __call__ error with GET /sdb4/10/AUTH_test/container-5c7397ac-a7fc-4a0f-aba8-bb3c6ac95d1d-%C3%A4%C3%AA%C3%AC%C3%B2%C3%BB%E1%88%B4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : \nTraceback (most recent call last):\n  File \"/vagrant/swift/swift/container/server.py\", line 906, in __call__\n    res \u003d getattr(self, req.method)(req)\n  File \"/vagrant/swift/swift/common/utils/__init__.py\", line 1370, in _timing_stats\n    resp \u003d func(ctrl, *args, **kwargs)\n  File \"/vagrant/swift/swift/container/server.py\", line 740, in GET\n    includes \u003d wsgi_to_str(params.get(\u0027includes\u0027))\n  File \"/vagrant/swift/swift/common/swob.py\", line 292, in wsgi_to_str\n    return wsgi_to_bytes(wsgi_str).decode(\u0027utf8\u0027, errors\u003d\u0027surrogateescape\u0027)\n  File \"/vagrant/swift/swift/common/swob.py\", line 284, in wsgi_to_bytes\n    return wsgi_str.encode(\u0027latin1\u0027)\nUnicodeEncodeError: \u0027latin-1\u0027 codec can\u0027t encode character \u0027\\u1234\u0027 in position 10: ordinal not in range(256)\n```\n\nwhen running probe tests with shard-range-caching disabled.\n\nReally, it\u0027s kind of nice: upgrade story is nice and simple this way. No upgrade-order dependency or anything; proxies on old code will continue to fail in this circumstance until they get on new code, while container servers are continuing to just do their thing.","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"071ac3914057004f8442597134b1f8e6e9a3395f","unresolved":true,"context_lines":[{"line_number":2402,"context_line":"        params.pop(\u0027limit\u0027, None)"},{"line_number":2403,"context_line":"        params[\u0027format\u0027] \u003d \u0027json\u0027"},{"line_number":2404,"context_line":"        if includes:"},{"line_number":2405,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2406,"context_line":"        if states:"},{"line_number":2407,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2408,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027}"}],"source_content_type":"text/x-python","patch_set":2,"id":"6d2f5111_7a9042e9","line":2405,"updated":"2023-07-20 17:32:34.000000000","message":"I don\u0027t understand, these aren\u0027t WSGI paths, they should already be quoted - and includes seem to work fine on master:\n\n\tvagrant@saio:~$ swift upload lots-of-files test --object-name test-’ --debug\n\tDEBUG:urllib3.connectionpool:Starting new HTTP connection (1): saio:8080\n\tDEBUG:urllib3.connectionpool:http://saio:8080 \"GET /auth/v1.0 HTTP/1.1\" 200 0\n\tDEBUG:swiftclient:REQ: curl -i http://saio:8080/auth/v1.0 -X GET\n\tDEBUG:swiftclient:RESP STATUS: 200 OK\n\tDEBUG:swiftclient:RESP HEADERS: {\u0027Content-Type\u0027: \u0027text/html; charset\u003dUTF-8\u0027, \u0027X-Auth-Token\u0027: \u0027AUTH_tk84de22bc15c94100a837cc7b18160a93\u0027, \u0027X-Storage-Token\u0027: \u0027AUTH_tk84de22bc15c94100a837cc7b18160a93\u0027, \u0027X-Auth-Token-Expires\u0027: \u002778224\u0027, \u0027X-Storage-Url\u0027: \u0027http://saio:8080/v1/AUTH_test\u0027, \u0027Content-Length\u0027: \u00270\u0027, \u0027X-Trans-Id\u0027: \u0027txb57e3e60ab5546e5ba3cb-0064b96ed7\u0027, \u0027X-Openstack-Request-Id\u0027: \u0027txb57e3e60ab5546e5ba3cb-0064b96ed7\u0027, \u0027Date\u0027: \u0027Thu, 20 Jul 2023 17:28:55 GMT\u0027}\n\tDEBUG:urllib3.connectionpool:Starting new HTTP connection (1): saio:8080\n\tDEBUG:urllib3.connectionpool:http://saio:8080 \"PUT /v1/AUTH_test/lots-of-files HTTP/1.1\" 202 76\n\tDEBUG:swiftclient:REQ: curl -i http://saio:8080/v1/AUTH_test/lots-of-files -X PUT -H \"X-Auth-Token: AUTH_tk84de22bc15c94100a837cc7b18160a93\" -H \"Content-Length: 0\"\n\tDEBUG:swiftclient:RESP STATUS: 202 Accepted\n\tDEBUG:swiftclient:RESP HEADERS: {\u0027Content-Type\u0027: \u0027text/html; charset\u003dUTF-8\u0027, \u0027Content-Length\u0027: \u002776\u0027, \u0027X-Trans-Id\u0027: \u0027txbcab856ec421444eb7e01-0064b96ed7\u0027, \u0027X-Openstack-Request-Id\u0027: \u0027txbcab856ec421444eb7e01-0064b96ed7\u0027, \u0027Date\u0027: \u0027Thu, 20 Jul 2023 17:28:55 GMT\u0027}\n\tDEBUG:swiftclient:RESP BODY: b\u0027\u003chtml\u003e\u003ch1\u003eAccepted\u003c/h1\u003e\u003cp\u003eThe request is accepted for processing.\u003c/p\u003e\u003c/html\u003e\u0027\n\tDEBUG:urllib3.connectionpool:Starting new HTTP connection (1): saio:8080\n\tDEBUG:urllib3.connectionpool:http://saio:8080 \"GET /auth/v1.0 HTTP/1.1\" 200 0\n\tDEBUG:swiftclient:REQ: curl -i http://saio:8080/auth/v1.0 -X GET\n\tDEBUG:swiftclient:RESP STATUS: 200 OK\n\tDEBUG:swiftclient:RESP HEADERS: {\u0027Content-Type\u0027: \u0027text/html; charset\u003dUTF-8\u0027, \u0027X-Auth-Token\u0027: \u0027AUTH_tk84de22bc15c94100a837cc7b18160a93\u0027, \u0027X-Storage-Token\u0027: \u0027AUTH_tk84de22bc15c94100a837cc7b18160a93\u0027, \u0027X-Auth-Token-Expires\u0027: \u002778224\u0027, \u0027X-Storage-Url\u0027: \u0027http://saio:8080/v1/AUTH_test\u0027, \u0027Content-Length\u0027: \u00270\u0027, \u0027X-Trans-Id\u0027: \u0027txe82879268db44ff8a3478-0064b96ed7\u0027, \u0027X-Openstack-Request-Id\u0027: \u0027txe82879268db44ff8a3478-0064b96ed7\u0027, \u0027Date\u0027: \u0027Thu, 20 Jul 2023 17:28:55 GMT\u0027}\n\tDEBUG:urllib3.connectionpool:Starting new HTTP connection (1): saio:8080\n\tDEBUG:urllib3.connectionpool:http://saio:8080 \"HEAD /v1/AUTH_test/lots-of-files/test-%E2%80%99 HTTP/1.1\" 200 0\n\tDEBUG:swiftclient:REQ: curl -i http://saio:8080/v1/AUTH_test/lots-of-files/test-’ -I -H \"X-Auth-Token: AUTH_tk84de22bc15c94100a837cc7b18160a93\"\n\tDEBUG:swiftclient:RESP STATUS: 200 OK\n\tDEBUG:swiftclient:RESP HEADERS: {\u0027Content-Type\u0027: \u0027application/octet-stream\u0027, \u0027X-Object-Meta-Mtime\u0027: \u00271689865968.595470\u0027, \u0027Etag\u0027: \u0027\"70c1db56f301c9e337b0099bd4174b28\"\u0027, \u0027Last-Modified\u0027: \u0027Thu, 20 Jul 2023 17:21:31 GMT\u0027, \u0027X-Timestamp\u0027: \u00271689873690.81611\u0027, \u0027Accept-Ranges\u0027: \u0027bytes\u0027, \u0027Content-Length\u0027: \u00278\u0027, \u0027X-Trans-Id\u0027: \u0027tx076d655b82c24eaaa7344-0064b96ed7\u0027, \u0027X-Openstack-Request-Id\u0027: \u0027tx076d655b82c24eaaa7344-0064b96ed7\u0027, \u0027Date\u0027: \u0027Thu, 20 Jul 2023 17:28:56 GMT\u0027}\n\tDEBUG:urllib3.connectionpool:http://saio:8080 \"PUT /v1/AUTH_test/lots-of-files/test-%E2%80%99 HTTP/1.1\" 201 0\n\tDEBUG:swiftclient:REQ: curl -i http://saio:8080/v1/AUTH_test/lots-of-files/test-’ -X PUT -H \"x-object-meta-mtime: 1689865968.595470\" -H \"X-Auth-Token: AUTH_tk84de22bc15c94100a837cc7b18160a93\" -H \"Content-Length: 8\"\n\tDEBUG:swiftclient:RESP STATUS: 201 Created\n\tDEBUG:swiftclient:RESP HEADERS: {\u0027Content-Type\u0027: \u0027text/html; charset\u003dUTF-8\u0027, \u0027Content-Length\u0027: \u00270\u0027, \u0027Etag\u0027: \u0027\"70c1db56f301c9e337b0099bd4174b28\"\u0027, \u0027Last-Modified\u0027: \u0027Thu, 20 Jul 2023 17:28:57 GMT\u0027, \u0027X-Trans-Id\u0027: \u0027txed2fb45c31c94d919a2eb-0064b96ed8\u0027, \u0027X-Openstack-Request-Id\u0027: \u0027txed2fb45c31c94d919a2eb-0064b96ed8\u0027, \u0027Date\u0027: \u0027Thu, 20 Jul 2023 17:28:56 GMT\u0027}\n\ttest-’\n\tvagrant@saio:~$ python\n\tPython 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0] on linux\n\tType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\t\u003e\u003e\u003e import urllib.parse\n\t\u003e\u003e\u003e urllib.parse.quote(\u0027test-’\u0027)\n\t\u0027test-%E2%80%99\u0027\n\t\u003e\u003e\u003e urllib.parse.unquote(\u0027test-%E2%80%99\u0027)\n\t\u0027test-’\u0027\n\t\u003e\u003e\u003e \n\tvagrant@saio:~$ curl -s -H \u0027accept: application/json\u0027 \"http://127.0.0.2:6021/sdb2/59/.shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1689867346.30030-9?prefix\u003dtest-%E2%80%99\" | python -m json.tool\n\t[\n\t    {\n\t\t\"bytes\": 8,\n\t\t\"hash\": \"70c1db56f301c9e337b0099bd4174b28\",\n\t\t\"name\": \"test-\\u2019\",\n\t\t\"content_type\": \"application/octet-stream\",\n\t\t\"last_modified\": \"2023-07-20T17:28:56.018160\"\n\t    }\n\t]\n\tvagrant@saio:~$ curl -s -H \u0027x-backend-record-type: shard\u0027 -H \u0027accept: application/json\u0027 \"http://127.0.0.2:6021/sdb2/54/AUTH_test/lots-of-files?includes\u003dtest-%E2%80%99\" | python -m json.tool\n\t[\n\t    {\n\t\t\"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1689867346.30030-9\",\n\t\t\"timestamp\": \"1689867346.30030\",\n\t\t\"lower\": \"obj0899\",\n\t\t\"upper\": \"\",\n\t\t\"object_count\": 101,\n\t\t\"bytes_used\": 8,\n\t\t\"meta_timestamp\": \"1689873713.89010\",\n\t\t\"deleted\": 0,\n\t\t\"state\": 40,\n\t\t\"state_timestamp\": \"1689867346.30030\",\n\t\t\"epoch\": null,\n\t\t\"reported\": 0,\n\t\t\"tombstones\": 0,\n\t\t\"last_modified\": \"2023-07-20T15:35:46.300300\"\n\t    }\n\t]","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"66017a41031f23ba10d8b54d69bda6e7b8e4fb48","unresolved":true,"context_lines":[{"line_number":2402,"context_line":"        params.pop(\u0027limit\u0027, None)"},{"line_number":2403,"context_line":"        params[\u0027format\u0027] \u003d \u0027json\u0027"},{"line_number":2404,"context_line":"        if includes:"},{"line_number":2405,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2406,"context_line":"        if states:"},{"line_number":2407,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2408,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027}"}],"source_content_type":"text/x-python","patch_set":2,"id":"4a2cb21f_2f8c69a6","line":2405,"in_reply_to":"6d2f5111_7a9042e9","updated":"2023-07-31 21:41:53.000000000","message":"\u003e these aren\u0027t WSGI paths, they should already be quoted\n\n... no? The `Request.params` setter should do the encoding; expectation is that the params dict passed to `_get_container_listing` is full of WSGI strings.\n\n\u003e includes seem to work fine on master\n\nIs that with shard range caching enabled or not? If caching is enabled, we never actually _use_ `includes`, we do that filtering in the proxy.","commit_id":"eb1ebe038da30a8472136ba075aec2c4bde5c358"}]}
