feat: add automatic session expiry to prevent stale session accumulation

Sessions now track their creation time and are automatically cleaned up after SESSION_TIMEOUT (30s) when a new session is opened. This prevents stale sessions from accumulating when clients crash or disconnect without calling close(), which would otherwise permanently exhaust the 16-session limit and make the CDM unusable until server restart.
Mirrors the existing implementation in csplayready.

Closes #4
This commit is contained in:
Sp4rky 2026-02-26 13:51:26 -07:00
parent 6817250fb7
commit 30d20728bc
2 changed files with 12 additions and 0 deletions

View File

@ -1,5 +1,6 @@
from __future__ import annotations
import time
import xml.etree.ElementTree as ET
from typing import List, Union, Optional
from uuid import UUID
@ -24,6 +25,7 @@ from pyplayready.system.wrmheader import WRMHeader
class Cdm:
MAX_NUM_OF_SESSIONS = 16
SESSION_TIMEOUT = 30
def __init__(
self,
@ -59,6 +61,14 @@ class Cdm:
def open(self) -> bytes:
"""Open a Playready Content Decryption Module (CDM) session"""
now = time.time()
expired = [
session_id for session_id, session in self.__sessions.items()
if (now - session.opened_at) > self.SESSION_TIMEOUT
]
for session_id in expired:
del self.__sessions[session_id]
if len(self.__sessions) > self.MAX_NUM_OF_SESSIONS:
raise TooManySessions(f"Too many Sessions open ({self.MAX_NUM_OF_SESSIONS}).")

View File

@ -1,3 +1,4 @@
import time
from typing import Optional
from Crypto.Random import get_random_bytes
@ -15,3 +16,4 @@ class Session:
self.signing_key: Optional[ECCKey] = None
self.encryption_key: Optional[ECCKey] = None
self.keys: list[Key] = []
self.opened_at: float = time.time()