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.

encoding.js 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * negotiator
  3. * Copyright(c) 2012 Isaac Z. Schlueter
  4. * Copyright(c) 2014 Federico Romero
  5. * Copyright(c) 2014-2015 Douglas Christopher Wilson
  6. * MIT Licensed
  7. */
  8. 'use strict';
  9. /**
  10. * Module exports.
  11. * @public
  12. */
  13. module.exports = preferredEncodings;
  14. module.exports.preferredEncodings = preferredEncodings;
  15. /**
  16. * Module variables.
  17. * @private
  18. */
  19. var simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/;
  20. /**
  21. * Parse the Accept-Encoding header.
  22. * @private
  23. */
  24. function parseAcceptEncoding(accept) {
  25. var accepts = accept.split(',');
  26. var hasIdentity = false;
  27. var minQuality = 1;
  28. for (var i = 0, j = 0; i < accepts.length; i++) {
  29. var encoding = parseEncoding(accepts[i].trim(), i);
  30. if (encoding) {
  31. accepts[j++] = encoding;
  32. hasIdentity = hasIdentity || specify('identity', encoding);
  33. minQuality = Math.min(minQuality, encoding.q || 1);
  34. }
  35. }
  36. if (!hasIdentity) {
  37. /*
  38. * If identity doesn't explicitly appear in the accept-encoding header,
  39. * it's added to the list of acceptable encoding with the lowest q
  40. */
  41. accepts[j++] = {
  42. encoding: 'identity',
  43. q: minQuality,
  44. i: i
  45. };
  46. }
  47. // trim accepts
  48. accepts.length = j;
  49. return accepts;
  50. }
  51. /**
  52. * Parse an encoding from the Accept-Encoding header.
  53. * @private
  54. */
  55. function parseEncoding(str, i) {
  56. var match = simpleEncodingRegExp.exec(str);
  57. if (!match) return null;
  58. var encoding = match[1];
  59. var q = 1;
  60. if (match[2]) {
  61. var params = match[2].split(';');
  62. for (var j = 0; j < params.length; j++) {
  63. var p = params[j].trim().split('=');
  64. if (p[0] === 'q') {
  65. q = parseFloat(p[1]);
  66. break;
  67. }
  68. }
  69. }
  70. return {
  71. encoding: encoding,
  72. q: q,
  73. i: i
  74. };
  75. }
  76. /**
  77. * Get the priority of an encoding.
  78. * @private
  79. */
  80. function getEncodingPriority(encoding, accepted, index) {
  81. var priority = {o: -1, q: 0, s: 0};
  82. for (var i = 0; i < accepted.length; i++) {
  83. var spec = specify(encoding, accepted[i], index);
  84. if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
  85. priority = spec;
  86. }
  87. }
  88. return priority;
  89. }
  90. /**
  91. * Get the specificity of the encoding.
  92. * @private
  93. */
  94. function specify(encoding, spec, index) {
  95. var s = 0;
  96. if(spec.encoding.toLowerCase() === encoding.toLowerCase()){
  97. s |= 1;
  98. } else if (spec.encoding !== '*' ) {
  99. return null
  100. }
  101. return {
  102. i: index,
  103. o: spec.i,
  104. q: spec.q,
  105. s: s
  106. }
  107. };
  108. /**
  109. * Get the preferred encodings from an Accept-Encoding header.
  110. * @public
  111. */
  112. function preferredEncodings(accept, provided) {
  113. var accepts = parseAcceptEncoding(accept || '');
  114. if (!provided) {
  115. // sorted list of all encodings
  116. return accepts
  117. .filter(isQuality)
  118. .sort(compareSpecs)
  119. .map(getFullEncoding);
  120. }
  121. var priorities = provided.map(function getPriority(type, index) {
  122. return getEncodingPriority(type, accepts, index);
  123. });
  124. // sorted list of accepted encodings
  125. return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) {
  126. return provided[priorities.indexOf(priority)];
  127. });
  128. }
  129. /**
  130. * Compare two specs.
  131. * @private
  132. */
  133. function compareSpecs(a, b) {
  134. return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
  135. }
  136. /**
  137. * Get full encoding string.
  138. * @private
  139. */
  140. function getFullEncoding(spec) {
  141. return spec.encoding;
  142. }
  143. /**
  144. * Check if a spec has any quality.
  145. * @private
  146. */
  147. function isQuality(spec) {
  148. return spec.q > 0;
  149. }