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;
|
continue;
|
||||||
if (method === 'POST' && postData && candidate.request.postData) {
|
if (method === 'POST' && postData && candidate.request.postData) {
|
||||||
const buffer = await this._loadContent(candidate.request.postData);
|
const buffer = await this._loadContent(candidate.request.postData);
|
||||||
if (!buffer.equals(postData))
|
if (!buffer.equals(postData)) {
|
||||||
continue;
|
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);
|
entries.push(candidate);
|
||||||
}
|
}
|
||||||
@ -437,3 +446,13 @@ export async function urlToWSEndpoint(progress: Progress|undefined, endpointURL:
|
|||||||
wsUrl.protocol = wsUrl.protocol === 'https:' ? 'wss:' : 'ws:';
|
wsUrl.protocol = wsUrl.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
return wsUrl.toString();
|
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)');
|
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) => {
|
it('should update har.zip for page', async ({ contextFactory, server }, testInfo) => {
|
||||||
const harPath = testInfo.outputPath('har.zip');
|
const harPath = testInfo.outputPath('har.zip');
|
||||||
const context1 = await contextFactory();
|
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)');
|
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) => {
|
it('should update har.zip for page with different options', async ({ contextFactory, server }, testInfo) => {
|
||||||
const harPath = testInfo.outputPath('har.zip');
|
const harPath = testInfo.outputPath('har.zip');
|
||||||
const context1 = await contextFactory();
|
const context1 = await contextFactory();
|
||||||
|
Loading…
Reference in New Issue
Block a user