| 14 | |
| 15 | class 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; |