accept.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // src/utils/accept.ts
  2. var isWhitespace = (char) => char === 32 || char === 9 || char === 10 || char === 13;
  3. var consumeWhitespace = (acceptHeader, startIndex) => {
  4. while (startIndex < acceptHeader.length) {
  5. if (!isWhitespace(acceptHeader.charCodeAt(startIndex))) {
  6. break;
  7. }
  8. startIndex++;
  9. }
  10. return startIndex;
  11. };
  12. var ignoreTrailingWhitespace = (acceptHeader, startIndex) => {
  13. while (startIndex > 0) {
  14. if (!isWhitespace(acceptHeader.charCodeAt(startIndex - 1))) {
  15. break;
  16. }
  17. startIndex--;
  18. }
  19. return startIndex;
  20. };
  21. var skipInvalidParam = (acceptHeader, startIndex) => {
  22. while (startIndex < acceptHeader.length) {
  23. const char = acceptHeader.charCodeAt(startIndex);
  24. if (char === 59) {
  25. return [startIndex + 1, true];
  26. }
  27. if (char === 44) {
  28. return [startIndex + 1, false];
  29. }
  30. startIndex++;
  31. }
  32. return [startIndex, false];
  33. };
  34. var skipInvalidAcceptValue = (acceptHeader, startIndex) => {
  35. let i = startIndex;
  36. let inQuotes = false;
  37. while (i < acceptHeader.length) {
  38. const char = acceptHeader.charCodeAt(i);
  39. if (inQuotes && char === 92) {
  40. i++;
  41. } else if (char === 34) {
  42. inQuotes = !inQuotes;
  43. } else if (!inQuotes && char === 44) {
  44. return i + 1;
  45. }
  46. i++;
  47. }
  48. return i;
  49. };
  50. var getNextParam = (acceptHeader, startIndex) => {
  51. startIndex = consumeWhitespace(acceptHeader, startIndex);
  52. let i = startIndex;
  53. let key;
  54. let value;
  55. let hasNext = false;
  56. while (i < acceptHeader.length) {
  57. const char = acceptHeader.charCodeAt(i);
  58. if (char === 61) {
  59. key = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
  60. i++;
  61. break;
  62. }
  63. if (char === 59) {
  64. return [i + 1, void 0, void 0, true];
  65. }
  66. if (char === 44) {
  67. return [i + 1, void 0, void 0, false];
  68. }
  69. i++;
  70. }
  71. if (key === void 0) {
  72. return [i, void 0, void 0, false];
  73. }
  74. i = consumeWhitespace(acceptHeader, i);
  75. if (acceptHeader.charCodeAt(i) === 61) {
  76. const skipResult = skipInvalidParam(acceptHeader, i + 1);
  77. return [skipResult[0], key, void 0, skipResult[1]];
  78. }
  79. let inQuotes = false;
  80. const paramStartIndex = i;
  81. while (i < acceptHeader.length) {
  82. const char = acceptHeader.charCodeAt(i);
  83. if (inQuotes && char === 92) {
  84. i++;
  85. } else if (char === 34) {
  86. if (inQuotes) {
  87. let nextIndex = consumeWhitespace(acceptHeader, i + 1);
  88. const nextChar = acceptHeader.charCodeAt(nextIndex);
  89. if (nextIndex < acceptHeader.length && !(nextChar === 59 || nextChar === 44)) {
  90. const skipResult = skipInvalidParam(acceptHeader, nextIndex);
  91. return [skipResult[0], key, void 0, skipResult[1]];
  92. }
  93. value = acceptHeader.slice(paramStartIndex + 1, i);
  94. if (value.includes("\\")) {
  95. value = value.replace(/\\(.)/g, "$1");
  96. }
  97. if (nextChar === 44) {
  98. return [nextIndex + 1, key, value, false];
  99. }
  100. if (nextChar === 59) {
  101. hasNext = true;
  102. nextIndex++;
  103. }
  104. i = nextIndex;
  105. break;
  106. }
  107. inQuotes = true;
  108. } else if (!inQuotes && (char === 59 || char === 44)) {
  109. value = acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i));
  110. if (char === 59) {
  111. hasNext = true;
  112. }
  113. i++;
  114. break;
  115. }
  116. i++;
  117. }
  118. return [
  119. i,
  120. key,
  121. value ?? acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i)),
  122. hasNext
  123. ];
  124. };
  125. var getNextAcceptValue = (acceptHeader, startIndex) => {
  126. const accept = {
  127. type: "",
  128. params: {},
  129. q: 1
  130. };
  131. startIndex = consumeWhitespace(acceptHeader, startIndex);
  132. let i = startIndex;
  133. while (i < acceptHeader.length) {
  134. const char = acceptHeader.charCodeAt(i);
  135. if (char === 59 || char === 44) {
  136. accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
  137. i++;
  138. if (char === 44) {
  139. return [i, accept.type ? accept : void 0];
  140. }
  141. if (!accept.type) {
  142. return [skipInvalidAcceptValue(acceptHeader, i), void 0];
  143. }
  144. break;
  145. }
  146. i++;
  147. }
  148. if (!accept.type) {
  149. accept.type = acceptHeader.slice(
  150. startIndex,
  151. ignoreTrailingWhitespace(acceptHeader, acceptHeader.length)
  152. );
  153. return [acceptHeader.length, accept.type ? accept : void 0];
  154. }
  155. let param;
  156. let value;
  157. let hasNext;
  158. while (i < acceptHeader.length) {
  159. ;
  160. [i, param, value, hasNext] = getNextParam(acceptHeader, i);
  161. if (param && value) {
  162. accept.params[param] = value;
  163. }
  164. if (!hasNext) {
  165. break;
  166. }
  167. }
  168. return [i, accept];
  169. };
  170. var parseAccept = (acceptHeader) => {
  171. if (!acceptHeader) {
  172. return [];
  173. }
  174. const values = [];
  175. let i = 0;
  176. let accept;
  177. let requiresSort = false;
  178. let lastAccept;
  179. while (i < acceptHeader.length) {
  180. ;
  181. [i, accept] = getNextAcceptValue(acceptHeader, i);
  182. if (accept) {
  183. accept.q = parseQuality(accept.params.q);
  184. values.push(accept);
  185. if (lastAccept && lastAccept.q < accept.q) {
  186. requiresSort = true;
  187. }
  188. lastAccept = accept;
  189. }
  190. }
  191. if (requiresSort) {
  192. values.sort((a, b) => b.q - a.q);
  193. }
  194. return values;
  195. };
  196. var parseQuality = (qVal) => {
  197. if (qVal === void 0) {
  198. return 1;
  199. }
  200. if (qVal === "") {
  201. return 1;
  202. }
  203. if (qVal === "NaN") {
  204. return 0;
  205. }
  206. const num = Number(qVal);
  207. if (num === Infinity) {
  208. return 1;
  209. }
  210. if (num === -Infinity) {
  211. return 0;
  212. }
  213. if (Number.isNaN(num)) {
  214. return 1;
  215. }
  216. if (num < 0 || num > 1) {
  217. return 1;
  218. }
  219. return num;
  220. };
  221. export {
  222. parseAccept
  223. };