Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

statiCache no longer tries to handle range requests, typos, hit uses …

…date header for freshness
  • Loading branch information...
commit 1b5ff2efc07c2daa8ee96045a91115c1023a9ddf 1 parent cbb17fe
@ryanrolds ryanrolds authored tj committed
Showing with 199 additions and 5 deletions.
  1. +6 −5 lib/middleware/staticCache.js
  2. +193 −0 test/staticCache.test.js
View
11 lib/middleware/staticCache.js
@@ -55,6 +55,7 @@ module.exports = function staticCache(options){
return function staticCache(req, res, next){
var path = url.parse(req.url).pathname
+ , ranges = req.headers.range
, hit = cache.get(path)
, hitCC
, uaCC
@@ -71,16 +72,16 @@ module.exports = function staticCache(options){
// ignore larger files
if (!contentLength || contentLength > maxlen) return;
- // done cache items we shouldn't be
+ // dont cache items we shouldn't be
if (cc['no-cache']
|| cc['no-store']
|| cc['private']
|| cc['must-revalidate']) return;
- // iif already in cache then validate
+ // if already in cache then validate
if (hit = cache.get(path)){
if (headers.etag == hit[0].etag) {
- hit.createdAt = new Date;
+ hit[0].date = new Date;
return;
} else {
cache.remove(path);
@@ -105,8 +106,8 @@ module.exports = function staticCache(options){
});
});
- // cache hit
- if (hit && hit.complete) {
+ // cache hit, doesnt support range requests
+ if (hit && hit.complete && !ranges) {
header = utils.merge({}, hit[0]);
header.Age = age = (new Date - hit.createdAt) / 1000 | 0;
header.date = new Date().toUTCString();
View
193 test/staticCache.test.js
@@ -0,0 +1,193 @@
+
+/**
+ * Module dependencies.
+ */
+
+var connect = require('../')
+ , assert = require('assert')
+ , should = require('should')
+ , http = require('http')
+ , create = require('./common').create;
+
+/**
+ * Path to ./test/fixtures/
+ */
+
+var fixturesPath = __dirname + '/fixtures';
+
+var app = create(
+ connect.staticCache(),
+ connect.static(fixturesPath, { maxAge: 60000 })
+);
+
+var app2 = create(
+ connect.staticCache(),
+ connect.static(fixturesPath, { maxAge: 0 })
+);
+
+
+module.exports = {
+
+ 'unconditional request': function() {
+ assert.response(
+ app,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ assert.response(
+ app,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('date');
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ }
+ );
+ }
+ );
+ },
+
+ 'ifnonematch request': function() {
+ assert.response(
+ app,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('etag');
+ assert.response(
+ app,
+ {
+ url: '/user.json',
+ headers: {
+ "If-None-Match": res.headers.etag
+ }
+ },
+ function(res) {
+ res.statusCode.should.equal(304);
+ res.headers.should.have.property('date');
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ }
+ );
+ }
+ );
+ },
+
+ 'old if-none-match request': function() {
+ assert.response(
+ app,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('etag');
+ assert.response(
+ app,
+ { url: '/user.json',
+ headers: {
+ 'If-None-Match': 'foobar'
+ }
+ },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('date');
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ }
+ );
+ }
+ );
+ },
+
+ 'if-modified since request': function() {
+ assert.response(
+ app,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('last-modified');
+ assert.response(
+ app,
+ {
+ url: '/user.json',
+ headers: {
+ 'If-Modified-Since': res.headers['last-modified']
+ }
+ },
+ function(res) {
+ res.statusCode.should.equal(304);
+ res.headers.should.have.property('date');
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ }
+ );
+ }
+ );
+ },
+
+ 'old if-modified-since request': function() {
+ assert.response(
+ app2,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ assert.response(
+ app2,
+ {
+ url: '/user.json',
+ headers: {
+ 'If-Modified-Since': 'Sat, 29 Oct 1994 19:43:31 GMT'
+ }
+ },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('date');
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ }
+ );
+ }
+ );
+ },
+
+ 'no-cache request': function() {
+ assert.response(
+ app,
+ { url: '/user.json' },
+ function(res) {
+ res.statusCode.should.equal(200);
+ res.headers.should.have.property('etag');
+ assert.response(
+ app,
+ {
+ url: '/user.json',
+ headers: {
+ 'Cache-Control': 'no-cache, max-age=0',
+ 'If-None-Match': res.headers.etag
+ }
+ },
+ function(res) {
+ res.statusCode.should.equal(304);
+ res.headers.should.have.property('date');
+ res.headers.should.have.property('last-modified');
+ res.headers.should.have.property('etag');
+ }
+ );
+ }
+ );
+ },
+
+ 'test range request': function(){
+ assert.response(app,
+ { url: '/list' },
+ function(res) {
+ assert.response(app,
+ { url: '/list', headers: { Range: 'bytes=3-6' }},
+ { body: '4567', 'Content-Range': 'bytes 3-6/9', status: 206 });
+ });
+ }
+};
Please sign in to comment.
Something went wrong with that request. Please try again.