Move RSS response headers into app
This commit is contained in:
parent
e7b00b4129
commit
a6632ef769
2 changed files with 55 additions and 2 deletions
20
repub/web.py
20
repub/web.py
|
|
@ -4,7 +4,7 @@ import asyncio
|
|||
import hashlib
|
||||
from collections.abc import AsyncGenerator, Awaitable, Callable
|
||||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import TypedDict, cast
|
||||
from urllib.parse import urlparse
|
||||
|
|
@ -590,7 +590,23 @@ def _load_sidebar_counts(app: Quart) -> dict[str, int]:
|
|||
def _rss_feed_response(feed_text: str | None) -> Response:
|
||||
if feed_text is None:
|
||||
return Response(status=404)
|
||||
return Response(feed_text, mimetype="application/rss+xml")
|
||||
etag = hashlib.sha256(feed_text.encode("utf-8")).hexdigest()
|
||||
if request.if_none_match.contains(etag):
|
||||
response = Response(status=304)
|
||||
else:
|
||||
response = Response(
|
||||
feed_text,
|
||||
content_type="application/rss+xml; charset=utf-8",
|
||||
)
|
||||
response.set_etag(etag)
|
||||
response.cache_control.public = True
|
||||
response.cache_control.max_age = 300
|
||||
response.expires = datetime.now(UTC) + timedelta(minutes=5)
|
||||
response.vary.add("Host")
|
||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||
response.headers["Access-Control-Allow-Methods"] = "GET, HEAD, OPTIONS"
|
||||
response.headers["Access-Control-Allow-Headers"] = "*"
|
||||
return response
|
||||
|
||||
|
||||
def _read_feed_text(*, feeds_dir: Path, feed_path: str) -> str | None:
|
||||
|
|
|
|||
|
|
@ -133,5 +133,42 @@ def test_published_rss_rewrites_feed_url_to_https_host_header(
|
|||
"<link>https://example.com/article</link>"
|
||||
"</channel></rss>\n"
|
||||
)
|
||||
assert response.headers["Access-Control-Allow-Origin"] == "*"
|
||||
assert response.headers["Access-Control-Allow-Methods"] == "GET, HEAD, OPTIONS"
|
||||
assert response.headers["Access-Control-Allow-Headers"] == "*"
|
||||
assert response.cache_control.public is True
|
||||
assert response.cache_control.max_age == 300
|
||||
assert response.headers["ETag"] != ""
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_published_rss_supports_conditional_requests(
|
||||
monkeypatch, tmp_path: Path
|
||||
) -> None:
|
||||
db_path = tmp_path / "conditional-rss.db"
|
||||
feeds_dir = tmp_path / "out" / "feeds"
|
||||
monkeypatch.setenv("REPUBLISHER_DB_PATH", str(db_path))
|
||||
|
||||
async def run() -> None:
|
||||
app = create_app()
|
||||
app.config["REPUB_FEEDS_DIR"] = feeds_dir
|
||||
feed_path = feeds_dir / "demo-source" / "feed.rss"
|
||||
feed_path.parent.mkdir(parents=True)
|
||||
feed_path.write_text(
|
||||
"<rss><channel><title>Demo</title></channel></rss>\n", encoding="utf-8"
|
||||
)
|
||||
|
||||
client = app.test_client()
|
||||
first_response = await client.get("/feeds/demo-source/feed.rss")
|
||||
etag = first_response.headers["ETag"]
|
||||
second_response = await client.get(
|
||||
"/feeds/demo-source/feed.rss",
|
||||
headers={"If-None-Match": etag},
|
||||
)
|
||||
|
||||
assert second_response.status_code == 304
|
||||
assert await second_response.get_data(as_text=True) == ""
|
||||
assert second_response.headers["ETag"] == etag
|
||||
|
||||
asyncio.run(run())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue