feat(har): store textual content without base64 encoding (#14772)
This commit is contained in:
parent
7a568a2952
commit
868e00253f
|
|
@ -191,7 +191,7 @@ export class HarTracer {
|
|||
const contentType = event.headers['content-type'];
|
||||
if (contentType)
|
||||
content.mimeType = contentType;
|
||||
this._storeResponseContent(event.body, content);
|
||||
this._storeResponseContent(event.body, content, 'other');
|
||||
|
||||
if (this._started)
|
||||
this._delegate.onEntryFinished(harEntry);
|
||||
|
|
@ -261,7 +261,7 @@ export class HarTracer {
|
|||
|
||||
const content = harEntry.response.content;
|
||||
compressionCalculationBarrier.setDecodedBodySize(buffer.length);
|
||||
this._storeResponseContent(buffer, content);
|
||||
this._storeResponseContent(buffer, content, request.resourceType());
|
||||
}).catch(() => {
|
||||
compressionCalculationBarrier.setDecodedBodySize(0);
|
||||
}).then(() => {
|
||||
|
|
@ -296,15 +296,21 @@ export class HarTracer {
|
|||
this._delegate.onEntryFinished(harEntry);
|
||||
}
|
||||
|
||||
private _storeResponseContent(buffer: Buffer | undefined, content: har.Content) {
|
||||
private _storeResponseContent(buffer: Buffer | undefined, content: har.Content, resourceType: string) {
|
||||
if (!buffer) {
|
||||
content.size = 0;
|
||||
return;
|
||||
}
|
||||
content.size = buffer.length;
|
||||
if (this._options.content === 'embedded') {
|
||||
content.text = buffer.toString('base64');
|
||||
content.encoding = 'base64';
|
||||
// Sometimes, we can receive a font/media file with textual mime type. Browser
|
||||
// still interprets them correctly, but the 'content-type' header is obviously wrong.
|
||||
if (isTextualMimeType(content.mimeType) && resourceType !== 'font') {
|
||||
content.text = buffer.toString();
|
||||
} else {
|
||||
content.text = buffer.toString('base64');
|
||||
content.encoding = 'base64';
|
||||
}
|
||||
} else if (this._options.content === 'sha1') {
|
||||
content._sha1 = calculateSha1(buffer) + '.' + (mime.getExtension(content.mimeType) || 'dat');
|
||||
if (this._started)
|
||||
|
|
@ -529,3 +535,7 @@ function parseCookie(c: string): har.Cookie {
|
|||
}
|
||||
return cookie;
|
||||
}
|
||||
|
||||
function isTextualMimeType(mimeType: string) {
|
||||
return !!mimeType.match(/^(text\/.*?|application\/(json|(x-)?javascript|xml.*?|ecmascript)|image\/svg(\+xml)?|application\/.*?(\+json|\+xml))(;\s*charset=.*)?$/);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,21 +248,26 @@ it('should include secure set-cookies', async ({ contextFactory, httpsServer },
|
|||
it('should include content @smoke', async ({ contextFactory, server }, testInfo) => {
|
||||
const { page, getLog } = await pageWithHar(contextFactory, testInfo);
|
||||
await page.goto(server.PREFIX + '/har.html');
|
||||
await page.evaluate(() => fetch('/pptr.png').then(r => r.arrayBuffer()));
|
||||
const log = await getLog();
|
||||
|
||||
expect(log.entries[0].response.httpVersion).toBe('HTTP/1.1');
|
||||
expect(log.entries[0].response.content.encoding).toBe('base64');
|
||||
expect(log.entries[0].response.content.encoding).toBe(undefined);
|
||||
expect(log.entries[0].response.content.mimeType).toBe('text/html; charset=utf-8');
|
||||
expect(Buffer.from(log.entries[0].response.content.text, 'base64').toString()).toContain('HAR Page');
|
||||
expect(log.entries[0].response.content.text).toContain('HAR Page');
|
||||
expect(log.entries[0].response.content.size).toBeGreaterThanOrEqual(96);
|
||||
expect(log.entries[0].response.content.compression).toBe(0);
|
||||
|
||||
expect(log.entries[1].response.httpVersion).toBe('HTTP/1.1');
|
||||
expect(log.entries[1].response.content.encoding).toBe('base64');
|
||||
expect(log.entries[1].response.content.encoding).toBe(undefined);
|
||||
expect(log.entries[1].response.content.mimeType).toBe('text/css; charset=utf-8');
|
||||
expect(Buffer.from(log.entries[1].response.content.text, 'base64').toString()).toContain('pink');
|
||||
expect(log.entries[1].response.content.text).toContain('pink');
|
||||
expect(log.entries[1].response.content.size).toBeGreaterThanOrEqual(37);
|
||||
expect(log.entries[1].response.content.compression).toBe(0);
|
||||
|
||||
expect(log.entries[2].response.content.encoding).toBe('base64');
|
||||
expect(log.entries[2].response.content.mimeType).toBe('image/png');
|
||||
expect(Buffer.from(log.entries[2].response.content.text, 'base64').byteLength).toBeGreaterThan(0);
|
||||
expect(log.entries[2].response.content.size).toBeGreaterThanOrEqual(6000);
|
||||
expect(log.entries[2].response.content.compression).toBe(0);
|
||||
});
|
||||
|
||||
it('should filter by glob', async ({ contextFactory, server }, testInfo) => {
|
||||
|
|
@ -580,7 +585,7 @@ it('should contain http2 for http2 requests', async ({ contextFactory, browserNa
|
|||
const log = await getLog();
|
||||
expect(log.entries[0].request.httpVersion).toBe('HTTP/2.0');
|
||||
expect(log.entries[0].response.httpVersion).toBe('HTTP/2.0');
|
||||
expect(Buffer.from(log.entries[0].response.content.text, 'base64').toString()).toBe('<h1>Hello World</h1>');
|
||||
expect(log.entries[0].response.content.text).toBe('<h1>Hello World</h1>');
|
||||
server.close();
|
||||
});
|
||||
|
||||
|
|
@ -734,7 +739,7 @@ it('should include API request', async ({ contextFactory, server }, testInfo) =>
|
|||
expect(entry.response.status).toBe(200);
|
||||
expect(entry.response.headers.find(h => h.name.toLowerCase() === 'content-type')?.value).toContain('application/json');
|
||||
expect(entry.response.content.size).toBe(15);
|
||||
expect(entry.response.content.text).toBe(responseBody.toString('base64'));
|
||||
expect(entry.response.content.text).toBe(responseBody.toString());
|
||||
});
|
||||
|
||||
it('should not hang on resources served from cache', async ({ contextFactory, server, browserName }, testInfo) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue