servie-send
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -40,4 +40,4 @@ /// <reference types="node" /> | ||
/** | ||
* Create an ETag of the payload body. | ||
* Create an entity tag for cache identification. | ||
*/ | ||
export declare function entityTag(body: string | Buffer): string; |
@@ -8,3 +8,3 @@ "use strict"; | ||
const TOKEN_LIST_REGEXP = / *, */; | ||
const ZERO_LENGTH_ENTITY_TAG = createEntityTag(''); | ||
const ZERO_LENGTH_ENTITY_TAG = entityTag(''); | ||
/** | ||
@@ -54,6 +54,8 @@ * Create an empty response. | ||
function send(req, payload, options = {}) { | ||
const headers = servie_1.createHeaders(options.headers); | ||
let statusCode = options.statusCode || 200; | ||
let body = req.method === 'HEAD' ? undefined : node_1.createBody(payload); | ||
if (fresh(req, options.etag, options.mtime)) { | ||
const headers = servie_1.createHeaders(options.headers); | ||
const { mtime, contentType, contentLength, skipEtag } = options; | ||
const etag = options.etag || (skipEtag ? undefined : toEntityTag(payload)); | ||
if (fresh(req, etag, mtime)) { | ||
statusCode = 304; | ||
@@ -63,17 +65,11 @@ body = undefined; | ||
else { | ||
if (options.contentType) | ||
headers.set('Content-Type', options.contentType); | ||
if (options.contentLength) | ||
headers.set('Content-Length', String(options.contentLength)); | ||
if (contentType) | ||
headers.set('Content-Type', contentType); | ||
if (contentLength) | ||
headers.set('Content-Length', String(contentLength)); | ||
} | ||
if (options.mtime) | ||
headers.set('Last-Modified', options.mtime.toUTCString()); | ||
if (options.etag) { | ||
headers.set('ETag', options.etag); | ||
} | ||
else if (!options.skipEtag) { | ||
if (typeof payload === 'string' || Buffer.isBuffer(payload)) { | ||
headers.set('ETag', entityTag(payload)); | ||
} | ||
} | ||
if (etag) | ||
headers.set('ETag', etag); | ||
if (mtime) | ||
headers.set('Last-Modified', mtime.toUTCString()); | ||
return new servie_1.Response({ statusCode, headers, body }); | ||
@@ -83,15 +79,17 @@ } | ||
/** | ||
* Create an ETag of the payload body. | ||
* Create an ETag from the payload body. | ||
*/ | ||
function entityTag(body) { | ||
return body.length === 0 ? ZERO_LENGTH_ENTITY_TAG : createEntityTag(body); | ||
function toEntityTag(body) { | ||
if (typeof body === 'string' || Buffer.isBuffer(body)) { | ||
return body.length === 0 ? ZERO_LENGTH_ENTITY_TAG : entityTag(body); | ||
} | ||
} | ||
exports.entityTag = entityTag; | ||
/** | ||
* Create an entity tag for cache identification. | ||
*/ | ||
function createEntityTag(body) { | ||
function entityTag(body) { | ||
const hash = crypto_1.createHash('sha256').update(body).digest('base64'); | ||
return `"${hash}"`; | ||
} | ||
exports.entityTag = entityTag; | ||
/** | ||
@@ -102,6 +100,6 @@ * Check if a request is fresh. | ||
*/ | ||
function fresh(req, etag, lastModified) { | ||
const noneMatch = req.headers.get('if-none-match'); | ||
const modifiedSince = req.headers.get('if-modified-since'); | ||
if (!noneMatch && !modifiedSince) | ||
function fresh(req, etag, mtime) { | ||
const ifNoneMatch = req.headers.get('if-none-match'); | ||
const ifModifiedSince = req.headers.get('if-modified-since'); | ||
if (!ifNoneMatch && !ifModifiedSince) | ||
return false; | ||
@@ -112,4 +110,4 @@ const cacheControl = req.headers.get('cache-control'); | ||
} | ||
if (noneMatch && etag) { | ||
const isStale = noneMatch.split(TOKEN_LIST_REGEXP).every(match => { | ||
if (ifNoneMatch && etag) { | ||
const isStale = ifNoneMatch.split(TOKEN_LIST_REGEXP).every(match => { | ||
return match !== etag; | ||
@@ -120,4 +118,4 @@ }); | ||
} | ||
if (modifiedSince && lastModified) { | ||
const isStale = lastModified.getTime() > Date.parse(modifiedSince); | ||
if (ifModifiedSince && mtime) { | ||
const isStale = mtime.getTime() > Date.parse(ifModifiedSince); | ||
if (isStale) | ||
@@ -124,0 +122,0 @@ return false; |
@@ -64,3 +64,16 @@ "use strict"; | ||
})); | ||
it('should send 200 with changed etag', () => __awaiter(this, void 0, void 0, function* () { | ||
const req = new servie_1.Request({ | ||
url: '/', | ||
headers: servie_1.createHeaders({ | ||
'If-None-Match': index_1.entityTag('content') | ||
}), | ||
body: node_1.createBody('') | ||
}); | ||
const res = index_1.sendText(req, ''); | ||
expect(res.statusCode).toEqual(200); | ||
expect(res.allHeaders).toMatchSnapshot(); | ||
expect(yield res.body.text()).toEqual(''); | ||
})); | ||
}); | ||
//# sourceMappingURL=index.spec.js.map |
{ | ||
"name": "servie-send", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "Generate a HTTP response with client-side cache support", | ||
@@ -40,12 +40,12 @@ "main": "dist/index.js", | ||
"devDependencies": { | ||
"@types/jest": "^22.2.2", | ||
"@types/node": "^9.6.5", | ||
"jest": "^22.4.3", | ||
"@types/jest": "^23.3.2", | ||
"@types/node": "^10.9.4", | ||
"jest": "^23.6.0", | ||
"rimraf": "^2.5.4", | ||
"servie": "^3.0.0", | ||
"throwback": "^2.0.0", | ||
"ts-jest": "^22.4.2", | ||
"throwback": "^3.0.0", | ||
"ts-jest": "^23.1.4", | ||
"tslint": "^5.9.1", | ||
"tslint-config-standard": "^7.0.0", | ||
"typescript": "^2.8.1" | ||
"tslint-config-standard": "^8.0.1", | ||
"typescript": "^3.0.3" | ||
}, | ||
@@ -52,0 +52,0 @@ "peerDependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25740
238