| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- '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)
- }
|