Skip to content
This repository has been archived by the owner on Oct 13, 2018. It is now read-only.

Commit

Permalink
Added conditional get support for client script middleware
Browse files Browse the repository at this point in the history
 * The client script is now served conditionnaly based on the request
   headers. This means that if the browser sends a conditional request
   and the current body is fresh, we send a not modified response. Otherwise,
   we send the request as usual.
  • Loading branch information
Matthieu Vachon committed Jun 10, 2015
1 parent 06e284c commit 20582f3
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 18 deletions.
56 changes: 40 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
"use strict";

var fs = require("fs");
var path = require("path");
var etag = require("etag")
var fresh = require("fresh")
var fs = require("fs");
var path = require("path");

var script = path.resolve(__dirname + "/dist/index.min.js");
var minifiedScript = path.resolve(__dirname + "/dist/index.min.js");
var unminifiedScript = path.resolve(__dirname + "/dist/index.js");

function init(options, connector, type) {

var result;

if (options && options.minify) {
result = fs.readFileSync(script);
} else {
script = path.resolve(__dirname + "/dist/index.js");
result = fs.readFileSync(script);
}
function headers(res, body){
res.setHeader("Cache-Control", "public, max-age=0");
res.setHeader("Content-Type", "text/javascript");
res.setHeader("ETag", etag(body));
};

function body(options, connector) {
var script = minifiedScript;
if (options && !options.minify) {
script = unminifiedScript;
}

return connector + fs.readFileSync(script);
}

function isConditionalGet(req) {
return req.headers["if-none-match"] || req.headers["if-modified-since"];
}

function notModified(res) {
res.removeHeader("Content-Type");
res.statusCode = 304;
res.end();
}

function init(options, connector, type) {
var requestBody = body(options, connector);
if (type && type === "file") {
return connector + result;
return requestBody;
}

return function (req, res) {
res.setHeader("Content-Type", "text/javascript");
res.end(connector + result);
headers(res, requestBody);

if (isConditionalGet(req) && fresh(req.headers, res._headers)) {
return notModified(res);
}

res.end(requestBody);
};
}

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@
"vinyl-source-stream": "^1.1.0"
},
"keywords": [],
"dependencies": {}
"dependencies": {
"etag": "^1.7.0",
"fresh": "^0.3.0"
}
}
39 changes: 38 additions & 1 deletion test/middleware/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,47 @@ describe("Using the middleware", function () {
assert.isFunction(index.middleware);
});

it("should return the JS", function (done) {
it("should return the JS when no cache", function (done) {
request(app)
.get("/client")
.expect("Content-Type", /text\/javascript/)
.expect("Cache-Control", "public, max-age=0")
.expect("ETag", /".*-.*"/)
.expect(200)
.end(function (err, res) {
assert.isTrue(res.text.length > 0);
assert.isTrue(res.text.indexOf("BEFORE") > -1);
done();
});
});

it("should return not modified if has cache and fresh", function (done) {
var etag = null;
request(app)
.get("/client")
.end(function (err, res) {
etag = res.headers["ETag"];
});

request(app)
.get("/client")
.set("If-None-Match", etag)
.expect("Cache-Control", "public, max-age=0")
.expect("ETag", /".*-.*"/)
.expect(304)
.end(function (err, res) {
assert.isUndefined(res.headers["Content-Type"]);
done();
});
});

it("should return the JS if has cache and not fresh", function (done) {
request(app)
.get("/client")
.set("If-None-Match", "Different-ETag")
.expect("Content-Type", /text\/javascript/)
.expect("Cache-Control", "public, max-age=0")
.expect("ETag", /".*-.*"/)
.expect(200)
.end(function (err, res) {
assert.isTrue(res.text.length > 0);
Expand Down

0 comments on commit 20582f3

Please sign in to comment.