mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-01 08:34:02 +03:00
fix(har): ignore boundary when matching multipart/form-data body (#31672)
Fixes https://github.com/microsoft/playwright/issues/31495
This commit is contained in:
parent
459b762565
commit
1b4d9003c6
@ -348,8 +348,17 @@ class HarBackend {
|
||||
continue;
|
||||
if (method === 'POST' && postData && candidate.request.postData) {
|
||||
const buffer = await this._loadContent(candidate.request.postData);
|
||||
if (!buffer.equals(postData))
|
||||
if (!buffer.equals(postData)) {
|
||||
const boundary = multipartBoundary(headers);
|
||||
if (!boundary)
|
||||
continue;
|
||||
const candidataBoundary = multipartBoundary(candidate.request.headers);
|
||||
if (!candidataBoundary)
|
||||
continue;
|
||||
// Try to match multipart/form-data ignroing boundary as it changes between requests.
|
||||
if (postData.toString().replaceAll(boundary, '') !== buffer.toString().replaceAll(candidataBoundary, ''))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
entries.push(candidate);
|
||||
}
|
||||
@ -437,3 +446,13 @@ export async function urlToWSEndpoint(progress: Progress|undefined, endpointURL:
|
||||
wsUrl.protocol = wsUrl.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
return wsUrl.toString();
|
||||
}
|
||||
|
||||
function multipartBoundary(headers: HeadersArray) {
|
||||
const contentType = headers.find(h => h.name.toLowerCase() === 'content-type');
|
||||
if (!contentType?.value.includes('multipart/form-data'))
|
||||
return undefined;
|
||||
const boundary = contentType.value.match(/boundary=(\S+)/);
|
||||
if (boundary)
|
||||
return boundary[1];
|
||||
return undefined;
|
||||
}
|
||||
|
@ -412,6 +412,46 @@ it('should update har.zip for context', async ({ contextFactory, server }, testI
|
||||
await expect(page2.locator('body')).toHaveCSS('background-color', 'rgb(255, 192, 203)');
|
||||
});
|
||||
|
||||
it('should ignore boundary when matching multipart/form-data body', {
|
||||
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31495' }
|
||||
}, async ({ contextFactory, server }, testInfo) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.end(`
|
||||
<form id="form" action="form.html" enctype="multipart/form-data" method="POST">
|
||||
<input id="file" type="file" multiple />
|
||||
<button type="submit">Upload</button>
|
||||
</form>`);
|
||||
});
|
||||
server.setRoute('/form.html', (req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.end('<div>done</div>');
|
||||
});
|
||||
|
||||
const harPath = testInfo.outputPath('har.zip');
|
||||
const context1 = await contextFactory();
|
||||
await context1.routeFromHAR(harPath, { update: true });
|
||||
const page1 = await context1.newPage();
|
||||
await page1.goto(server.PREFIX + '/empty.html');
|
||||
const reqPromise = server.waitForRequest('/form.html');
|
||||
await page1.locator('button').click();
|
||||
await expect(page1.locator('div')).toHaveText('done');
|
||||
const req = await reqPromise;
|
||||
expect((await req.postBody).toString()).toContain('---');
|
||||
await context1.close();
|
||||
|
||||
const context2 = await contextFactory();
|
||||
await context2.routeFromHAR(harPath, { notFound: 'abort' });
|
||||
const page2 = await context2.newPage();
|
||||
await page2.goto(server.PREFIX + '/empty.html');
|
||||
const requestPromise = page2.waitForRequest(/.*form.html/);
|
||||
await page2.locator('button').click();
|
||||
const request = await requestPromise;
|
||||
expect.soft(await request.response()).toBeTruthy();
|
||||
expect(request.failure()).toBe(null);
|
||||
await expect(page2.locator('div')).toHaveText('done');
|
||||
});
|
||||
|
||||
it('should update har.zip for page', async ({ contextFactory, server }, testInfo) => {
|
||||
const harPath = testInfo.outputPath('har.zip');
|
||||
const context1 = await contextFactory();
|
||||
@ -428,7 +468,6 @@ it('should update har.zip for page', async ({ contextFactory, server }, testInfo
|
||||
await expect(page2.locator('body')).toHaveCSS('background-color', 'rgb(255, 192, 203)');
|
||||
});
|
||||
|
||||
|
||||
it('should update har.zip for page with different options', async ({ contextFactory, server }, testInfo) => {
|
||||
const harPath = testInfo.outputPath('har.zip');
|
||||
const context1 = await contextFactory();
|
||||
|
Loading…
Reference in New Issue
Block a user