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 84x 84x 84x 84x 84x 9x 335x 335x 5x 5x 335x 9x 9x 9x 9x 9x 9x 9x 84x 84x 84x 84x 170x 170x 170x 170x 81x 81x 81x 166x 170x 166x 170x 170x 165x 165x 78x 78x 78x 78x 78x 78x 78x 78x 84x | // 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,
};
}
|