Skip to content

fix: accept HEAD requests on the playback endpoint - #631

Open
funkypenguin wants to merge 1 commit into
g0ldyy:mainfrom
elfhosted:fix/playback-accept-head
Open

fix: accept HEAD requests on the playback endpoint#631
funkypenguin wants to merge 1 commit into
g0ldyy:mainfrom
elfhosted:fix/playback-accept-head

Conversation

@funkypenguin

@funkypenguin funkypenguin commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Problem

/{b64config}/playback/... is registered with @router.get(...), so it answers 405 Method Not Allowed to HEAD.

This is easy to miss because Starlette's Route auto-adds HEAD whenever GET is present, but FastAPI's APIRoute does not — it takes methods verbatim. So a plain @router.get route is GET-only.

Reported by a user on Stremio for Android TV (ExoPlayer), which probes the stream URL with HEAD before opening it. Desktop players don't, which is why this only shows up on some clients.

Fix

Register the route with api_route(..., methods=["GET", "HEAD"]). One line plus the decorator swap; no handler changes.

The handler was already HEAD-ready:

  • request.method is already forwarded to custom_handle_stream_request
  • mediaflow_proxy.handlers.handle_stream_request has an explicit HEAD branch that closes the streamer and returns headers without a body
  • combined_background_tasks already tolerates the None close-task that the HEAD branch produces, so the active_connections row is still released
  • Starlette's FileResponse (status videos) and RedirectResponse both handle HEAD by sending headers only

Verification

Against v2.58.0, on the playback route:

before after
HEAD 405 200, 0-byte body, content-type: video/mp4
GET 200 200 (unchanged)

Note (not in this PR)

/{b64config}/debrid-sync/{service_index} is also handed to players as a stream URL and is likewise GET-only, so it 405s on HEAD too. I left it out because it is a side-effecting trigger — making it accept HEAD would mean a probe fires an account sync. Happy to follow up if you'd like it handled.

Summary by CodeRabbit

  • New Features
    • Playback requests now support both GET and HEAD methods.
    • Existing playback behavior and responses remain unchanged.

FastAPI's APIRoute does not add HEAD to a route's methods the way
Starlette's Route does, so the playback endpoint answered 405 Method Not
Allowed to any HEAD probe. Some clients (reported on Stremio for Android
TV / ExoPlayer) probe a stream URL with HEAD before opening it.

Register the route with api_route(methods=["GET", "HEAD"]). No handler
changes are needed: request.method is already forwarded to
custom_handle_stream_request, mediaflow_proxy's handle_stream_request has
an explicit HEAD branch that closes the streamer and returns headers only,
and combined_background_tasks already tolerates the resulting None close
task. Starlette's FileResponse and RedirectResponse both handle HEAD by
sending headers without a body.

Verified against v2.58.0: HEAD now returns 200 with a zero-byte body and
the same content-type GET serves.
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2f48e59a-7c06-4d2f-8730-9c94dd4d656a

📥 Commits

Reviewing files that changed from the base of the PR and between f56677f and 84a4606.

📒 Files selected for processing (1)
  • comet/api/endpoints/playback.py

Walkthrough

The playback endpoint now accepts both GET and HEAD requests. Its handler and response behavior remain unchanged.

Changes

Playback route

Layer / File(s) Summary
Register HEAD requests
comet/api/endpoints/playback.py
The playback route decorator now registers GET and HEAD methods.
Suggested reviewers: g0ldyy

Mergeability Score: ⚪ Minimal · up to 84a46

This localized change enables HEAD requests on the playback endpoint without changing GET behavior or handler logic, and no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: enabling HEAD requests on the playback endpoint.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@funkypenguin

Copy link
Copy Markdown
Contributor Author

Note - the user who reported this issue claimed that it was "fixed", but in retrospect, the updated container hadn't rolled out to them yet, so IDK whether this was the root cause of their exoplayer problem or not 🤷🏻

@SwordfishTrumpet

Copy link
Copy Markdown

+1 — independently confirmed in production. We’ve been running this exact approach since 2026-06-24 (HEAD handler delegating to the playback logic, body-stripped response preserving the 302 Location) on a custom image. Without it, Stremio’s HEAD probe gets 405 and playback fails with “Loading Failed”. Just re-applied it on top of v2.58.0 — HEAD returns 302, playback works. Would be great to get this merged so the custom build can be dropped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants