diff --git a/lib/ecstatic.js b/lib/ecstatic.js index e4e5a5e..4b460f1 100755 --- a/lib/ecstatic.js +++ b/lib/ecstatic.js @@ -141,24 +141,6 @@ var ecstatic = module.exports = function (dir, options) { }); function serve(stat) { - - // TODO: Helper for this, with default headers. - res.setHeader('etag', etag(stat)); - res.setHeader('last-modified', (new Date(stat.mtime)).toUTCString()); - res.setHeader('cache-control', cache); - - // Return a 304 if necessary - if ( req.headers - && ( - (req.headers['if-none-match'] === etag(stat)) - || (new Date(Date.parse(req.headers['if-modified-since'])) >= stat.mtime) - ) - ) { - return status[304](res, next); - } - - 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; @@ -177,6 +159,37 @@ var ecstatic = module.exports = function (dir, options) { contentType = mime.lookup(path.basename(file, ".gz")); } + var range = (req.headers && 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': contentType || 'application/octet-stream' }); + fstream.pipe(res); + return; + } + + // TODO: Helper for this, with default headers. + res.setHeader('etag', etag(stat)); + res.setHeader('last-modified', (new Date(stat.mtime)).toUTCString()); + res.setHeader('cache-control', cache); + + // Return a 304 if necessary + if ( req.headers + && ( + (req.headers['if-none-match'] === etag(stat)) + || (new Date(Date.parse(req.headers['if-modified-since'])) >= stat.mtime) + ) + ) { + return status[304](res, next); + } + + res.setHeader('content-length', stat.size); res.setHeader('content-type', contentType || 'application/octet-stream'); if (req.method === "HEAD") {