diff --git a/elasticapm/contrib/sanic/utils.py b/elasticapm/contrib/sanic/utils.py index e4e987274..91cb986e3 100644 --- a/elasticapm/contrib/sanic/utils.py +++ b/elasticapm/contrib/sanic/utils.py @@ -148,4 +148,12 @@ def make_client(client_cls=Client, **defaults) -> Client: def _transform_response_cookie(cookies: CookieJar) -> Dict[str, str]: """Transform the Sanic's CookieJar instance into a Normal dictionary to build the context""" - return {k: {"value": v.value, "path": v["path"]} for k, v in cookies.items()} + # old sanic versions used to have an items() method + if hasattr(cookies, "items"): + return {k: {"value": v.value, "path": v["path"]} for k, v in cookies.items()} + + try: + return {cookie.key: {"value": cookie.value, "path": cookie.path} for cookie in cookies.cookies} + except KeyError: + # cookies.cookies assumes Set-Cookie header will be there + return {} diff --git a/tests/contrib/asyncio/starlette_tests.py b/tests/contrib/asyncio/starlette_tests.py index e3c4f4a16..38c51fa08 100644 --- a/tests/contrib/asyncio/starlette_tests.py +++ b/tests/contrib/asyncio/starlette_tests.py @@ -348,7 +348,8 @@ def test_transaction_name_is_route(app, elasticapm_client): ) def test_trailing_slash_redirect_detection(app, elasticapm_client, url, expected): client = TestClient(app) - response = client.get(url, allow_redirects=False) + kwargs = {"allow_redirects": False} if starlette_version_tuple < (0, 43) else {"follow_redirects": False} + response = client.get(url, **kwargs) assert response.status_code == 307 assert len(elasticapm_client.events[constants.TRANSACTION]) == 1 for transaction in elasticapm_client.events[constants.TRANSACTION]: diff --git a/tests/contrib/sanic/fixtures.py b/tests/contrib/sanic/fixtures.py index e4d8d4158..0f231243c 100644 --- a/tests/contrib/sanic/fixtures.py +++ b/tests/contrib/sanic/fixtures.py @@ -155,6 +155,12 @@ async def raise_value_error(request): async def custom_headers(request): return json({"data": "message"}, headers={"sessionid": 1234555}) + @app.get("/add-cookies") + async def add_cookies(request): + response = json({"data": "message"}, headers={"sessionid": 1234555}) + response.add_cookie("some", "cookie") + return response + try: yield app, apm finally: diff --git a/tests/contrib/sanic/sanic_tests.py b/tests/contrib/sanic/sanic_tests.py index ec97fb02f..291ceae7c 100644 --- a/tests/contrib/sanic/sanic_tests.py +++ b/tests/contrib/sanic/sanic_tests.py @@ -194,6 +194,16 @@ def test_header_field_sanitization(sanic_elastic_app, elasticapm_client): assert transaction["context"]["request"]["headers"]["api_key"] == "[REDACTED]" +def test_cookies_normalization(sanic_elastic_app, elasticapm_client): + sanic_app, apm = next(sanic_elastic_app(elastic_client=elasticapm_client)) + _, resp = sanic_app.test_client.get( + "/add-cookies", + ) + assert len(apm._client.events[constants.TRANSACTION]) == 1 + transaction = apm._client.events[constants.TRANSACTION][0] + assert transaction["context"]["response"]["cookies"] == {"some": {"value": "cookie", "path": "/"}} + + def test_custom_callback_handlers(sanic_elastic_app, elasticapm_client): def _custom_transaction_callback(request): return "my-custom-name"