I’m trying to serve the iPhone a video file from my controller using
send_file. However, it appears as thought the iPhone requires byte-
range request support and rails doesn’t seem to support this.
If I give the iPhone a url that points to an actual file (i.e. it’s
served by my webserver nginx, instead of rails) it downloads and plays
it fine.
Here is the proof (from the iphone docs):
This byte-range request should only return 100 bytes from the video:
curl --range 0-99 http://test.com/7_7.3g2 -o /dev/null
% Total % Received % Xferd Average Speed Time Time
Time Current
Dload Upload Total Spent
Left Speed
0 100 0 100 0 0 49 0 --:–:-- 0:00:02
–:–:-- 97
As you can see it does, i.e. byte-range support. Now lets try the same
thing on my controller:
curl --range 0-50 http://test.com/play_video -o /dev/null
% Total % Received % Xferd Average Speed Time Time
Time Current
Dload Upload Total Spent
Left Speed
100 261k 100 261k 0 0 44310 0 0:00:06 0:00:06
–:–:-- 68172
As you can see it downloaded the entire file, i.e. no byte-range
request.
Any idea how I can get around this issue, because I really need to be
able to server the file via my controller.
Any idea how I can get around this issue, because I really need to be
able to server the file via my controller.
Well you need to do 2 things: extract the desired range, for which I
imagine you could get from poking around with the environment
ActionController sets up for you.
Secondly send_file would have to support sending a range of data,
which it currently doesn’t. However the source to send_file isn’t
complicated. It shouldn’t be hard to add this.
The fix is to the X-Sendfile or X-Accel-Redirect for apache/ighthttp
or nginx respectively.
Definitely… You don’t want to do this in Rails because a)
apache/lighttpd/nginx are tuned for this, b) mongrel buffers responses
from rails, so this could eat up some memory, and c) longer responses
can lock the mongrel process from responding to other rails requests.