diff --git a/src/connectrpc/_client_shared.py b/src/connectrpc/_client_shared.py index d0df033..bfd3e49 100644 --- a/src/connectrpc/_client_shared.py +++ b/src/connectrpc/_client_shared.py @@ -22,14 +22,12 @@ def prepare_get_params( codec: Codec, request_data: bytes, headers: HTTPHeaders ) -> dict[str, str]: - params = { - "connect": f"v{CONNECT_PROTOCOL_VERSION}", - "message": base64.urlsafe_b64encode(request_data).decode("ascii"), - "base64": "1", - "encoding": codec.name(), - } + # Follow order in spec: https://connectrpc.com/docs/protocol/#unary-get-request + params: dict[str, str] = {"connect": f"v{CONNECT_PROTOCOL_VERSION}", "base64": "1"} if "content-encoding" in headers: params["compression"] = headers.pop("content-encoding") + params["encoding"] = codec.name() + params["message"] = base64.urlsafe_b64encode(request_data).decode("ascii") return params diff --git a/test/test_client_shared.py b/test/test_client_shared.py new file mode 100644 index 0000000..179ecf5 --- /dev/null +++ b/test/test_client_shared.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +from urllib.parse import urlencode + +from pyqwest import Headers as HTTPHeaders + +from connectrpc._client_shared import prepare_get_params +from connectrpc.codec import proto_binary_codec + + +def test_prepare_get_params_order() -> None: + headers = HTTPHeaders([("content-encoding", "gzip")]) + params = prepare_get_params(proto_binary_codec(), b"hello", headers) + assert list(params.keys()) == [ + "connect", + "base64", + "compression", + "encoding", + "message", + ] + assert "content-encoding" not in headers + query = urlencode(params) + expected_prefix = "connect=v1&base64=1&compression=gzip&encoding=proto&message=" + assert query.startswith(expected_prefix) + + +def test_prepare_get_params_order_without_compression() -> None: + params = prepare_get_params(proto_binary_codec(), b"hello", HTTPHeaders([])) + assert list(params.keys()) == ["connect", "base64", "encoding", "message"]