fix(chromium): concat all post data entries for request.postData() (#30734)

This already works in Firefox, but does not work in WebKit.
This commit is contained in:
Dmitry Gozman 2024-05-09 14:08:38 -07:00 committed by GitHub
parent 10da0801e3
commit 0d004c9f3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 2 deletions

View File

@ -583,8 +583,9 @@ class InterceptableRequest {
} = requestPausedEvent ? requestPausedEvent.request : requestWillBeSentEvent.request;
const type = (requestWillBeSentEvent.type || '').toLowerCase();
let postDataBuffer = null;
if (postDataEntries && postDataEntries.length && postDataEntries[0].bytes)
postDataBuffer = Buffer.from(postDataEntries[0].bytes, 'base64');
const entries = postDataEntries?.filter(entry => entry.bytes);
if (entries && entries.length)
postDataBuffer = Buffer.concat(entries.map(entry => Buffer.from(entry.bytes!, 'base64')));
this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersObjectToArray(headers));
}

View File

@ -317,6 +317,30 @@ it('should get |undefined| with postDataJSON() when there is no post data', asyn
expect(response.request().postDataJSON()).toBe(null);
});
it('should return multipart/form-data', async ({ page, server, browserName }) => {
it.fixme(browserName === 'webkit', 'File content is missing in WebKit');
await page.goto(server.EMPTY_PAGE);
server.setRoute('/post', (req, res) => res.end());
await page.route('**/*', route => route.continue());
const requestPromise = page.waitForRequest('**/post');
await page.evaluate(async () => {
const body = new FormData();
body.set('name1', 'value1');
body.set('file', new File(['file-value'], 'foo.txt'));
body.set('name2', 'value2');
body.append('name2', 'another-value2');
await fetch('/post', { method: 'POST', body });
});
const request = await requestPromise;
const contentType = await request.headerValue('Content-Type');
const re = /^multipart\/form-data; boundary=(.*)$/;
expect(contentType).toMatch(re);
const b = contentType.match(re)[1]!;
const expected = `--${b}\r\nContent-Disposition: form-data; name=\"name1\"\r\n\r\nvalue1\r\n--${b}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"foo.txt\"\r\nContent-Type: application/octet-stream\r\n\r\nfile-value\r\n--${b}\r\nContent-Disposition: form-data; name=\"name2\"\r\n\r\nvalue2\r\n--${b}\r\nContent-Disposition: form-data; name=\"name2\"\r\n\r\nanother-value2\r\n--${b}--\r\n`;
expect(request.postDataBuffer().toString('utf8')).toEqual(expected);
});
it('should return event source', async ({ page, server }) => {
const SSE_MESSAGE = { foo: 'bar' };
// 1. Setup server-sent events on server that immediately sends a message to the client.