Permalink
Browse files

Add Range support.

  • Loading branch information...
1 parent 36945b2 commit 3e32d792e3633be38125a0549f5ebbecffc4f3fd @JacksonTian committed Nov 11, 2011
Showing with 58 additions and 12 deletions.
  1. +32 −11 app.js
  2. +1 −1 assets/index.html
  3. +25 −0 utils.js
View
43 app.js
@@ -5,10 +5,12 @@ var fs = require("fs");
var path = require("path");
var mime = require("./mime").types;
var config = require("./config");
+var utils = require("./utils");
var zlib = require("zlib");
var server = http.createServer(function(request, response) {
response.setHeader("Server", "Node/V5");
+ response.setHeader('Accept-Ranges', 'bytes');
var pathname = url.parse(request.url).pathname;console.log(pathname);
if (pathname.slice(-1) === "/") {
pathname = pathname + config.Welcome.file;
@@ -30,6 +32,7 @@ var server = http.createServer(function(request, response) {
ext = ext ? ext.slice(1) : 'unknown';
var contentType = mime[ext] || "text/plain";
response.setHeader("Content-Type", contentType);
+ response.setHeader('Content-Length', stats.size);
var lastModified = stats.mtime.toUTCString();
var ifModifiedSince = "If-Modified-Since".toLowerCase();
@@ -46,19 +49,37 @@ var server = http.createServer(function(request, response) {
response.writeHead(304, "Not Modified");
response.end();
} else {
- var raw = fs.createReadStream(realPath);
- var acceptEncoding = request.headers['accept-encoding'] || "";
- var matched = ext.match(config.Compress.match);
+ var compressHandle = function (raw, statusCode, reasonPhrase) {
+ var stream = raw;
+ var acceptEncoding = request.headers['accept-encoding'] || "";
+ var matched = ext.match(config.Compress.match);
- if (matched && acceptEncoding.match(/\bgzip\b/)) {
- response.writeHead(200, "Ok", {'Content-Encoding': 'gzip'});
- raw.pipe(zlib.createGzip()).pipe(response);
- } else if (matched && acceptEncoding.match(/\bdeflate\b/)) {
- response.writeHead(200, "Ok", {'Content-Encoding': 'deflate'});
- raw.pipe(zlib.createDeflate()).pipe(response);
+ if (matched && acceptEncoding.match(/\bgzip\b/)) {
+ response.setHeader("Content-Encoding", "gzip");
+ stream = raw.pipe(zlib.createGzip());
+ } else if (matched && acceptEncoding.match(/\bdeflate\b/)) {
+ response.setHeader("Content-Encoding", "deflate");
+ stream = raw.pipe(zlib.createDeflate());
+ }
+ response.writeHead(statusCode, reasonPhrase);
+ stream.pipe(response);
+ };
+
+ if (request.headers["range"]) {
+ var range = utils.parseRange(request.headers["range"], stats.size);
+ if (range) {
+ response.setHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + stats.size);
+ response.setHeader("Content-Length", (range.end - range.start + 1));
+ var raw = fs.createReadStream(realPath, {"start": range.start, "end": range.end});
+ compressHandle(raw, 206, "Partial Content");
+ } else {
+ response.removeHeader("Content-Length");
+ response.writeHead(416, "Request Range Not Satisfiable");
+ response.end();
+ }
} else {
- response.writeHead(200, "Ok");
- raw.pipe(response);
+ var raw = fs.createReadStream(realPath);
+ compressHandle(raw, 200, "Ok");
}
}
}
View
@@ -2,4 +2,4 @@
<body>
<h1>It works!</h1>
</body>
-</html>
+</html>
View
@@ -0,0 +1,25 @@
+exports.parseRange = function (str, size) {
+ if (str.indexOf(",") != -1) {
+ return;
+ }
+
+ var range = str.split("-"),
+ start = parseInt(range[0], 10),
+ end = parseInt(range[1], 10);
+
+ // Case: -100
+ if (isNaN(start)) {
+ start = size - end;
+ end = size - 1;
+ // Case: 100-
+ } else if (isNaN(end)) {
+ end = size - 1;
+ }
+
+ // Invalid
+ if (isNaN(start) || isNaN(end) || start > end || end > size) {
+ return;
+ }
+
+ return {start: start, end: end};
+};

0 comments on commit 3e32d79

Please sign in to comment.