Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 9x 82x 82x 82x 82x 82x 9x 327x 327x 5x 5x 327x 9x 9x 9x 9x 9x 9x 9x 82x 82x 82x 82x 166x 166x 166x 166x 79x 79x 79x 162x 166x 162x 166x 166x 161x 161x 76x 76x 76x 76x 76x 76x 76x 76x 82x | // multipart/form-data assembled by hand as one ArrayBuffer (DESIGN 5.1 and 5.2).
//
// wx.uploadFile cannot set a part Content-Type, so in 1.x the `config` part reached the platform as
// text/plain and native evaluate failed with HTTP 415. The body built here is sent with
// wx.request({method: 'POST', header: {'content-type': 'multipart/form-data; boundary=...'}, data}).
import { utf8Encode } from './codec.js';
import { localError } from './errors.js';
import { concatBytes, exactArrayBuffer, toUint8, randomBytes } from './util.js';
const CRLF = new Uint8Array([13, 10]);
const BOUNDARY_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
export function generateBoundary() {
const b = randomBytes(24);
let s = '----YuguFormBoundary';
for (let i = 0; i < b.length; i++) s += BOUNDARY_ALPHABET[b[i] % BOUNDARY_ALPHABET.length];
return s;
}
function checkToken(v, what) {
if (typeof v !== 'string' || !v || /["\r\n]/.test(v)) {
throw localError(90010, 'multipart ' + what + ' must be a non empty string without quotes or line breaks');
}
}
/**
* parts: [{name, data: string | ArrayBuffer | ArrayBufferView, filename?, contentType?}]
* A part without filename is a form parameter on the platform; a part with filename is a file.
* Returns {body: ArrayBuffer, bytes: Uint8Array, boundary, contentType}.
*/
export function buildMultipart(parts, boundary) {
const b = boundary || generateBoundary();
checkToken(b, 'boundary');
const chunks = [];
for (let i = 0; i < parts.length; i++) {
const p = parts[i];
checkToken(p.name, 'part name');
let head = '--' + b + '\r\nContent-Disposition: form-data; name="' + p.name + '"';
if (p.filename !== undefined && p.filename !== null) {
checkToken(p.filename, 'filename');
head += '; filename="' + p.filename + '"';
}
head += '\r\n';
if (p.contentType) head += 'Content-Type: ' + p.contentType + '\r\n';
head += '\r\n';
const data = typeof p.data === 'string' ? utf8Encode(p.data) : toUint8(p.data);
if (!data) throw localError(90010, 'multipart part ' + p.name + ' has no data');
chunks.push(utf8Encode(head), data, CRLF);
}
chunks.push(utf8Encode('--' + b + '--\r\n'));
const bytes = concatBytes(chunks);
return {
body: exactArrayBuffer(bytes),
bytes,
boundary: b,
contentType: 'multipart/form-data; boundary=' + b,
};
}
|