Skip to content

Commit c754b0b

Browse files
authored
Merge pull request #187 from lsst-sqre/tickets/DM-50042
DM-50042: Drop Expires header from {links} endpoint
2 parents ca65022 + 2a5c7cc commit c754b0b

File tree

3 files changed

+4
-14
lines changed

3 files changed

+4
-14
lines changed

changelog.d/20250411_142505_rra.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Other changes
2+
3+
- Drop `Expires` from the reply headers of the `{links}` endpoint, since that header is effectively obsolete since HTTP/1.1 given the presence of `Cache-Control` with a `max-age` parameter.

src/datalinker/handlers/external.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Handlers for the app's external root, ``/datalinker/``."""
22

3-
from datetime import UTC, datetime
4-
from email.utils import format_datetime
53
from typing import Annotated, Literal
64
from urllib.parse import urlencode
75

@@ -279,7 +277,6 @@ def links(
279277
)
280278

281279
lifetime = int(config.links_lifetime.total_seconds())
282-
expires = datetime.now(tz=UTC) + config.links_lifetime
283280
return _TEMPLATES.TemplateResponse(
284281
request,
285282
"links.xml",
@@ -290,9 +287,6 @@ def links(
290287
"image_size": image_uri.size(),
291288
"cutout_sync_url": str(config.cutout_sync_url),
292289
},
293-
headers={
294-
"Cache-Control": f"max-age={lifetime}",
295-
"Expires": format_datetime(expires, usegmt=True),
296-
},
290+
headers={"Cache-Control": f"max-age={lifetime}"},
297291
media_type="application/x-votable+xml",
298292
)

tests/handlers/external_test.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
from __future__ import annotations
44

5-
from datetime import timedelta
6-
from email.utils import parsedate_to_datetime
75
from unittest.mock import patch
86
from urllib.parse import parse_qs, urlparse
97
from uuid import uuid4
@@ -12,7 +10,6 @@
1210
from httpx import AsyncClient
1311
from jinja2 import Environment, PackageLoader, select_autoescape
1412
from lsst.daf.butler import LabeledButlerFactory
15-
from safir.datetime import current_datetime
1613

1714
from datalinker.config import config
1815

@@ -197,17 +194,13 @@ async def test_links(client: AsyncClient, mock_butler: MockButler) -> None:
197194
f"https://presigned-url.example.com/{mock_butler.uuid!s}"
198195
"?X-Amz-Signature=abcdef"
199196
)
200-
expected_expires = current_datetime() + config.links_lifetime
201197

202198
# Use iD to test the IVOA requirement of case insensitive parameters.
203199
r = await client.get(
204200
"/api/datalink/links",
205201
params={"iD": f"butler://label-http/{mock_butler.uuid!s}"},
206202
)
207203
assert r.status_code == 200
208-
expires = parsedate_to_datetime(r.headers["Expires"])
209-
assert expected_expires <= expires
210-
assert expires <= expected_expires + timedelta(seconds=5)
211204
lifetime = int(config.links_lifetime.total_seconds())
212205
assert r.headers["Cache-Control"] == f"max-age={lifetime}"
213206

0 commit comments

Comments
 (0)