Files
Senko-san 4ade6939b6
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
feat(stream): require auth on GET /stream/{id} via token query param
The audio stream endpoint was unauthenticated. Add a get_streaming_user
dependency that accepts the access token either as a ?token= query param
(the browser <audio> element can't send an Authorization header) or a
bearer header for native clients. Update streaming tests accordingly and
add a test asserting unauthenticated requests are rejected with 401.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 17:11:43 +03:00

40 lines
1.0 KiB
Python

"""Audio streaming endpoint — direct stream with Range support."""
import uuid
from typing import Annotated
from fastapi import APIRouter, Header
from fastapi.responses import StreamingResponse
from app.api.deps import StreamingServiceDep, StreamUser
router = APIRouter(prefix="/stream", tags=["streaming"])
@router.get("/{track_id}")
async def stream_track(
track_id: uuid.UUID,
service: StreamingServiceDep,
_user: StreamUser,
range_header: Annotated[str | None, Header(alias="Range")] = None,
) -> StreamingResponse:
result = await service.open_stream(track_id, range_header)
headers = {
"Accept-Ranges": "bytes",
"Content-Length": str(result.content_length),
}
if result.is_partial:
headers["Content-Range"] = f"bytes {result.start}-{result.end}/{result.total_size}"
status_code = 206
else:
status_code = 200
return StreamingResponse(
result.stream,
status_code=status_code,
headers=headers,
media_type=result.content_type,
)