microsoft / microsoft/playwright

[Bug]: bidi reports transfer size as responseBodySize, so request().sizes() over-reports the body by the header size

Open
#42,697 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
96.3k
Forks
6.5k
Avg merge
1d 6h
Merged PRs (30d)
180

Description

### Version

1.64.0-next, `d1ead3ecc`. Chrome 141 over `--project=bidi-chrome-page`.

### Steps to reproduce

Serve a body of a known length and read `sizes()`:

```js
server.setRoute('/fixed', (req, res) => {
const plain = 'x'.repeat(2000);
res.writeHead(200, { 'content-type': 'text/plain', 'content-length': String(plain.length) });
res.end(plain);
});
const resp = await page.goto(server.PREFIX + '/fixed');
console.log(await resp.request().sizes());
```

### Expected

`responseBodySize` of 2000, as chromium over CDP reports:

```
chromium (CDP) {"requestBodySize":0,"requestHeadersSize":674,"responseBodySize":2000,"responseHeadersSize":151}
```

### Actual

```
bidi-chrome {"requestBodySize":0,"requestHeadersSize":343,"responseBodySize":2151,"responseHeadersSize":132}
```

2151 for a 2000 byte body. That number is exactly CDP's body plus CDP's header size (2000 + 151), so what is coming back is the whole transfer, headers included, in the body field. Same overshoot on the other shapes I tried: a gzipped body whose encoded length is 35 reports 208, and a chunked response whose wire body is 15 reports 172.

### Cause

`packages/playwright-core/src/server/bidi/bidiNetworkManager.ts:168`:

```ts
response.setTransferSize(params.response.bodySize);
response.setEncodedBodySize(params.response.bodySize);
```

One protocol field feeds two different metrics. The codebase treats them as distinct, and `network.ts:719` spells the relationship out in the fallback path:

```ts
transferSize = responseHeadersSize + encodedBodySize;
```

so setting both from one value cannot be right for both. CDP keeps them apart:

```ts
response.setTransferSize(event.encodedDataLength);
response.responseHeadersSize().then(size => response.setEncodedBodySize(event.encodedDataLength - size));
```

WebKit only sets `setEncodedBodySize(event.metrics?.responseBodyBytesReceived)` and leaves transfer size to the fallback.

If BiDi's `network.ResponseData` carries `headersSize` alongside `bodySize`, subtracting it the way CDP does would line the two up. I did not check what Chrome actually populates there, so that part is a suggestion rather than a diagnosis.

### Scope

Only the bidi backend, which I realise is still experimental and tracked under #32577, so this is a low-priority one. Filing it discretely because the value is plainly wrong rather than merely missing, and the cause is two lines.

I am a freshman in college doing my best to contribute usefully, so if bidi gaps are better collected on #32577 than filed one by one, tell me and I will move it there.

Contributor guide

Open the contributing guide

Research direction

Start in packages/playwright-core/src/server/bidi/bidiNetworkManager.ts:168, then compare the fallback relationship in network.ts:719 and the CDP handling described in the issue. Inspect whether BiDi Network.ResponseData provides headersSize alongside bodySize. Done means request().sizes() reports the 2000-byte body separately from response headers for the reproduction and other response shapes.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.