opusdev/vector-similarity-api
1
1/*!2 * fresh3 * Copyright(c) 2012 TJ Holowaychuk4 * Copyright(c) 2016-2017 Douglas Christopher Wilson5 * MIT Licensed6 */7 8'use strict'9 10/**11 * RegExp to check for no-cache token in Cache-Control.12 * @private13 */14 15var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/16 17/**18 * Module exports.19 * @public20 */21 22module.exports = fresh23 24/**25 * Check freshness of the response using request and response headers.26 *27 * @param {Object} reqHeaders28 * @param {Object} resHeaders29 * @return {Boolean}30 * @public31 */32 33function fresh (reqHeaders, resHeaders) {34 // fields35 var modifiedSince = reqHeaders['if-modified-since']36 var noneMatch = reqHeaders['if-none-match']37 38 // unconditional request39 if (!modifiedSince && !noneMatch) {40 return false41 }42 43 // Always return stale when Cache-Control: no-cache44 // to support end-to-end reload requests45 // https://tools.ietf.org/html/rfc2616#section-14.9.446 var cacheControl = reqHeaders['cache-control']47 if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {48 return false49 }50 51 // if-none-match52 if (noneMatch && noneMatch !== '*') {53 var etag = resHeaders['etag']54 55 if (!etag) {56 return false57 }58 59 var etagStale = true60 var matches = parseTokenList(noneMatch)61 for (var i = 0; i < matches.length; i++) {62 var match = matches[i]63 if (match === etag || match === 'W/' + etag || 'W/' + match === etag) {64 etagStale = false65 break66 }67 }68 69 if (etagStale) {70 return false71 }72 }73 74 // if-modified-since75 if (modifiedSince) {76 var lastModified = resHeaders['last-modified']77 var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))78 79 if (modifiedStale) {80 return false81 }82 }83 84 return true85}86 87/**88 * Parse an HTTP Date into a number.89 *90 * @param {string} date91 * @private92 */93 94function parseHttpDate (date) {95 var timestamp = date && Date.parse(date)96 97 // istanbul ignore next: guard against date.js Date.parse patching98 return typeof timestamp === 'number'99 ? timestamp100 : NaN101}102 103/**104 * Parse a HTTP token list.105 *106 * @param {string} str107 * @private108 */109 110function parseTokenList (str) {111 var end = 0112 var list = []113 var start = 0114 115 // gather tokens116 for (var i = 0, len = str.length; i < len; i++) {117 switch (str.charCodeAt(i)) {118 case 0x20: /* */119 if (start === end) {120 start = end = i + 1121 }122 break123 case 0x2c: /* , */124 list.push(str.substring(start, end))125 start = end = i + 1126 break127 default:128 end = i + 1129 break130 }131 }132 133 // final token134 list.push(str.substring(start, end))135 136 return list137}138 