diff --git a/CHANGES.md b/CHANGES.md index 5899749f2..0376b4e9d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ ### Fixed +* Allow url encoded values for `query` in GET requests ([#504](https://github.com/stac-utils/stac-fastapi/pull/504)) + ## [2.4.3] ### Added @@ -22,7 +24,6 @@ ### Fixed - ## [2.4.2] ### Added diff --git a/stac_fastapi/pgstac/stac_fastapi/pgstac/core.py b/stac_fastapi/pgstac/stac_fastapi/pgstac/core.py index 9f9f0a093..9b194f70e 100644 --- a/stac_fastapi/pgstac/stac_fastapi/pgstac/core.py +++ b/stac_fastapi/pgstac/stac_fastapi/pgstac/core.py @@ -2,7 +2,7 @@ import re from datetime import datetime from typing import Any, Dict, List, Optional, Union -from urllib.parse import urljoin +from urllib.parse import unquote_plus, urljoin import attr import orjson @@ -372,7 +372,7 @@ async def get_search( "bbox": bbox, "limit": limit, "token": token, - "query": orjson.loads(query) if query else query, + "query": orjson.loads(unquote_plus(query)) if query else query, } if filter: diff --git a/stac_fastapi/pgstac/tests/api/test_api.py b/stac_fastapi/pgstac/tests/api/test_api.py index 6a8bc2776..1f7fbe371 100644 --- a/stac_fastapi/pgstac/tests/api/test_api.py +++ b/stac_fastapi/pgstac/tests/api/test_api.py @@ -1,5 +1,7 @@ from datetime import datetime, timedelta +from urllib.parse import quote_plus +import orjson import pytest STAC_CORE_ROUTES = [ @@ -102,6 +104,12 @@ async def test_app_query_extension(load_test_data, app_client, load_test_collect resp_json = resp.json() assert len(resp_json["features"]) == 1 + params["query"] = quote_plus(orjson.dumps(params["query"])) + resp = await app_client.get("/search", params=params) + assert resp.status_code == 200 + resp_json = resp.json() + assert len(resp_json["features"]) == 1 + async def test_app_query_extension_limit_1( load_test_data, app_client, load_test_collection diff --git a/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/core.py b/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/core.py index 16a4c856e..68c96f2de 100644 --- a/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/core.py +++ b/stac_fastapi/sqlalchemy/stac_fastapi/sqlalchemy/core.py @@ -4,7 +4,7 @@ import operator from datetime import datetime from typing import List, Optional, Set, Type, Union -from urllib.parse import urlencode, urljoin +from urllib.parse import unquote_plus, urlencode, urljoin import attr import geoalchemy2 as ga @@ -243,7 +243,7 @@ def get_search( "bbox": bbox, "limit": limit, "token": token, - "query": json.loads(query) if query else query, + "query": json.loads(unquote_plus(query)) if query else query, } if datetime: diff --git a/stac_fastapi/sqlalchemy/tests/api/test_api.py b/stac_fastapi/sqlalchemy/tests/api/test_api.py index 2cfec175c..de4f5d734 100644 --- a/stac_fastapi/sqlalchemy/tests/api/test_api.py +++ b/stac_fastapi/sqlalchemy/tests/api/test_api.py @@ -1,4 +1,7 @@ from datetime import datetime, timedelta +from urllib.parse import quote_plus + +import orjson from ..conftest import MockStarletteRequest @@ -150,6 +153,12 @@ def test_app_query_extension_gt(load_test_data, app_client, postgres_transaction resp_json = resp.json() assert len(resp_json["features"]) == 0 + params["query"] = quote_plus(orjson.dumps(params["query"])) + resp = app_client.get("/search", params=params) + assert resp.status_code == 200 + resp_json = resp.json() + assert len(resp_json["features"]) == 0 + def test_app_query_extension_gte(load_test_data, app_client, postgres_transactions): test_item = load_test_data("test_item.json")