v7: file storage limits - 1MB per file, 50MB total, FIFO eviction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-03-26 14:43:20 +04:00
parent 229223168e
commit d55b65db1f

31
chat.py
View File

@@ -25,16 +25,29 @@ import html
import urllib.parse
PORT = 9999
VERSION = "6"
VERSION = "7"
TUNNEL_TARGET = ("185.208.174.152", 22)
MAX_UPLOAD = 10 * 1024 * 1024 # 10 MB
MAX_FILE_SIZE = 1 * 1024 * 1024 # 1 MB per file
MAX_TOTAL_STORAGE = 50 * 1024 * 1024 # 50 MB total
# ── Server ──────────────────────────────────────────────────────────────
clients: dict[asyncio.StreamWriter, str] = {} # TCP clients
sse_queues: list[asyncio.Queue] = [] # web clients
history: list[dict] = []
uploaded_files: dict[str, bytes] = {} # file_id -> raw bytes
uploaded_files: dict[str, bytes] = {} # file_id -> raw bytes (insertion order)
total_file_bytes = 0
def store_file(file_id: str, data: bytes):
"""Store a file, evicting oldest files if total storage exceeds limit."""
global total_file_bytes
uploaded_files[file_id] = data
total_file_bytes += len(data)
while total_file_bytes > MAX_TOTAL_STORAGE and uploaded_files:
oldest_id = next(iter(uploaded_files))
total_file_bytes -= len(uploaded_files.pop(oldest_id))
async def broadcast(msg: dict):
@@ -481,9 +494,9 @@ async def handle_http(reader, writer, first_line):
if file_entry and file_entry[0]:
filename = file_entry[0]
file_data = file_entry[1]
if len(file_data) <= MAX_UPLOAD:
if len(file_data) <= MAX_FILE_SIZE:
file_id = hashlib.sha256(file_data + str(time.time()).encode()).hexdigest()[:16]
uploaded_files[file_id] = file_data
store_file(file_id, file_data)
await broadcast({
"ts": time.time(), "user": name,
"text": f"[file: {filename}]",
@@ -577,8 +590,10 @@ async def handle(reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
pkt = json.loads(line)
if pkt.get("type") == "file":
file_data = base64.b64decode(pkt["data"])
if len(file_data) > MAX_FILE_SIZE:
continue
file_id = hashlib.sha256(file_data + str(time.time()).encode()).hexdigest()[:16]
uploaded_files[file_id] = file_data
store_file(file_id, file_data)
await broadcast({
"ts": time.time(), "user": name,
"text": f"[file: {pkt['filename']}]",
@@ -693,8 +708,8 @@ class ChatClient:
self.messages.append((f" *** file not found: {filepath}", CP_SYSTEM))
return
size = os.path.getsize(filepath)
if size > MAX_UPLOAD:
self.messages.append((f" *** file too large ({size} bytes, max {MAX_UPLOAD})", CP_SYSTEM))
if size > MAX_FILE_SIZE:
self.messages.append((f" *** file too large ({size} bytes, max {MAX_FILE_SIZE})", CP_SYSTEM))
return
with open(filepath, "rb") as f:
data = f.read()