fix: reject directories in _safe_path; remove Content-Disposition from _stream

_safe_path now uses path.is_file() instead of path.exists() so empty or
directory-traversal filenames never resolve to a directory and get served
as a 0-byte octet-stream download.  This was the cause of the browser
downloading a file named 'recordings' with 0 bytes when Play was clicked.

Removed Content-Disposition: inline from _stream responses — it is not
needed for <audio> playback and it was what labelled the erroneous
directory response as 'recordings' in the save dialog.
This commit is contained in:
2026-04-26 13:53:36 +02:00
parent f84b36687b
commit 357b3e6ed9
+1 -3
View File
@@ -337,7 +337,6 @@ class _Handler(BaseHTTPRequestHandler):
self.send_response(206)
self.send_header('Content-Type', content_type)
self.send_header('Content-Disposition', f'inline; filename="{path.name}"')
self.send_header('Content-Range', f'bytes {start}-{end}/{size}')
self.send_header('Content-Length', str(length))
self.send_header('Accept-Ranges', 'bytes')
@@ -355,7 +354,6 @@ class _Handler(BaseHTTPRequestHandler):
else:
self.send_response(200)
self.send_header('Content-Type', content_type)
self.send_header('Content-Disposition', f'inline; filename="{path.name}"')
self.send_header('Content-Length', str(size))
self.send_header('Accept-Ranges', 'bytes')
self.end_headers()
@@ -376,7 +374,7 @@ class _Handler(BaseHTTPRequestHandler):
self._send(403, b'Forbidden', 'text/plain')
return None
if not path.exists():
if not path.is_file():
self._send(404, b'Not found', 'text/plain')
return None