-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathindex.js
58 lines (46 loc) · 1.14 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
'use strict'
/**
* Module dependencies.
*/
const calculate = require('etag')
const Stream = require('stream')
const promisify = require('util').promisify
const fs = require('fs')
const stat = promisify(fs.stat)
/**
* Expose `etag`.
*
* Add ETag header field.
* @param {object} [options] see https://github.com/jshttp/etag#options
* @param {boolean} [options.weak]
* @return {Function}
* @api public
*/
module.exports = function etag (options) {
return async function etag (ctx, next) {
await next()
const entity = await getResponseEntity(ctx)
setEtag(ctx, entity, options)
}
}
async function getResponseEntity (ctx) {
// no body
const body = ctx.body
if (!body || ctx.response.get('etag')) return
// type
const status = ctx.status / 100 | 0
// 2xx
if (status !== 2) return
if (body instanceof Stream) {
if (!body.path) return
return await stat(body.path)
} else if ((typeof body === 'string') || Buffer.isBuffer(body)) {
return body
} else {
return JSON.stringify(body)
}
}
function setEtag (ctx, entity, options) {
if (!entity) return
ctx.response.etag = calculate(entity, options)
}