Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50650 views
1
/*!
2
* etag
3
* Copyright(c) 2014-2016 Douglas Christopher Wilson
4
* MIT Licensed
5
*/
6
7
'use strict'
8
9
/**
10
* Module exports.
11
* @public
12
*/
13
14
module.exports = etag
15
16
/**
17
* Module dependencies.
18
* @private
19
*/
20
21
var crypto = require('crypto')
22
var Stats = require('fs').Stats
23
24
/**
25
* Module variables.
26
* @private
27
*/
28
29
var base64PadCharRegExp = /=+$/
30
var toString = Object.prototype.toString
31
32
/**
33
* Generate an entity tag.
34
*
35
* @param {Buffer|string} entity
36
* @return {string}
37
* @private
38
*/
39
40
function entitytag (entity) {
41
if (entity.length === 0) {
42
// fast-path empty
43
return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'
44
}
45
46
// compute hash of entity
47
var hash = crypto
48
.createHash('sha1')
49
.update(entity, 'utf8')
50
.digest('base64')
51
.replace(base64PadCharRegExp, '')
52
53
// compute length of entity
54
var len = typeof entity === 'string'
55
? Buffer.byteLength(entity, 'utf8')
56
: entity.length
57
58
return '"' + len.toString(16) + '-' + hash + '"'
59
}
60
61
/**
62
* Create a simple ETag.
63
*
64
* @param {string|Buffer|Stats} entity
65
* @param {object} [options]
66
* @param {boolean} [options.weak]
67
* @return {String}
68
* @public
69
*/
70
71
function etag (entity, options) {
72
if (entity == null) {
73
throw new TypeError('argument entity is required')
74
}
75
76
// support fs.Stats object
77
var isStats = isstats(entity)
78
var weak = options && typeof options.weak === 'boolean'
79
? options.weak
80
: isStats
81
82
// validate argument
83
if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) {
84
throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
85
}
86
87
// generate entity tag
88
var tag = isStats
89
? stattag(entity)
90
: entitytag(entity)
91
92
return weak
93
? 'W/' + tag
94
: tag
95
}
96
97
/**
98
* Determine if object is a Stats object.
99
*
100
* @param {object} obj
101
* @return {boolean}
102
* @api private
103
*/
104
105
function isstats (obj) {
106
// genuine fs.Stats
107
if (typeof Stats === 'function' && obj instanceof Stats) {
108
return true
109
}
110
111
// quack quack
112
return obj && typeof obj === 'object' &&
113
'ctime' in obj && toString.call(obj.ctime) === '[object Date]' &&
114
'mtime' in obj && toString.call(obj.mtime) === '[object Date]' &&
115
'ino' in obj && typeof obj.ino === 'number' &&
116
'size' in obj && typeof obj.size === 'number'
117
}
118
119
/**
120
* Generate a tag for a stat.
121
*
122
* @param {object} stat
123
* @return {string}
124
* @private
125
*/
126
127
function stattag (stat) {
128
var mtime = stat.mtime.getTime().toString(16)
129
var size = stat.size.toString(16)
130
131
return '"' + size + '-' + mtime + '"'
132
}
133
134