From 6c26f8eb2291830e125973cb7596cf42d41e3fea Mon Sep 17 00:00:00 2001 From: choonkeat Date: Mon, 30 Dec 2013 02:30:57 +0800 Subject: [PATCH 1/3] Implements #8 content-range using code from streamer.js --- lib/ecstatic.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/ecstatic.js b/lib/ecstatic.js index e4e5a5e..25d4616 100755 --- a/lib/ecstatic.js +++ b/lib/ecstatic.js @@ -141,6 +141,20 @@ var ecstatic = module.exports = function (dir, options) { }); function serve(stat) { + var range = req.headers['range']; + if (range) { + var total = stat.size; + var parts = range.replace(/bytes=/, "").split("-"); + var partialstart = parts[0]; + var partialend = parts[1]; + var start = parseInt(partialstart, 10); + var end = partialend ? parseInt(partialend, 10) : total-1; + var chunksize = (end-start)+1; + var fstream = fs.createReadStream(file, {start: start, end: end}); + res.writeHead(206, { 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4' }); + fstream.pipe(res); + return; + } // TODO: Helper for this, with default headers. res.setHeader('etag', etag(stat)); From 3fd073772716c2e86cb68a9262aba28722c30a6e Mon Sep 17 00:00:00 2001 From: choonkeat Date: Mon, 30 Dec 2013 02:40:21 +0800 Subject: [PATCH 2/3] re-order lookup of "contentType"; use that value when streaming --- lib/ecstatic.js | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/ecstatic.js b/lib/ecstatic.js index 25d4616..505eee6 100755 --- a/lib/ecstatic.js +++ b/lib/ecstatic.js @@ -141,6 +141,24 @@ var ecstatic = module.exports = function (dir, options) { }); function serve(stat) { + // Do a MIME lookup, fall back to octet-stream and handle gzip + // special case. + var contentType = mime.lookup(file), charSet; + + if (contentType) { + charSet = mime.charsets.lookup(contentType, 'utf-8'); + if (charSet) { + contentType += '; charset=' + charSet; + } + } + + if (path.extname(file) === '.gz') { + res.setHeader('Content-Encoding', 'gzip'); + + // strip gz ending and lookup mime type + contentType = mime.lookup(path.basename(file, ".gz")); + } + var range = req.headers['range']; if (range) { var total = stat.size; @@ -151,7 +169,7 @@ var ecstatic = module.exports = function (dir, options) { var end = partialend ? parseInt(partialend, 10) : total-1; var chunksize = (end-start)+1; var fstream = fs.createReadStream(file, {start: start, end: end}); - res.writeHead(206, { 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4' }); + res.writeHead(206, { 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': contentType || 'application/octet-stream' }); fstream.pipe(res); return; } @@ -172,25 +190,6 @@ var ecstatic = module.exports = function (dir, options) { } res.setHeader('content-length', stat.size); - - // Do a MIME lookup, fall back to octet-stream and handle gzip - // special case. - var contentType = mime.lookup(file), charSet; - - if (contentType) { - charSet = mime.charsets.lookup(contentType, 'utf-8'); - if (charSet) { - contentType += '; charset=' + charSet; - } - } - - if (path.extname(file) === '.gz') { - res.setHeader('Content-Encoding', 'gzip'); - - // strip gz ending and lookup mime type - contentType = mime.lookup(path.basename(file, ".gz")); - } - res.setHeader('content-type', contentType || 'application/octet-stream'); if (req.method === "HEAD") { From 49c02d2d23497b0f7a18763955655732a76c8e02 Mon Sep 17 00:00:00 2001 From: choonkeat Date: Mon, 30 Dec 2013 10:16:22 +0800 Subject: [PATCH 3/3] Fixes TypeError: Cannot read property 'range' of undefined --- lib/ecstatic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ecstatic.js b/lib/ecstatic.js index 505eee6..4b460f1 100755 --- a/lib/ecstatic.js +++ b/lib/ecstatic.js @@ -159,7 +159,7 @@ var ecstatic = module.exports = function (dir, options) { contentType = mime.lookup(path.basename(file, ".gz")); } - var range = req.headers['range']; + var range = (req.headers && req.headers['range']); if (range) { var total = stat.size; var parts = range.replace(/bytes=/, "").split("-");