Skip to content

Commit

Permalink
Merge pull request #258 from wpreul/feature/files
Browse files Browse the repository at this point in the history
Adding support for etag and last-modified headers
  • Loading branch information
Eran Hammer committed Nov 20, 2012
2 parents 5a8f703 + ace9888 commit 24e10df
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
1 change: 1 addition & 0 deletions lib/response/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ internals.File.prototype._prepare = function (callback) {
self.headers['Content-Type'] = Mime.lookup(self._filePath) || 'application/octet-stream';
self.headers['Content-Length'] = stat.size;
self.headers['Last-Modified'] = new Date(stat.mtime).toUTCString();
self.headers.etag = JSON.stringify([stat.ino, stat.size, Date.parse(stat.mtime)].join('-'));

return callback(self);
});
Expand Down
16 changes: 16 additions & 0 deletions lib/response/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,22 @@ exports._respond = function (item, request, callback) {
response = new internals.Error(errOptions);
}


if (request.method === 'get' || request.method === 'head') {
// Process ETag and If-Modified-Since headers

var ifModifiedSince = request.raw.req.headers['if-modified-since'] ? Date.parse(request.raw.req.headers['if-modified-since']) : null;
var lastModified = response.headers && response.headers['Last-Modified'] ? Date.parse(response.headers['Last-Modified']) : null;
var etag = response.headers ? response.headers.etag : null;

if ((etag && request.raw.req.headers['if-none-match'] === etag) ||
(ifModifiedSince && lastModified && ifModifiedSince >= lastModified)) {

response = new internals.Empty();
response._code = 304;
}
}

// Set Cache, CORS, Location headers

Headers.set(response, request);
Expand Down
54 changes: 45 additions & 9 deletions test/integration/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ describe('Response', function () {
{ method: 'GET', path: '/direct', config: { handler: directHandler, cache: { mode: 'client', expiresIn: 9999 } } },
{ method: 'POST', path: '/exp', handler: expHandler },
{ method: 'POST', path: '/stream/{issue?}', handler: streamHandler },
{ method: 'POST', path: '/file', handler: fileHandler },
{ method: 'POST', path: '/relativefile', handler: relativeFileHandler },
{ method: 'POST', path: '/filenotfound', handler: fileNotFoundHandler },
{ method: 'POST', path: '/staticfile', handler: { file: __dirname + '/../../package.json' } },
{ method: 'POST', path: '/relativestaticfile', handler: { file: './package.json' } },
{ method: 'GET', path: '/file', handler: fileHandler },
{ method: 'GET', path: '/relativefile', handler: relativeFileHandler },
{ method: 'GET', path: '/filenotfound', handler: fileNotFoundHandler },
{ method: 'GET', path: '/staticfile', handler: { file: __dirname + '/../../package.json' } },
{ method: 'GET', path: '/relativestaticfile', handler: { file: './package.json' } },
{ method: 'GET', path: '/cache', config: { handler: cacheHandler, cache: { expiresIn: 5000 } } }
]);

Expand Down Expand Up @@ -280,7 +280,7 @@ describe('Response', function () {

server.start(function () {

Request.post('http://localhost:17082/file', function (err, res, body) {
Request.get('http://localhost:17082/file', function (err, res, body) {

expect(err).to.not.exist;
expect(body).to.contain('hapi');
Expand All @@ -306,7 +306,7 @@ describe('Response', function () {

it('returns a file using the built-in handler config', function (done) {

Request.post('http://localhost:17082/staticfile', function (err, res, body) {
Request.get('http://localhost:17082/staticfile', function (err, res, body) {

expect(err).to.not.exist;
expect(body).to.contain('hapi');
Expand All @@ -322,7 +322,7 @@ describe('Response', function () {

server.start(function () {

Request.post('http://localhost:17082/relativefile', function (err, res, body) {
Request.get('http://localhost:17082/relativefile', function (err, res, body) {

expect(err).to.not.exist;
expect(body).to.contain('hapi');
Expand All @@ -335,7 +335,7 @@ describe('Response', function () {

it('returns a file using the built-in handler config', function (done) {

Request.post('http://localhost:17082/relativestaticfile', function (err, res, body) {
Request.get('http://localhost:17082/relativestaticfile', function (err, res, body) {

expect(err).to.not.exist;
expect(body).to.contain('hapi');
Expand All @@ -345,5 +345,41 @@ describe('Response', function () {
});
});
});

it('returns a 304 when the request has a matching etag', function (done) {

server.start(function () {

Request.get('http://localhost:17082/file', function (err, res1) {

var headers = {
'if-none-match': res1.headers.etag
};

Request.get({ url: 'http://localhost:17082/file', headers: headers }, function (err, res2) {

expect(res2.statusCode).to.equal(304);
done();
});
});
});
});

it('returns a 304 when the request has a future modifed-since', function (done) {

server.start(function () {

var date = new Date(Date.now());
var headers = {
'if-modified-since': new Date(date.setFullYear(date.getFullYear() + 1)).toUTCString()
};

Request.get({ url: 'http://localhost:17082/file', headers: headers }, function (err, res) {

expect(res.statusCode).to.equal(304);
done();
});
});
});
});
});

0 comments on commit 24e10df

Please sign in to comment.