diff --git a/.env-sample b/.env-sample index 66afc91..862dba4 100644 --- a/.env-sample +++ b/.env-sample @@ -277,15 +277,10 @@ STREMTHRU_URL=https://stremthru.13377001.xyz # needed to use debrid services HTTP_CACHE_ENABLED=False # Master switch for HTTP cache headers -# PUBLIC streams TTL (for /stream/movie/tt1234567.json without user config) -# These can be cached at edge and shared between all users. -# Higher = less origin traffic, lower = fresher results -HTTP_CACHE_PUBLIC_STREAMS_TTL=300 # 5 minutes (recommended: 120-600) - -# PRIVATE streams TTL (for /{config}/stream/... with user config) -# Only cached in user's browser (private cache). -# These contain user-specific debrid availability info. -HTTP_CACHE_PRIVATE_STREAMS_TTL=60 # 1 minute (recommended: 30-120) +# STREAMS streams TTL (for /stream/movie/tt1234567.json) +# These results are cached at edge and shared between all users. +# Higher = less traffic to origin, Lower = faster updates for new content +HTTP_CACHE_STREAMS_TTL=300 # 5 minutes # Stale-While-Revalidate: serve stale content while fetching fresh in background # Improves perceived performance - users get instant response with cached data diff --git a/comet/api/endpoints/stream.py b/comet/api/endpoints/stream.py index fd33f1f..a53d328 100644 --- a/comet/api/endpoints/stream.py +++ b/comet/api/endpoints/stream.py @@ -5,7 +5,7 @@ from urllib.parse import quote import aiohttp from fastapi import APIRouter, BackgroundTasks, Request -from comet.core.config_validation import config_check, is_default_config +from comet.core.config_validation import config_check from comet.core.logger import logger from comet.core.models import database, settings, trackers from comet.debrid.exceptions import DebridAuthError @@ -30,7 +30,6 @@ streams = APIRouter() def _build_stream_response( request: Request, content: dict, - is_public: bool = False, is_empty: bool = False, vary_headers: list = None, ): @@ -45,12 +44,9 @@ def _build_stream_response( if is_empty: cache_policy = CachePolicies.empty_results() vary = ["Accept", "Accept-Encoding"] - elif is_public: - cache_policy = CachePolicies.public_torrents() - vary = ["Accept", "Accept-Encoding"] else: - cache_policy = CachePolicies.private_streams() - vary = ["Accept", "Accept-Encoding", "Authorization"] + cache_policy = CachePolicies.streams() + vary = ["Accept", "Accept-Encoding"] if vary_headers: vary.extend(vary_headers) @@ -177,17 +173,11 @@ async def stream( b64config: str = None, chilllink: bool = False, ): - is_public_request = b64config is None - if media_type not in ["movie", "series"]: - return _build_stream_response( - request, {"streams": []}, is_public=True, is_empty=True - ) + return _build_stream_response(request, {"streams": []}, is_empty=True) if "tmdb:" in media_id: - return _build_stream_response( - request, {"streams": []}, is_public=True, is_empty=True - ) + return _build_stream_response(request, {"streams": []}, is_empty=True) media_id = media_id.replace("imdb_id:", "") @@ -202,12 +192,7 @@ async def stream( } ] } - return _build_stream_response( - request, error_response, is_public=True, is_empty=True - ) - - if is_default_config(config): - is_public_request = True + return _build_stream_response(request, error_response, is_empty=True) is_torrent = config["debridService"] == "torrent" if settings.DISABLE_TORRENT_STREAMS and is_torrent: @@ -218,9 +203,7 @@ async def stream( if settings.TORRENT_DISABLED_STREAM_URL: placeholder_stream["url"] = settings.TORRENT_DISABLED_STREAM_URL - return _build_stream_response( - request, {"streams": [placeholder_stream]}, is_public=is_public_request - ) + return _build_stream_response(request, {"streams": [placeholder_stream]}) connector = aiohttp.TCPConnector(limit=0) async with aiohttp.ClientSession(connector=connector) as session: @@ -247,7 +230,6 @@ async def stream( } ] }, - is_public=True, is_empty=True, ) @@ -356,7 +338,6 @@ async def stream( } ] }, - is_public=True, is_empty=True, ) @@ -475,7 +456,6 @@ async def stream( } ] }, - is_public=True, is_empty=True, ) @@ -558,7 +538,6 @@ async def stream( } ] }, - is_public=False, is_empty=True, ) @@ -675,6 +654,5 @@ async def stream( return _build_stream_response( request, {"streams": final_streams}, - is_public=is_public_request or not has_results, is_empty=not has_results, ) diff --git a/comet/core/logger.py b/comet/core/logger.py index f42e301..60f94c8 100644 --- a/comet/core/logger.py +++ b/comet/core/logger.py @@ -436,7 +436,7 @@ def log_startup_info(settings): logger.log("COMET", f"Custom Header HTML: {bool(settings.CUSTOM_HEADER_HTML)}") http_cache_info = ( - f" - Public Streams TTL: {settings.HTTP_CACHE_PUBLIC_STREAMS_TTL}s - Private Streams TTL: {settings.HTTP_CACHE_PRIVATE_STREAMS_TTL}s - Manifest TTL: {settings.HTTP_CACHE_MANIFEST_TTL}s - Configure TTL: {settings.HTTP_CACHE_CONFIGURE_TTL}s - SWR: {settings.HTTP_CACHE_STALE_WHILE_REVALIDATE}s" + f" - Streams TTL: {settings.HTTP_CACHE_STREAMS_TTL}s - Manifest TTL: {settings.HTTP_CACHE_MANIFEST_TTL}s - Configure TTL: {settings.HTTP_CACHE_CONFIGURE_TTL}s - SWR: {settings.HTTP_CACHE_STALE_WHILE_REVALIDATE}s" if settings.HTTP_CACHE_ENABLED else "" ) diff --git a/comet/core/models.py b/comet/core/models.py index 18e6d1a..a073fa6 100644 --- a/comet/core/models.py +++ b/comet/core/models.py @@ -138,8 +138,7 @@ class AppSettings(BaseSettings): RATELIMIT_RETRY_BASE_DELAY: Optional[float] = 1.0 RTN_FILTER_DEBUG: Optional[bool] = False HTTP_CACHE_ENABLED: Optional[bool] = False - HTTP_CACHE_PUBLIC_STREAMS_TTL: Optional[int] = 300 - HTTP_CACHE_PRIVATE_STREAMS_TTL: Optional[int] = 60 + HTTP_CACHE_STREAMS_TTL: Optional[int] = 300 HTTP_CACHE_STALE_WHILE_REVALIDATE: Optional[int] = 60 HTTP_CACHE_MANIFEST_TTL: Optional[int] = 86400 HTTP_CACHE_CONFIGURE_TTL: Optional[int] = 86400 diff --git a/comet/utils/cache.py b/comet/utils/cache.py index 46f509f..5c9550f 100644 --- a/comet/utils/cache.py +++ b/comet/utils/cache.py @@ -154,13 +154,13 @@ def not_modified_response(etag: str): class CachePolicies: @staticmethod - def public_torrents(): + def streams(): """ - For public torrent lists (without user config). + For all stream results. Cache for a short time at CDN, revalidate often. """ - ttl = settings.HTTP_CACHE_PUBLIC_STREAMS_TTL + ttl = settings.HTTP_CACHE_STREAMS_TTL swr = settings.HTTP_CACHE_STALE_WHILE_REVALIDATE return ( @@ -172,17 +172,6 @@ class CachePolicies: .stale_if_error(300) ) - @staticmethod - def private_streams(): - """ - For user-specific stream results (with b64config). - Private cache only, short TTL. - """ - - ttl = settings.HTTP_CACHE_PRIVATE_STREAMS_TTL - - return CacheControl().private().max_age(ttl).must_revalidate() - @staticmethod def manifest(): """ diff --git a/deployment/cloudflare-cache-rules.md b/deployment/cloudflare-cache-rules.md index f7c35df..0fa2def 100644 --- a/deployment/cloudflare-cache-rules.md +++ b/deployment/cloudflare-cache-rules.md @@ -3,7 +3,7 @@ To optimize performance, configure Cloudflare to offload traffic from your server. We use **Cache Rules** to cache responses while respecting the application's cache headers. ## 1. Streams (Cache Rule) -Cache all stream results (public and private). Comet controls the TTL via headers. +Cache all stream results. Comet controls the TTL via headers. * **Rule Name**: Streams * **Expression**: `(http.request.uri.path contains "/stream/")`