AK-21/Graphite-Industrial-Intelligence
0
1/*!2 * etag3 * Copyright(c) 2014-2016 Douglas Christopher Wilson4 * MIT Licensed5 */6 7'use strict'8 9/**10 * Module exports.11 * @public12 */13 14module.exports = etag15 16/**17 * Module dependencies.18 * @private19 */20 21var crypto = require('crypto')22var Stats = require('fs').Stats23 24/**25 * Module variables.26 * @private27 */28 29var toString = Object.prototype.toString30 31/**32 * Generate an entity tag.33 *34 * @param {Buffer|string} entity35 * @return {string}36 * @private37 */38 39function entitytag (entity) {40 if (entity.length === 0) {41 // fast-path empty42 return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'43 }44 45 // compute hash of entity46 var hash = crypto47 .createHash('sha1')48 .update(entity, 'utf8')49 .digest('base64')50 .substring(0, 27)51 52 // compute length of entity53 var len = typeof entity === 'string'54 ? Buffer.byteLength(entity, 'utf8')55 : entity.length56 57 return '"' + len.toString(16) + '-' + hash + '"'58}59 60/**61 * Create a simple ETag.62 *63 * @param {string|Buffer|Stats} entity64 * @param {object} [options]65 * @param {boolean} [options.weak]66 * @return {String}67 * @public68 */69 70function etag (entity, options) {71 if (entity == null) {72 throw new TypeError('argument entity is required')73 }74 75 // support fs.Stats object76 var isStats = isstats(entity)77 var weak = options && typeof options.weak === 'boolean'78 ? options.weak79 : isStats80 81 // validate argument82 if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) {83 throw new TypeError('argument entity must be string, Buffer, or fs.Stats')84 }85 86 // generate entity tag87 var tag = isStats88 ? stattag(entity)89 : entitytag(entity)90 91 return weak92 ? 'W/' + tag93 : tag94}95 96/**97 * Determine if object is a Stats object.98 *99 * @param {object} obj100 * @return {boolean}101 * @api private102 */103 104function isstats (obj) {105 // genuine fs.Stats106 if (typeof Stats === 'function' && obj instanceof Stats) {107 return true108 }109 110 // quack quack111 return obj && typeof obj === 'object' &&112 'ctime' in obj && toString.call(obj.ctime) === '[object Date]' &&113 'mtime' in obj && toString.call(obj.mtime) === '[object Date]' &&114 'ino' in obj && typeof obj.ino === 'number' &&115 'size' in obj && typeof obj.size === 'number'116}117 118/**119 * Generate a tag for a stat.120 *121 * @param {object} stat122 * @return {string}123 * @private124 */125 126function stattag (stat) {127 var mtime = stat.mtime.getTime().toString(16)128 var size = stat.size.toString(16)129 130 return '"' + size + '-' + mtime + '"'131}132 