diff --git a/aurweb/routers/rpc.py b/aurweb/routers/rpc.py index 6abd73d9..66376067 100644 --- a/aurweb/routers/rpc.py +++ b/aurweb/routers/rpc.py @@ -113,6 +113,11 @@ async def rpc(request: Request, "ETag": f'"{etag}"' } + if_none_match = request.headers.get("If-None-Match", str()) + if if_none_match and if_none_match.strip("\t\n\r\" ") == etag: + return Response(headers=headers, + status_code=int(HTTPStatus.NOT_MODIFIED)) + if callback: content = f"/**/{callback}({content.decode()})" diff --git a/test/test_rpc.py b/test/test_rpc.py index f4ce6de8..055baa33 100644 --- a/test/test_rpc.py +++ b/test/test_rpc.py @@ -1,6 +1,7 @@ import re from http import HTTPStatus +from typing import Dict from unittest import mock import orjson @@ -28,9 +29,9 @@ from aurweb.redis import redis_connection from aurweb.testing import setup_test_db -def make_request(path): +def make_request(path, headers: Dict[str, str] = {}): with TestClient(app) as request: - return request.get(path) + return request.get(path, headers=headers) @pytest.fixture(autouse=True) @@ -539,6 +540,13 @@ def test_rpc_search(): result = data.get("results")[0] assert result.get("Name") == "big-chungus" + # Test the If-None-Match headers. + etag = response.headers.get("ETag").strip('"') + headers = {"If-None-Match": etag} + response = make_request("/rpc?v=5&type=search&arg=big", headers=headers) + assert response.status_code == int(HTTPStatus.NOT_MODIFIED) + assert response.content == b'' + # No args on non-m by types return an error. response = make_request("/rpc?v=5&type=search") assert response.json().get("error") == "No request type/data specified."