The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.js 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*!
  2. * vary
  3. * Copyright(c) 2014-2017 Douglas Christopher Wilson
  4. * MIT Licensed
  5. */
  6. 'use strict'
  7. /**
  8. * Module exports.
  9. */
  10. module.exports = vary
  11. module.exports.append = append
  12. /**
  13. * RegExp to match field-name in RFC 7230 sec 3.2
  14. *
  15. * field-name = token
  16. * token = 1*tchar
  17. * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
  18. * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
  19. * / DIGIT / ALPHA
  20. * ; any VCHAR, except delimiters
  21. */
  22. var FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/
  23. /**
  24. * Append a field to a vary header.
  25. *
  26. * @param {String} header
  27. * @param {String|Array} field
  28. * @return {String}
  29. * @public
  30. */
  31. function append (header, field) {
  32. if (typeof header !== 'string') {
  33. throw new TypeError('header argument is required')
  34. }
  35. if (!field) {
  36. throw new TypeError('field argument is required')
  37. }
  38. // get fields array
  39. var fields = !Array.isArray(field)
  40. ? parse(String(field))
  41. : field
  42. // assert on invalid field names
  43. for (var j = 0; j < fields.length; j++) {
  44. if (!FIELD_NAME_REGEXP.test(fields[j])) {
  45. throw new TypeError('field argument contains an invalid header name')
  46. }
  47. }
  48. // existing, unspecified vary
  49. if (header === '*') {
  50. return header
  51. }
  52. // enumerate current values
  53. var val = header
  54. var vals = parse(header.toLowerCase())
  55. // unspecified vary
  56. if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {
  57. return '*'
  58. }
  59. for (var i = 0; i < fields.length; i++) {
  60. var fld = fields[i].toLowerCase()
  61. // append value (case-preserving)
  62. if (vals.indexOf(fld) === -1) {
  63. vals.push(fld)
  64. val = val
  65. ? val + ', ' + fields[i]
  66. : fields[i]
  67. }
  68. }
  69. return val
  70. }
  71. /**
  72. * Parse a vary header into an array.
  73. *
  74. * @param {String} header
  75. * @return {Array}
  76. * @private
  77. */
  78. function parse (header) {
  79. var end = 0
  80. var list = []
  81. var start = 0
  82. // gather tokens
  83. for (var i = 0, len = header.length; i < len; i++) {
  84. switch (header.charCodeAt(i)) {
  85. case 0x20: /* */
  86. if (start === end) {
  87. start = end = i + 1
  88. }
  89. break
  90. case 0x2c: /* , */
  91. list.push(header.substring(start, end))
  92. start = end = i + 1
  93. break
  94. default:
  95. end = i + 1
  96. break
  97. }
  98. }
  99. // final token
  100. list.push(header.substring(start, end))
  101. return list
  102. }
  103. /**
  104. * Mark that a request is varied on a header field.
  105. *
  106. * @param {Object} res
  107. * @param {String|Array} field
  108. * @public
  109. */
  110. function vary (res, field) {
  111. if (!res || !res.getHeader || !res.setHeader) {
  112. // quack quack
  113. throw new TypeError('res argument is required')
  114. }
  115. // get existing header
  116. var val = res.getHeader('Vary') || ''
  117. var header = Array.isArray(val)
  118. ? val.join(', ')
  119. : String(val)
  120. // set new header
  121. if ((val = append(header, field))) {
  122. res.setHeader('Vary', val)
  123. }
  124. }