fix: data corruption in protocol.handle
(#41932)
* fix: data corruption in protocol.handle Co-authored-by: Jeremy Rose <jeremya@chromium.org> * slice instead of subarray Co-authored-by: Jeremy Rose <jeremya@chromium.org> --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Jeremy Rose <jeremya@chromium.org>
This commit is contained in:
parent
9ab77e77b1
commit
9c631ea744
3 changed files with 45 additions and 1 deletions
|
@ -18,7 +18,7 @@ function makeStreamFromPipe (pipe: any): ReadableStream {
|
||||||
try {
|
try {
|
||||||
const rv = await pipe.read(buf);
|
const rv = await pipe.read(buf);
|
||||||
if (rv > 0) {
|
if (rv > 0) {
|
||||||
controller.enqueue(buf.subarray(0, rv));
|
controller.enqueue(buf.slice(0, rv));
|
||||||
} else {
|
} else {
|
||||||
controller.close();
|
controller.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1381,6 +1381,49 @@ describe('protocol module', () => {
|
||||||
expect(body).to.equal(text);
|
expect(body).to.equal(text);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can receive stream request body asynchronously', async () => {
|
||||||
|
let done: any;
|
||||||
|
const requestReceived: Promise<Buffer[]> = new Promise(resolve => { done = resolve; });
|
||||||
|
protocol.handle('http-like', async (req) => {
|
||||||
|
const chunks = [];
|
||||||
|
for await (const chunk of (req.body as any)) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
}
|
||||||
|
done(chunks);
|
||||||
|
return new Response('ok');
|
||||||
|
});
|
||||||
|
defer(() => { protocol.unhandle('http-like'); });
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
w.loadURL('about:blank');
|
||||||
|
const expectedHashChunks = await w.webContents.executeJavaScript(`
|
||||||
|
const dataStream = () =>
|
||||||
|
new ReadableStream({
|
||||||
|
async start(controller) {
|
||||||
|
for (let i = 0; i < 10; i++) { controller.enqueue(Array(1024 * 128).fill(+i).join("\\n")); }
|
||||||
|
controller.close();
|
||||||
|
},
|
||||||
|
}).pipeThrough(new TextEncoderStream());
|
||||||
|
fetch(
|
||||||
|
new Request("http-like://host", {
|
||||||
|
method: "POST",
|
||||||
|
body: dataStream(),
|
||||||
|
duplex: "half",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
(async () => {
|
||||||
|
const chunks = []
|
||||||
|
for await (const chunk of dataStream()) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
|
})()
|
||||||
|
`);
|
||||||
|
const expectedHash = Buffer.from(await crypto.subtle.digest('SHA-256', Buffer.concat(expectedHashChunks))).toString('hex');
|
||||||
|
const body = Buffer.concat(await requestReceived);
|
||||||
|
const actualHash = Buffer.from(await crypto.subtle.digest('SHA-256', Buffer.from(body))).toString('hex');
|
||||||
|
expect(actualHash).to.equal(expectedHash);
|
||||||
|
});
|
||||||
|
|
||||||
it('can receive multi-part postData from loadURL', async () => {
|
it('can receive multi-part postData from loadURL', async () => {
|
||||||
protocol.handle('test-scheme', (req) => new Response(req.body));
|
protocol.handle('test-scheme', (req) => new Response(req.body));
|
||||||
defer(() => { protocol.unhandle('test-scheme'); });
|
defer(() => { protocol.unhandle('test-scheme'); });
|
||||||
|
|
|
@ -40,6 +40,7 @@ protocol.registerSchemesAsPrivileged([
|
||||||
{ scheme: global.standardScheme, privileges: { standard: true, secure: true, stream: false } },
|
{ scheme: global.standardScheme, privileges: { standard: true, secure: true, stream: false } },
|
||||||
{ scheme: global.zoomScheme, privileges: { standard: true, secure: true } },
|
{ scheme: global.zoomScheme, privileges: { standard: true, secure: true } },
|
||||||
{ scheme: global.serviceWorkerScheme, privileges: { allowServiceWorkers: true, standard: true, secure: true } },
|
{ scheme: global.serviceWorkerScheme, privileges: { allowServiceWorkers: true, standard: true, secure: true } },
|
||||||
|
{ scheme: 'http-like', privileges: { standard: true, secure: true, corsEnabled: true, supportFetchAPI: true } },
|
||||||
{ scheme: 'cors-blob', privileges: { corsEnabled: true, supportFetchAPI: true } },
|
{ scheme: 'cors-blob', privileges: { corsEnabled: true, supportFetchAPI: true } },
|
||||||
{ scheme: 'cors', privileges: { corsEnabled: true, supportFetchAPI: true } },
|
{ scheme: 'cors', privileges: { corsEnabled: true, supportFetchAPI: true } },
|
||||||
{ scheme: 'no-cors', privileges: { supportFetchAPI: true } },
|
{ scheme: 'no-cors', privileges: { supportFetchAPI: true } },
|
||||||
|
|
Loading…
Reference in a new issue