| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 | 
							- /*!
 
-  * fresh
 
-  * Copyright(c) 2012 TJ Holowaychuk
 
-  * Copyright(c) 2016-2017 Douglas Christopher Wilson
 
-  * MIT Licensed
 
-  */
 
- 'use strict'
 
- /**
 
-  * RegExp to check for no-cache token in Cache-Control.
 
-  * @private
 
-  */
 
- var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/
 
- /**
 
-  * Module exports.
 
-  * @public
 
-  */
 
- module.exports = fresh
 
- /**
 
-  * Check freshness of the response using request and response headers.
 
-  *
 
-  * @param {Object} reqHeaders
 
-  * @param {Object} resHeaders
 
-  * @return {Boolean}
 
-  * @public
 
-  */
 
- function fresh (reqHeaders, resHeaders) {
 
-   // fields
 
-   var modifiedSince = reqHeaders['if-modified-since']
 
-   var noneMatch = reqHeaders['if-none-match']
 
-   // unconditional request
 
-   if (!modifiedSince && !noneMatch) {
 
-     return false
 
-   }
 
-   // Always return stale when Cache-Control: no-cache
 
-   // to support end-to-end reload requests
 
-   // https://tools.ietf.org/html/rfc2616#section-14.9.4
 
-   var cacheControl = reqHeaders['cache-control']
 
-   if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {
 
-     return false
 
-   }
 
-   // if-none-match
 
-   if (noneMatch && noneMatch !== '*') {
 
-     var etag = resHeaders['etag']
 
-     if (!etag) {
 
-       return false
 
-     }
 
-     var etagStale = true
 
-     var matches = parseTokenList(noneMatch)
 
-     for (var i = 0; i < matches.length; i++) {
 
-       var match = matches[i]
 
-       if (match === etag || match === 'W/' + etag || 'W/' + match === etag) {
 
-         etagStale = false
 
-         break
 
-       }
 
-     }
 
-     if (etagStale) {
 
-       return false
 
-     }
 
-   }
 
-   // if-modified-since
 
-   if (modifiedSince) {
 
-     var lastModified = resHeaders['last-modified']
 
-     var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))
 
-     if (modifiedStale) {
 
-       return false
 
-     }
 
-   }
 
-   return true
 
- }
 
- /**
 
-  * Parse an HTTP Date into a number.
 
-  *
 
-  * @param {string} date
 
-  * @private
 
-  */
 
- function parseHttpDate (date) {
 
-   var timestamp = date && Date.parse(date)
 
-   // istanbul ignore next: guard against date.js Date.parse patching
 
-   return typeof timestamp === 'number'
 
-     ? timestamp
 
-     : NaN
 
- }
 
- /**
 
-  * Parse a HTTP token list.
 
-  *
 
-  * @param {string} str
 
-  * @private
 
-  */
 
- function parseTokenList (str) {
 
-   var end = 0
 
-   var list = []
 
-   var start = 0
 
-   // gather tokens
 
-   for (var i = 0, len = str.length; i < len; i++) {
 
-     switch (str.charCodeAt(i)) {
 
-       case 0x20: /*   */
 
-         if (start === end) {
 
-           start = end = i + 1
 
-         }
 
-         break
 
-       case 0x2c: /* , */
 
-         list.push(str.substring(start, end))
 
-         start = end = i + 1
 
-         break
 
-       default:
 
-         end = i + 1
 
-         break
 
-     }
 
-   }
 
-   // final token
 
-   list.push(str.substring(start, end))
 
-   return list
 
- }
 
 
  |