index.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*!
  2. * fresh
  3. * Copyright(c) 2012 TJ Holowaychuk
  4. * Copyright(c) 2016-2017 Douglas Christopher Wilson
  5. * MIT Licensed
  6. */
  7. 'use strict'
  8. /**
  9. * RegExp to check for no-cache token in Cache-Control.
  10. * @private
  11. */
  12. var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/
  13. /**
  14. * Simple expression to split token list.
  15. * @private
  16. */
  17. var TOKEN_LIST_REGEXP = / *, */
  18. /**
  19. * Module exports.
  20. * @public
  21. */
  22. module.exports = fresh
  23. /**
  24. * Check freshness of the response using request and response headers.
  25. *
  26. * @param {Object} reqHeaders
  27. * @param {Object} resHeaders
  28. * @return {Boolean}
  29. * @public
  30. */
  31. function fresh (reqHeaders, resHeaders) {
  32. // fields
  33. var modifiedSince = reqHeaders['if-modified-since']
  34. var noneMatch = reqHeaders['if-none-match']
  35. // unconditional request
  36. if (!modifiedSince && !noneMatch) {
  37. return false
  38. }
  39. // Always return stale when Cache-Control: no-cache
  40. // to support end-to-end reload requests
  41. // https://tools.ietf.org/html/rfc2616#section-14.9.4
  42. var cacheControl = reqHeaders['cache-control']
  43. if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {
  44. return false
  45. }
  46. // if-none-match
  47. if (noneMatch && noneMatch !== '*') {
  48. var etag = resHeaders['etag']
  49. var etagStale = !etag || noneMatch.split(TOKEN_LIST_REGEXP).every(function (match) {
  50. return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag
  51. })
  52. if (etagStale) {
  53. return false
  54. }
  55. }
  56. // if-modified-since
  57. if (modifiedSince) {
  58. var lastModified = resHeaders['last-modified']
  59. var modifiedStale = !lastModified || Date.parse(lastModified) > Date.parse(modifiedSince)
  60. if (modifiedStale) {
  61. return false
  62. }
  63. }
  64. return true
  65. }