You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							137 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
	
	
							137 lines
						
					
					
						
							2.6 KiB
						
					
					
				/*! | 
						|
 * 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 | 
						|
}
 | 
						|
 |