Comparing version 14.1.0 to 14.2.0
@@ -48,7 +48,7 @@ 'use strict'; | ||
if (!result._takeover) { | ||
return next(); | ||
if (result._takeover) { | ||
return callback(null, result); | ||
} | ||
return callback(null, result); | ||
return next(); | ||
}); | ||
@@ -55,0 +55,0 @@ }, nextSet); |
@@ -79,8 +79,9 @@ 'use strict'; | ||
reply.response = internals.response; | ||
reply.close = internals.close; | ||
reply.continue = internals.continue; | ||
reply.state = internals.state; | ||
reply.unstate = internals.unstate; | ||
reply.redirect = internals.redirect; | ||
reply.continue = internals.continue; | ||
reply.response = internals.response; | ||
reply.entity = internals.entity; | ||
@@ -176,1 +177,16 @@ if (this._decorations) { | ||
}; | ||
internals.entity = function (options) { | ||
Hoek.assert(options, 'Entity method missing required options'); | ||
Hoek.assert(options.etag || options.modified, 'Entity methods missing require options key'); | ||
this.request._entity = options; | ||
if (Response.unmodified(this.request, options)) { | ||
return this.response().code(304).takeover(); | ||
} | ||
return null; | ||
}; |
@@ -146,2 +146,3 @@ 'use strict'; | ||
this._states = {}; | ||
this._entity = {}; // Entity information set via reply.entity() | ||
this._logger = []; | ||
@@ -148,0 +149,0 @@ this._allowInternals = !!options.allowInternals; |
@@ -201,2 +201,66 @@ 'use strict'; | ||
internals.Response.unmodified = function (request, options) { | ||
if (request.method !== 'get' && | ||
request.method !== 'head') { | ||
return false; | ||
} | ||
// Strong verifier | ||
if (options.etag && | ||
request.headers['if-none-match']) { | ||
const ifNoneMatch = request.headers['if-none-match'].split(/\s*,\s*/); | ||
for (let i = 0; i < ifNoneMatch.length; ++i) { | ||
const etag = ifNoneMatch[i]; | ||
if (etag === options.etag) { | ||
return true; | ||
} | ||
if (options.vary) { | ||
const etagBase = options.etag.slice(0, -1); | ||
if (etag === etagBase + '-gzip"' || | ||
etag === etagBase + '-deflate"') { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
// Weak verifier | ||
const ifModifiedSinceHeader = request.headers['if-modified-since']; | ||
if (ifModifiedSinceHeader && | ||
options.modified) { | ||
const ifModifiedSince = internals.parseDate(ifModifiedSinceHeader); | ||
const lastModified = internals.parseDate(options.modified); | ||
if (ifModifiedSince && | ||
lastModified && | ||
ifModifiedSince >= lastModified) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
internals.parseDate = function (string) { | ||
try { | ||
return Date.parse(string); | ||
} | ||
catch (errIgnore) { } | ||
}; | ||
internals.Response.prototype.type = function (type) { | ||
@@ -203,0 +267,0 @@ |
@@ -57,51 +57,4 @@ 'use strict'; | ||
internals.security(response); | ||
internals.unmodified(response); | ||
if (response.statusCode !== 304 && | ||
(request.method === 'get' || request.method === 'head')) { | ||
if (response.headers.etag && | ||
request.headers['if-none-match']) { | ||
// Strong verifier | ||
const ifNoneMatch = request.headers['if-none-match'].split(/\s*,\s*/); | ||
for (let i = 0; i < ifNoneMatch.length; ++i) { | ||
const etag = ifNoneMatch[i]; | ||
if (etag === response.headers.etag) { | ||
response.code(304); | ||
break; | ||
} | ||
else if (response.settings.varyEtag) { | ||
const etagBase = response.headers.etag.slice(0, -1); | ||
if (etag === etagBase + '-gzip"' || | ||
etag === etagBase + '-deflate"') { | ||
response.code(304); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
else { | ||
const ifModifiedSinceHeader = request.headers['if-modified-since']; | ||
const lastModifiedHeader = response.headers['last-modified']; | ||
if (ifModifiedSinceHeader && | ||
lastModifiedHeader) { | ||
// Weak verifier | ||
const ifModifiedSince = internals.parseDate(ifModifiedSinceHeader); | ||
const lastModified = internals.parseDate(lastModifiedHeader); | ||
if (ifModifiedSince && | ||
lastModified && | ||
ifModifiedSince >= lastModified) { | ||
response.code(304); | ||
} | ||
} | ||
} | ||
} | ||
internals.state(response, (err) => { | ||
@@ -160,11 +113,2 @@ | ||
internals.parseDate = function (string) { | ||
try { | ||
return Date.parse(string); | ||
} | ||
catch (errIgnore) { } | ||
}; | ||
internals.fail = function (request, boom, callback) { | ||
@@ -570,1 +514,35 @@ | ||
}; | ||
internals.unmodified = function (response) { | ||
const request = response.request; | ||
// Set headers from reply.entity() | ||
if (request._entity.etag && | ||
!response.headers.etag) { | ||
response.etag(request._entity.etag, { vary: request._entity.vary }); | ||
} | ||
if (request._entity.modified && | ||
!response.headers['last-modified']) { | ||
response.header('last-modified', request._entity.modified); | ||
} | ||
if (response.statusCode === 304) { | ||
return; | ||
} | ||
const entity = { | ||
etag: response.headers.etag, | ||
vary: response.settings.varyEtag, | ||
modified: response.headers['last-modified'] | ||
}; | ||
if (Response.unmodified(request, entity)) { | ||
response.code(304); | ||
} | ||
}; |
@@ -5,3 +5,3 @@ { | ||
"homepage": "http://hapijs.com", | ||
"version": "14.1.0", | ||
"version": "14.2.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -15,3 +15,3 @@ <img src="https://raw.github.com/hapijs/hapi/master/images/hapi.png" /> | ||
Development version: **14.0.x** ([release notes](https://github.com/hapijs/hapi/issues?labels=release+notes&page=1&state=closed)) | ||
Development version: **14.2.x** ([release notes](https://github.com/hapijs/hapi/issues?labels=release+notes&page=1&state=closed)) | ||
[![Build Status](https://secure.travis-ci.org/hapijs/hapi.svg?branch=master)](http://travis-ci.org/hapijs/hapi) | ||
@@ -18,0 +18,0 @@ |
171931
4234