ETag support for .db downloads, closes #1739

pull/1740/head
Simon Willison 2022-05-03 07:59:18 -07:00
rodzic d60f163528
commit 280ff372ab
3 zmienionych plików z 34 dodań i 3 usunięć

Wyświetl plik

@ -55,10 +55,21 @@ class TestClient:
@async_to_sync
async def get(
self, path, follow_redirects=False, redirect_count=0, method="GET", cookies=None
self,
path,
follow_redirects=False,
redirect_count=0,
method="GET",
cookies=None,
if_none_match=None,
):
return await self._request(
path, follow_redirects, redirect_count, method, cookies
path=path,
follow_redirects=follow_redirects,
redirect_count=redirect_count,
method=method,
cookies=cookies,
if_none_match=if_none_match,
)
@async_to_sync
@ -110,6 +121,7 @@ class TestClient:
headers=None,
post_body=None,
content_type=None,
if_none_match=None,
):
return await self._request(
path,
@ -120,6 +132,7 @@ class TestClient:
headers=headers,
post_body=post_body,
content_type=content_type,
if_none_match=if_none_match,
)
async def _request(
@ -132,10 +145,13 @@ class TestClient:
headers=None,
post_body=None,
content_type=None,
if_none_match=None,
):
headers = headers or {}
if content_type:
headers["content-type"] = content_type
if if_none_match:
headers["if-none-match"] = if_none_match
httpx_response = await self.ds.client.request(
method,
path,

Wyświetl plik

@ -183,6 +183,13 @@ class DatabaseDownload(DataView):
headers = {}
if self.ds.cors:
add_cors_headers(headers)
if db.hash:
etag = '"{}"'.format(db.hash)
headers["Etag"] = etag
# Has user seen this already?
if_none_match = request.headers.get("if-none-match")
if if_none_match and if_none_match == etag:
return Response("", status=304)
headers["Transfer-Encoding"] = "chunked"
return AsgiFileDownload(
filepath,

Wyświetl plik

@ -401,7 +401,7 @@ def test_database_download_for_immutable():
assert len(soup.findAll("a", {"href": re.compile(r"\.db$")}))
# Check we can actually download it
download_response = client.get("/fixtures.db")
assert 200 == download_response.status
assert download_response.status == 200
# Check the content-length header exists
assert "content-length" in download_response.headers
content_length = download_response.headers["content-length"]
@ -413,6 +413,14 @@ def test_database_download_for_immutable():
== 'attachment; filename="fixtures.db"'
)
assert download_response.headers["transfer-encoding"] == "chunked"
# ETag header should be present and match db.hash
assert "etag" in download_response.headers
etag = download_response.headers["etag"]
assert etag == '"{}"'.format(client.ds.databases["fixtures"].hash)
# Try a second download with If-None-Match: current-etag
download_response2 = client.get("/fixtures.db", if_none_match=etag)
assert download_response2.body == b""
assert download_response2.status == 304
def test_database_download_disallowed_for_mutable(app_client):