source: frontend/node_modules/axios/lib/helpers/formDataToStream.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 3.0 KB
Line 
1import util from 'util';
2import { Readable } from 'stream';
3import utils from '../utils.js';
4import readBlob from './readBlob.js';
5import platform from '../platform/index.js';
6
7const BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_';
8
9const textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util.TextEncoder();
10
11const CRLF = '\r\n';
12const CRLF_BYTES = textEncoder.encode(CRLF);
13const CRLF_BYTES_COUNT = 2;
14
15class FormDataPart {
16 constructor(name, value) {
17 const { escapeName } = this.constructor;
18 const isStringValue = utils.isString(value);
19
20 let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${
21 !isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : ''
22 }${CRLF}`;
23
24 if (isStringValue) {
25 value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF));
26 } else {
27 const safeType = String(value.type || 'application/octet-stream').replace(/[\r\n]/g, '');
28 headers += `Content-Type: ${safeType}${CRLF}`;
29 }
30
31 this.headers = textEncoder.encode(headers + CRLF);
32
33 this.contentLength = isStringValue ? value.byteLength : value.size;
34
35 this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;
36
37 this.name = name;
38 this.value = value;
39 }
40
41 async *encode() {
42 yield this.headers;
43
44 const { value } = this;
45
46 if (utils.isTypedArray(value)) {
47 yield value;
48 } else {
49 yield* readBlob(value);
50 }
51
52 yield CRLF_BYTES;
53 }
54
55 static escapeName(name) {
56 return String(name).replace(
57 /[\r\n"]/g,
58 (match) =>
59 ({
60 '\r': '%0D',
61 '\n': '%0A',
62 '"': '%22',
63 })[match]
64 );
65 }
66}
67
68const formDataToStream = (form, headersHandler, options) => {
69 const {
70 tag = 'form-data-boundary',
71 size = 25,
72 boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET),
73 } = options || {};
74
75 if (!utils.isFormData(form)) {
76 throw TypeError('FormData instance required');
77 }
78
79 if (boundary.length < 1 || boundary.length > 70) {
80 throw Error('boundary must be 1-70 characters long');
81 }
82
83 const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);
84 const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF);
85 let contentLength = footerBytes.byteLength;
86
87 const parts = Array.from(form.entries()).map(([name, value]) => {
88 const part = new FormDataPart(name, value);
89 contentLength += part.size;
90 return part;
91 });
92
93 contentLength += boundaryBytes.byteLength * parts.length;
94
95 contentLength = utils.toFiniteNumber(contentLength);
96
97 const computedHeaders = {
98 'Content-Type': `multipart/form-data; boundary=${boundary}`,
99 };
100
101 if (Number.isFinite(contentLength)) {
102 computedHeaders['Content-Length'] = contentLength;
103 }
104
105 headersHandler && headersHandler(computedHeaders);
106
107 return Readable.from(
108 (async function* () {
109 for (const part of parts) {
110 yield boundaryBytes;
111 yield* part.encode();
112 }
113
114 yield footerBytes;
115 })()
116 );
117};
118
119export default formDataToStream;
Note: See TracBrowser for help on using the repository browser.