encoding.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. module.exports = preferredEncodings;
  2. preferredEncodings.preferredEncodings = preferredEncodings;
  3. function parseAcceptEncoding(accept) {
  4. var acceptableEncodings;
  5. if (accept) {
  6. acceptableEncodings = accept.split(',').map(function(e) {
  7. return parseEncoding(e.trim());
  8. });
  9. } else {
  10. acceptableEncodings = [];
  11. }
  12. if (!acceptableEncodings.some(function(e) {
  13. return e && e.encoding === 'identity';
  14. })) {
  15. acceptableEncodings.push({
  16. encoding: 'identity',
  17. q: 0.1
  18. });
  19. }
  20. return acceptableEncodings.filter(function(e) {
  21. return e && e.q > 0;
  22. });
  23. }
  24. function parseEncoding(s) {
  25. var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
  26. if (!match) return null;
  27. var encoding = match[1];
  28. var q = 1;
  29. if (match[2]) {
  30. var params = match[2].split(';');
  31. for (var i = 0; i < params.length; i ++) {
  32. var p = params[i].trim().split('=');
  33. if (p[0] === 'q') {
  34. q = parseFloat(p[1]);
  35. break;
  36. }
  37. }
  38. }
  39. return {
  40. encoding: encoding,
  41. q: q
  42. };
  43. }
  44. function getEncodingPriority(encoding, accepted) {
  45. return (accepted.filter(function(a) {
  46. return specify(encoding, a);
  47. }).sort(function (a, b) {
  48. // revsort
  49. return a.q === b.q ? 0 : a.q > b.q ? -1 : 1;
  50. })[0] || {q:0}).q;
  51. }
  52. function specify(encoding, spec) {
  53. if (spec.encoding === '*' || spec.encoding === encoding) {
  54. return spec;
  55. }
  56. }
  57. function preferredEncodings(accept, provided) {
  58. accept = parseAcceptEncoding(accept || '');
  59. if (provided) {
  60. return provided.map(function(type) {
  61. return [type, getEncodingPriority(type, accept)];
  62. }).filter(function(pair) {
  63. return pair[1] > 0;
  64. }).sort(function(a, b) {
  65. // revsort
  66. return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1;
  67. }).map(function(pair) {
  68. return pair[0];
  69. });
  70. } else {
  71. return accept.sort(function (a, b) {
  72. // revsort
  73. return a.q < b.q ? 1 : -1;
  74. }).map(function(type) {
  75. return type.encoding;
  76. });
  77. }
  78. }