460.node-fetch.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. "use strict";
  2. exports.id = 460;
  3. exports.ids = [460];
  4. exports.modules = {
  5. /***/ 460:
  6. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  7. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  8. /* harmony export */ toFormData: () => (/* binding */ toFormData)
  9. /* harmony export */ });
  10. /* harmony import */ var fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(730);
  11. /* harmony import */ var formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(435);
  12. let s = 0;
  13. const S = {
  14. START_BOUNDARY: s++,
  15. HEADER_FIELD_START: s++,
  16. HEADER_FIELD: s++,
  17. HEADER_VALUE_START: s++,
  18. HEADER_VALUE: s++,
  19. HEADER_VALUE_ALMOST_DONE: s++,
  20. HEADERS_ALMOST_DONE: s++,
  21. PART_DATA_START: s++,
  22. PART_DATA: s++,
  23. END: s++
  24. };
  25. let f = 1;
  26. const F = {
  27. PART_BOUNDARY: f,
  28. LAST_BOUNDARY: f *= 2
  29. };
  30. const LF = 10;
  31. const CR = 13;
  32. const SPACE = 32;
  33. const HYPHEN = 45;
  34. const COLON = 58;
  35. const A = 97;
  36. const Z = 122;
  37. const lower = c => c | 0x20;
  38. const noop = () => {};
  39. class MultipartParser {
  40. /**
  41. * @param {string} boundary
  42. */
  43. constructor(boundary) {
  44. this.index = 0;
  45. this.flags = 0;
  46. this.onHeaderEnd = noop;
  47. this.onHeaderField = noop;
  48. this.onHeadersEnd = noop;
  49. this.onHeaderValue = noop;
  50. this.onPartBegin = noop;
  51. this.onPartData = noop;
  52. this.onPartEnd = noop;
  53. this.boundaryChars = {};
  54. boundary = '\r\n--' + boundary;
  55. const ui8a = new Uint8Array(boundary.length);
  56. for (let i = 0; i < boundary.length; i++) {
  57. ui8a[i] = boundary.charCodeAt(i);
  58. this.boundaryChars[ui8a[i]] = true;
  59. }
  60. this.boundary = ui8a;
  61. this.lookbehind = new Uint8Array(this.boundary.length + 8);
  62. this.state = S.START_BOUNDARY;
  63. }
  64. /**
  65. * @param {Uint8Array} data
  66. */
  67. write(data) {
  68. let i = 0;
  69. const length_ = data.length;
  70. let previousIndex = this.index;
  71. let {lookbehind, boundary, boundaryChars, index, state, flags} = this;
  72. const boundaryLength = this.boundary.length;
  73. const boundaryEnd = boundaryLength - 1;
  74. const bufferLength = data.length;
  75. let c;
  76. let cl;
  77. const mark = name => {
  78. this[name + 'Mark'] = i;
  79. };
  80. const clear = name => {
  81. delete this[name + 'Mark'];
  82. };
  83. const callback = (callbackSymbol, start, end, ui8a) => {
  84. if (start === undefined || start !== end) {
  85. this[callbackSymbol](ui8a && ui8a.subarray(start, end));
  86. }
  87. };
  88. const dataCallback = (name, clear) => {
  89. const markSymbol = name + 'Mark';
  90. if (!(markSymbol in this)) {
  91. return;
  92. }
  93. if (clear) {
  94. callback(name, this[markSymbol], i, data);
  95. delete this[markSymbol];
  96. } else {
  97. callback(name, this[markSymbol], data.length, data);
  98. this[markSymbol] = 0;
  99. }
  100. };
  101. for (i = 0; i < length_; i++) {
  102. c = data[i];
  103. switch (state) {
  104. case S.START_BOUNDARY:
  105. if (index === boundary.length - 2) {
  106. if (c === HYPHEN) {
  107. flags |= F.LAST_BOUNDARY;
  108. } else if (c !== CR) {
  109. return;
  110. }
  111. index++;
  112. break;
  113. } else if (index - 1 === boundary.length - 2) {
  114. if (flags & F.LAST_BOUNDARY && c === HYPHEN) {
  115. state = S.END;
  116. flags = 0;
  117. } else if (!(flags & F.LAST_BOUNDARY) && c === LF) {
  118. index = 0;
  119. callback('onPartBegin');
  120. state = S.HEADER_FIELD_START;
  121. } else {
  122. return;
  123. }
  124. break;
  125. }
  126. if (c !== boundary[index + 2]) {
  127. index = -2;
  128. }
  129. if (c === boundary[index + 2]) {
  130. index++;
  131. }
  132. break;
  133. case S.HEADER_FIELD_START:
  134. state = S.HEADER_FIELD;
  135. mark('onHeaderField');
  136. index = 0;
  137. // falls through
  138. case S.HEADER_FIELD:
  139. if (c === CR) {
  140. clear('onHeaderField');
  141. state = S.HEADERS_ALMOST_DONE;
  142. break;
  143. }
  144. index++;
  145. if (c === HYPHEN) {
  146. break;
  147. }
  148. if (c === COLON) {
  149. if (index === 1) {
  150. // empty header field
  151. return;
  152. }
  153. dataCallback('onHeaderField', true);
  154. state = S.HEADER_VALUE_START;
  155. break;
  156. }
  157. cl = lower(c);
  158. if (cl < A || cl > Z) {
  159. return;
  160. }
  161. break;
  162. case S.HEADER_VALUE_START:
  163. if (c === SPACE) {
  164. break;
  165. }
  166. mark('onHeaderValue');
  167. state = S.HEADER_VALUE;
  168. // falls through
  169. case S.HEADER_VALUE:
  170. if (c === CR) {
  171. dataCallback('onHeaderValue', true);
  172. callback('onHeaderEnd');
  173. state = S.HEADER_VALUE_ALMOST_DONE;
  174. }
  175. break;
  176. case S.HEADER_VALUE_ALMOST_DONE:
  177. if (c !== LF) {
  178. return;
  179. }
  180. state = S.HEADER_FIELD_START;
  181. break;
  182. case S.HEADERS_ALMOST_DONE:
  183. if (c !== LF) {
  184. return;
  185. }
  186. callback('onHeadersEnd');
  187. state = S.PART_DATA_START;
  188. break;
  189. case S.PART_DATA_START:
  190. state = S.PART_DATA;
  191. mark('onPartData');
  192. // falls through
  193. case S.PART_DATA:
  194. previousIndex = index;
  195. if (index === 0) {
  196. // boyer-moore derrived algorithm to safely skip non-boundary data
  197. i += boundaryEnd;
  198. while (i < bufferLength && !(data[i] in boundaryChars)) {
  199. i += boundaryLength;
  200. }
  201. i -= boundaryEnd;
  202. c = data[i];
  203. }
  204. if (index < boundary.length) {
  205. if (boundary[index] === c) {
  206. if (index === 0) {
  207. dataCallback('onPartData', true);
  208. }
  209. index++;
  210. } else {
  211. index = 0;
  212. }
  213. } else if (index === boundary.length) {
  214. index++;
  215. if (c === CR) {
  216. // CR = part boundary
  217. flags |= F.PART_BOUNDARY;
  218. } else if (c === HYPHEN) {
  219. // HYPHEN = end boundary
  220. flags |= F.LAST_BOUNDARY;
  221. } else {
  222. index = 0;
  223. }
  224. } else if (index - 1 === boundary.length) {
  225. if (flags & F.PART_BOUNDARY) {
  226. index = 0;
  227. if (c === LF) {
  228. // unset the PART_BOUNDARY flag
  229. flags &= ~F.PART_BOUNDARY;
  230. callback('onPartEnd');
  231. callback('onPartBegin');
  232. state = S.HEADER_FIELD_START;
  233. break;
  234. }
  235. } else if (flags & F.LAST_BOUNDARY) {
  236. if (c === HYPHEN) {
  237. callback('onPartEnd');
  238. state = S.END;
  239. flags = 0;
  240. } else {
  241. index = 0;
  242. }
  243. } else {
  244. index = 0;
  245. }
  246. }
  247. if (index > 0) {
  248. // when matching a possible boundary, keep a lookbehind reference
  249. // in case it turns out to be a false lead
  250. lookbehind[index - 1] = c;
  251. } else if (previousIndex > 0) {
  252. // if our boundary turned out to be rubbish, the captured lookbehind
  253. // belongs to partData
  254. const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);
  255. callback('onPartData', 0, previousIndex, _lookbehind);
  256. previousIndex = 0;
  257. mark('onPartData');
  258. // reconsider the current character even so it interrupted the sequence
  259. // it could be the beginning of a new sequence
  260. i--;
  261. }
  262. break;
  263. case S.END:
  264. break;
  265. default:
  266. throw new Error(`Unexpected state entered: ${state}`);
  267. }
  268. }
  269. dataCallback('onHeaderField');
  270. dataCallback('onHeaderValue');
  271. dataCallback('onPartData');
  272. // Update properties for the next call
  273. this.index = index;
  274. this.state = state;
  275. this.flags = flags;
  276. }
  277. end() {
  278. if ((this.state === S.HEADER_FIELD_START && this.index === 0) ||
  279. (this.state === S.PART_DATA && this.index === this.boundary.length)) {
  280. this.onPartEnd();
  281. } else if (this.state !== S.END) {
  282. throw new Error('MultipartParser.end(): stream ended unexpectedly');
  283. }
  284. }
  285. }
  286. function _fileName(headerValue) {
  287. // matches either a quoted-string or a token (RFC 2616 section 19.5.1)
  288. const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
  289. if (!m) {
  290. return;
  291. }
  292. const match = m[2] || m[3] || '';
  293. let filename = match.slice(match.lastIndexOf('\\') + 1);
  294. filename = filename.replace(/%22/g, '"');
  295. filename = filename.replace(/&#(\d{4});/g, (m, code) => {
  296. return String.fromCharCode(code);
  297. });
  298. return filename;
  299. }
  300. async function toFormData(Body, ct) {
  301. if (!/multipart/i.test(ct)) {
  302. throw new TypeError('Failed to fetch');
  303. }
  304. const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
  305. if (!m) {
  306. throw new TypeError('no or bad content-type header, no multipart boundary');
  307. }
  308. const parser = new MultipartParser(m[1] || m[2]);
  309. let headerField;
  310. let headerValue;
  311. let entryValue;
  312. let entryName;
  313. let contentType;
  314. let filename;
  315. const entryChunks = [];
  316. const formData = new formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__/* .FormData */ .fS();
  317. const onPartData = ui8a => {
  318. entryValue += decoder.decode(ui8a, {stream: true});
  319. };
  320. const appendToFile = ui8a => {
  321. entryChunks.push(ui8a);
  322. };
  323. const appendFileToFormData = () => {
  324. const file = new fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__/* .File */ .ZH(entryChunks, filename, {type: contentType});
  325. formData.append(entryName, file);
  326. };
  327. const appendEntryToFormData = () => {
  328. formData.append(entryName, entryValue);
  329. };
  330. const decoder = new TextDecoder('utf-8');
  331. decoder.decode();
  332. parser.onPartBegin = function () {
  333. parser.onPartData = onPartData;
  334. parser.onPartEnd = appendEntryToFormData;
  335. headerField = '';
  336. headerValue = '';
  337. entryValue = '';
  338. entryName = '';
  339. contentType = '';
  340. filename = null;
  341. entryChunks.length = 0;
  342. };
  343. parser.onHeaderField = function (ui8a) {
  344. headerField += decoder.decode(ui8a, {stream: true});
  345. };
  346. parser.onHeaderValue = function (ui8a) {
  347. headerValue += decoder.decode(ui8a, {stream: true});
  348. };
  349. parser.onHeaderEnd = function () {
  350. headerValue += decoder.decode();
  351. headerField = headerField.toLowerCase();
  352. if (headerField === 'content-disposition') {
  353. // matches either a quoted-string or a token (RFC 2616 section 19.5.1)
  354. const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);
  355. if (m) {
  356. entryName = m[2] || m[3] || '';
  357. }
  358. filename = _fileName(headerValue);
  359. if (filename) {
  360. parser.onPartData = appendToFile;
  361. parser.onPartEnd = appendFileToFormData;
  362. }
  363. } else if (headerField === 'content-type') {
  364. contentType = headerValue;
  365. }
  366. headerValue = '';
  367. headerField = '';
  368. };
  369. for await (const chunk of Body) {
  370. parser.write(chunk);
  371. }
  372. parser.end();
  373. return formData;
  374. }
  375. /***/ })
  376. };
  377. ;