diff --git a/CHANGES.md b/CHANGES.md index dd8dca36d..99c2d98c9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Release Notes +## [unreleased] + +- fix `LowerCaseQueryStringMiddleware` unexpectedly truncating query parameters (https://github.com/developmentseed/titiler/pull/677) + ## 0.13.0 (2023-07-27) * update core requirements to libraries using pydantic **~=2.0** diff --git a/src/titiler/core/tests/test_case_middleware.py b/src/titiler/core/tests/test_case_middleware.py index 00b885773..0a13abe7f 100644 --- a/src/titiler/core/tests/test_case_middleware.py +++ b/src/titiler/core/tests/test_case_middleware.py @@ -47,3 +47,26 @@ async def route1(value: Annotated[List[str], Query()]): response = client.get("/route1?VALUE=lorenzori&VALUE=dogs&value=trucks") assert response.json() == {"value": ["lorenzori", "dogs", "trucks"]} + + +def test_lowercase_middleware_url_with_query_parameters(): + """Make sure all query parameters return.""" + app = FastAPI() + + @app.get("/route1") + async def route1(url: List[str] = Query(...)): + """route1.""" + return {"url": url} + + app.add_middleware(LowerCaseQueryStringMiddleware) + + client = TestClient(app) + + url = "https://developmentseed.org?solutions=geospatial&planet=better" + url_encoded = ( + "https%3A%2F%2Fdevelopmentseed.org%3Fsolutions%3Dgeospatial%26planet%3Dbetter" + ) + + response = client.get(f"/route1?url={url_encoded}") + + assert response.json() == {"url": [url]} diff --git a/src/titiler/core/titiler/core/middleware.py b/src/titiler/core/titiler/core/middleware.py index f592c962d..0d19eb688 100644 --- a/src/titiler/core/titiler/core/middleware.py +++ b/src/titiler/core/titiler/core/middleware.py @@ -3,6 +3,7 @@ import logging import re import time +import urllib.parse from typing import Optional, Set from fastapi.logger import logger @@ -160,7 +161,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send): query_string = "" for k, v in request.query_params.multi_items(): - query_string += k.lower() + "=" + v + "&" + query_string += k.lower() + "=" + urllib.parse.quote(v) + "&" query_string = query_string[:-1] request.scope["query_string"] = query_string.encode(DECODE_FORMAT)