Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Media handler does not support HTTP range requests #4780

Open
k80w opened this issue Mar 2, 2019 · 4 comments
Open

Media handler does not support HTTP range requests #4780

k80w opened this issue Mar 2, 2019 · 4 comments
Labels
P4 (OBSOLETE: use S- labels.) Okay backlog: will not schedule, will accept patches S-Minor Blocks non-critical functionality, workarounds exist. T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues.

Comments

@k80w
Copy link
Contributor

k80w commented Mar 2, 2019

Presently, Synapse does not support HTTP range requests, which prevents users from seeking through audio/video media in many browsers. element-hq/element-web#2909 sought to fix this, though as that PR has been closed, I figured I should open another issue. This issue is the root cause of matrix-org/riot-web#4265.

@wapsi
Copy link

wapsi commented Dec 30, 2021

I had issues with my WebKit based web browsers (mainly Gnome's Epiphany) that GStreamer failed to play any videos because Synapse returns HTTP response 200 (OK) when the client performs Range request (the return code should be 206 if Range functionality is supported):

0:00:35.565467510 201865 0x5637dbbd6630 WARN webkitwebsrc WebKitWebSourceGStreamer.cpp:1054:responseReceived: error: R2: Received unexpected 200 HTTP status code for range request
0:00:35.565665181 201865 0x5637dbf698c0 DEBUG webkitwebsrc WebKitWebSourceGStreamer.cpp:567:webKitWebSrcCreate: Reached the end of the response, signalling EOS
0:00:35.565922158 201865 0x5637dbbd6630 LOG webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:1705:handleMessage: Message error received from element source
0:00:35.565949342 201865 0x5637dbbd6630 ERROR webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:1711:handleMessage: Error 9: R2: Received unexpected 200 HTTP status code for range request (url=https://www.foo.bar/_matrix/media/r0/download/foo.bar/xxx)
0:00:35.566048994 201865 0x5637dbbd6630 DEBUG webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:896:changePipelineState: Rejected state change to READY from READY with PAUSED pending
0:00:35.567078624 201865 0x5637dbbd6630 DEBUG webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:188:~MediaPlayerPrivateGStreamer: Disposing player
0:00:35.730489598 201865 0x5637dbbd6630 DEBUG webkitglvideosink GLVideoSinkGStreamer.cpp:181:webKitGLVideoSinkChangeState: READY->NULL

But for now, as a workaround I configured my Apache (which acts as a frontend / reverse proxy in the front of the actual Synapse instance) to interrupt the media downloads, and by using mod_rewrite it serves the static media files directly from /var/lib/matrix-synapse/media/local_content directory (so those queries won't reach Synapse at all and Apache handles the Range requests properly). (Please note that this is just PoC and needs to be modified if used with Nginx e.g.):

Alias /matrix-media /var/lib/matrix-synapse/media/local_content
<Location "/var/lib/matrix-synapse/media/local_content">
  Header set Accept-Ranges bytes
</Location>
# Omit link preview downloads from mobile devices:
RewriteCond %{REQUEST_URI} !^/_matrix/media/r0/download/foo.bar/[0-9]{4}-[0-9]{2}-[0-9]{2}_
RewriteCond %{REQUEST_URI} ^/_matrix/media/r0/download/foo.bar
RewriteRule ^/_matrix/media/r0/download/foo.bar/([A-Za-z0-9]{2})([A-Za-z0-9]{2})(.*)$ /matrix-media/$1/$2/$3 [R=301,L]

With that configuration applied I'm able to play videos in Epiphany and the seeking is working properly too.

Please note that this most probably breaks the correct mime type reported by the Apache, because the files under local_content directory do not have any extension. So the mime type will be always some generic, like application/octet-stream. This could be an issue if you embed the Synapse download URLs somewhere, but my web based Element, macOS Electron Element or Android Element app work just fine: I'm able to watch and download video and photos files.

@DMRobertson DMRobertson added P4 (OBSOLETE: use S- labels.) Okay backlog: will not schedule, will accept patches S-Minor Blocks non-critical functionality, workarounds exist. T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues. and removed z-bug (Deprecated Label) z-p2 (Deprecated Label) labels Jan 7, 2022
@ShadowJonathan
Copy link
Contributor

Ive re-tried adding this, following the code in #2909 somewhat.

However, unfortunately, synapse's architecture has become drastically more complicated since 2018, now all calls go to MediaRepository.{get_local_media,get_remote_media}, which then themselves (for integration with third-party media repository modules) call fetch_media, which looks like this;

async def fetch_media(self, file_info: FileInfo) -> Optional[Responder]:

The Responder is supplied with a IConsumer, which is a fancy wrapper for a byte sink, from which the media repo can write the file on its own dime.

This basically delegates the "oh, select the bytes" bit to the media repo.

Changing this to "oh, respond with only this range of bytes" would require a breakage in the media repo API, which might be a tad difficult at the moment.

Some hacks could be implemented where it seeks the first X bytes and then only writes the next Y bytes, discarding the rest, but ultimately that's an ugly hack.

@Cyberes
Copy link
Contributor

Cyberes commented Feb 13, 2023

Alright everyone, I've implemented this into nginx following @wapsi's post. It should emulate the native Synapse media server and supports MIME types (Content-Type) and filenames (Content-Disposition) via fetching them from the database.

https://gist.github.com/Cyberes/4ee247bf78b38aa1073bc5b58c5afdd9

It needs Lua so just use OpenResty. Don't forget to do luarocks install pgmoon

@ShadowJonathan
Copy link
Contributor

FWIW, an MSC exists to try to mandate this on media endpoints: matrix-org/matrix-spec-proposals#3469

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P4 (OBSOLETE: use S- labels.) Okay backlog: will not schedule, will accept patches S-Minor Blocks non-critical functionality, workarounds exist. T-Defect Bugs, crashes, hangs, security vulnerabilities, or other reported issues.
Projects
None yet
Development

No branches or pull requests

6 participants