ring-clojure / ring

Clojure HTTP server abstraction
MIT License
3.75k stars 519 forks source link

Range header not respected when serving files #423

Closed patosai closed 3 years ago

patosai commented 3 years ago

edit: I ended up making a package for this:

I came across an issue where the ring server was serving mp4 files, but Safari likes to stream the video in small parts using the Range header. Header looks something like Range: bytes=0-1

It doesn't seem that ring supports this. Should this function be modified? https://github.com/ring-clojure/ring/blob/ae6a42108286ca95f33e2d9d6f33172ae7233730/ring-core/src/ring/util/response.clj#L148-L163

weavejester commented 3 years ago

I'd welcome a patch to add support for Range, though as middleware, rather than a modification of file-response, as Range can be useful for any 200 OK response. My guess is that this is going to be reasonably complex, as it needs to deal with a number of different scenaros.

However, it's worth noting that Range is an optional header, and may be safely ignored by the server, though obviously that may mean the server is sending more data than necessary.

sova commented 3 years ago

Humorous, I just ran into this problem myself =) Yes, apparently WebKit (iOS mobile) requires these three (3) headers for HTML5 audio to have a seek bar rather than say "Live Broadcast":

Accept-Ranges:bytes Content-Length:7437847 Content-Range:bytes 0-7437846/7437847

Using java.io as io you can have something such as file-size-in-bytes (.length (io/file -filename-)) and the header can be something like "Content-Range" (str "bytes 0-" (dec file-size-in-bytes) "/" file-size-in-bytes)

I'm testing this now, hopefully it will work as expected.

It would be nice if WebKit respected the "optional" part of Content-Range, especially because it's clearly discernible when one knows the Content-Length, but I can't argue with them over BugZilla all day.

sova commented 3 years ago

@patosai please use absolute file name instead of relative file name in the audio element source https://stackoverflow.com/a/43133607/440887 Hopefully that fixes the issue for you (don't ask me why :D)

patosai commented 3 years ago

I eventually hosted the file on Cloudfront and because that implements the Range header, it ended up working. I'm working on a pull request for this.