Initial commit for OpenECOMP SDN-C OA&M
[sdnc/oam.git] / dgbuilder / dgeflows / node_modules / serve-favicon / node_modules / etag / index.js
diff --git a/dgbuilder/dgeflows/node_modules/serve-favicon/node_modules/etag/index.js b/dgbuilder/dgeflows/node_modules/serve-favicon/node_modules/etag/index.js
new file mode 100644 (file)
index 0000000..bb05eb7
--- /dev/null
@@ -0,0 +1,171 @@
+/*!
+ * etag
+ * Copyright(c) 2014 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+/**
+ * Module exports.
+ */
+
+module.exports = etag
+
+/**
+ * Module dependencies.
+ */
+
+var crc = require('crc').crc32
+var crypto = require('crypto')
+var Stats = require('fs').Stats
+
+/**
+ * Module variables.
+ */
+
+var crc32threshold = 1000 // 1KB
+var NULL = new Buffer([0])
+var toString = Object.prototype.toString
+
+/**
+ * Create a simple ETag.
+ *
+ * @param {string|Buffer|Stats} entity
+ * @param {object} [options]
+ * @param {boolean} [options.weak]
+ * @return {String}
+ * @api public
+ */
+
+function etag(entity, options) {
+  if (entity == null) {
+    throw new TypeError('argument entity is required')
+  }
+
+  var isStats = isstats(entity)
+  var weak = options && typeof options.weak === 'boolean'
+    ? options.weak
+    : isStats
+
+  // support fs.Stats object
+  if (isStats) {
+    return stattag(entity, weak)
+  }
+
+  if (typeof entity !== 'string' && !Buffer.isBuffer(entity)) {
+    throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
+  }
+
+  var hash = weak
+    ? weakhash(entity)
+    : stronghash(entity)
+
+  return weak
+    ? 'W/"' + hash + '"'
+    : '"' + hash + '"'
+}
+
+/**
+ * Determine if object is a Stats object.
+ *
+ * @param {object} obj
+ * @return {boolean}
+ * @api private
+ */
+
+function isstats(obj) {
+  // not even an object
+  if (obj === null || typeof obj !== 'object') {
+    return false
+  }
+
+  // genuine fs.Stats
+  if (obj instanceof Stats) {
+    return true
+  }
+
+  // quack quack
+  return 'atime' in obj && toString.call(obj.atime) === '[object Date]'
+    && 'ctime' in obj && toString.call(obj.ctime) === '[object Date]'
+    && 'mtime' in obj && toString.call(obj.mtime) === '[object Date]'
+    && 'ino' in obj && typeof obj.ino === 'number'
+    && 'size' in obj && typeof obj.size === 'number'
+}
+
+/**
+ * Generate a tag for a stat.
+ *
+ * @param {Buffer} entity
+ * @return {String}
+ * @api private
+ */
+
+function stattag(stat, weak) {
+  var mtime = stat.mtime.toISOString()
+  var size = stat.size.toString(16)
+
+  if (weak) {
+    return 'W/"' + size + '-' + crc(mtime) + '"'
+  }
+
+  var hash = crypto
+    .createHash('md5')
+    .update('file', 'utf8')
+    .update(NULL)
+    .update(size, 'utf8')
+    .update(NULL)
+    .update(mtime, 'utf8')
+    .digest('base64')
+
+  return '"' + hash + '"'
+}
+
+/**
+ * Generate a strong hash.
+ *
+ * @param {Buffer} entity
+ * @return {String}
+ * @api private
+ */
+
+function stronghash(entity) {
+  if (entity.length === 0) {
+    // fast-path empty
+    return '1B2M2Y8AsgTpgAmY7PhCfg=='
+  }
+
+  return crypto
+    .createHash('md5')
+    .update(entity, 'utf8')
+    .digest('base64')
+}
+
+/**
+ * Generate a weak hash.
+ *
+ * @param {Buffer} entity
+ * @return {String}
+ * @api private
+ */
+
+function weakhash(entity) {
+  if (entity.length === 0) {
+    // fast-path empty
+    return '0-0'
+  }
+
+  var len = typeof entity === 'string'
+    ? Buffer.byteLength(entity, 'utf8')
+    : entity.length
+
+  if (len <= crc32threshold) {
+    // crc32 plus length when it's fast
+    // crc(str) only accepts utf-8 encoding
+    return len.toString(16) + '-' + crc(entity).toString(16)
+  }
+
+  // use md4 for long strings
+  return crypto
+    .createHash('md4')
+    .update(entity, 'utf8')
+    .digest('base64')
+}