Permalink
Browse files

Add support for Range requests (needed to get HTML5 videos in chrome …

…to seek and loop)
  • Loading branch information...
1 parent 479560a commit c190d3ba61911b00e6b385bf1d1fafb238a3c87d @afri afri committed Mar 3, 2012
Showing with 39 additions and 6 deletions.
  1. +1 −0 rocket-modules/main.sjs
  2. +38 −6 rocket-modules/serverfs.sjs
View
@@ -115,6 +115,7 @@ BaseFileFormatMap.prototype = {
xml : { none : { mime: "text/xml" },
src : { mime: "text/plain" }
},
+ mp4 : { none : { mime: "video/mp4" } },
svg : { none : { mime: "image/svg+xml" } },
txt : { none : { mime: "text/plain" } },
"*" : { none : { /* serve without mimetype */ }
@@ -137,7 +137,7 @@ function listDirectory(request, response, root, branch, format, formats) {
}
var listingJson = JSON.stringify(listing);
return formatResponse(
- { input: new stream.ReadableStringStream(listingJson),
+ { input: function() { return new stream.ReadableStringStream(listingJson) },
extension: "/",
requestedFormat: format,
defaultFormats: defaultDirectoryListingFormats
@@ -218,23 +218,55 @@ function formatResponse(item, request, response, formats) {
}
var contentHeader = formatdesc.mime ? {"Content-Type":formatdesc.mime} : {};
- response.writeHead(200, contentHeader);
if(formatdesc.filter) {
- formatdesc.filter(input, response, request);
+ response.writeHead(200, contentHeader);
+ formatdesc.filter(input(), response, request);
} else {
- stream.pump(input, response);
+ if (item.length) {
+ contentHeader["Content-Length"] = item.length;
+ contentHeader["Accept-Ranges"] = "bytes";
+ }
+ var range;
+ if (item.length && request.headers["range"] &&
+ (range=/^bytes=(\d*)-(\d*)$/.exec(request.headers["range"]))) {
+ // we honor simple range requests
+ var from = range[1] ? parseInt(range[1]) : 0;
+ var to = range[2] ? parseInt(range[2]) : item.length-1;
+ to = Math.min(to, item.length-1);
+ if (isNaN(from) || isNaN(to) || from<0 || to<from)
+ response.writeHead(416); // range not satisfiable
+ else {
+ contentHeader["Content-Length"] = (to-from+1);
+ contentHeader["Content-Range"] = "bytes "+from+"-"+to+"/"+item.length;
+ response.writeHead(206, contentHeader);
+ stream.pump(input({start:from, end:to}), response);
+ }
+ }
+ else {
+ // normal request
+ response.writeHead(200, contentHeader);
+ stream.pump(input(), response);
+ }
}
response.end();
return true;
};
// attempts to serve the file; returns 'false' if not found
function serveFile(request, response, filePath, format, formats) {
- if (!fs.isFile(filePath)) return false;
+ try {
+ var stat = fs.stat(filePath);
+ }
+ catch (e) {
+ return false;
+ }
+ if (!stat.isFile()) return false;
var ext = path.extname(filePath).slice(1);
return formatResponse(
- { input: require('fs').createReadStream(filePath),
+ { input: function(opts) {
+ return require('fs').createReadStream(filePath, opts) },
+ length: stat.size,
extension: ext,
requestedFormat: format
},

0 comments on commit c190d3b

Please sign in to comment.