From fd527cff7e5a88135122fc0ef7d010533e24b469 Mon Sep 17 00:00:00 2001 From: Skulldorom <51134009+Skulldorom@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:43:04 +0300 Subject: [PATCH] Normalize and encode FreshRSS categories --- main.py | 12 +++++++++--- tests/test_main.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 627c74a..f750597 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,7 @@ import logging import os +from urllib.parse import quote + from fastapi import FastAPI, HTTPException, Query import requests import humanize @@ -72,7 +74,7 @@ def health(): @app.get("/freshrss/unread") def freshrss_unread( n: int = Query(default=10, ge=1), - category: str | None = Query(default=None), + category: str | None = Query(default=None, max_length=200), ): token = get_greader_token() headers = {"Authorization": f"GoogleLogin auth={token}"} @@ -81,8 +83,12 @@ def freshrss_unread( "output": "json", "n": n, } - category_label = category if isinstance(category, str) and category else None - stream_id = f"user/-/label/{category_label}" if category_label else "user/-/state/com.google/reading-list" + category_label = category.strip() if isinstance(category, str) else None + stream_id = ( + f"user/-/label/{quote(category_label, safe='')}" + if category_label + else "user/-/state/com.google/reading-list" + ) # Using the same host as before but with the right endpoint url = f"{FRESHRSS_HOST}/api/greader.php/reader/api/0/stream/contents/{stream_id}" try: diff --git a/tests/test_main.py b/tests/test_main.py index 8e624e9..ab3aba0 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -193,6 +193,36 @@ def fake_get(url, headers, params, timeout): assert result[0]["url"] == "" +@pytest.mark.parametrize( + ("category", "expected_stream"), + [ + (" Tech News ", "user/-/label/Tech%20News"), + ("Tech/News", "user/-/label/Tech%2FNews"), + ("100% News", "user/-/label/100%25%20News"), + ("What?", "user/-/label/What%3F"), + ("日本語", "user/-/label/%E6%97%A5%E6%9C%AC%E8%AA%9E"), + (" \t\n ", "user/-/state/com.google/reading-list"), + ], +) +def test_freshrss_unread_normalizes_and_encodes_category(monkeypatch, category, expected_stream): + main = import_app(monkeypatch) + monkeypatch.setattr(main, "get_greader_token", lambda: "token-123") + captured = {} + + def fake_get(url, **kwargs): + captured["url"] = url + return FakeResponse(payload={"items": []}) + + monkeypatch.setattr(main.requests, "get", fake_get) + + main.freshrss_unread(category=category) + + assert captured["url"] == ( + "https://freshrss.example.test/api/greader.php/reader/api/0/stream/contents/" + f"{expected_stream}" + ) + + def test_freshrss_unread_wraps_upstream_http_errors(monkeypatch): main = import_app(monkeypatch) monkeypatch.setattr(main, "get_greader_token", lambda: "token-123")