Issue 1:
System info

Playwright Version: v1.33.0

Operating System: Ubuntu 22.04

Browser: Firefox

Other info:

Source code

I provided exact source code that allows reproducing the issue locally.

Link to the GitHub repository with the repro

https://github.com/ppath/playwright-firefox-buggy-large-req-payload

Steps

npm install

npm run test

Expected

For each test, the route/request interception should occur. Therefore, the message REQUEST INTERCEPTED: http://localhost:3000/api/foo <METHOD> should be printed three times:

✓ 1 [firefox] › tests/request_interception.spec.ts:17:5 › should intercept POSTing of 10KB payload (1.7s)
REQUEST INTERCEPTED: http://localhost:3000/api/foo POST
[browser]: response payload size: 10260
✓ 2 [firefox] › tests/request_interception.spec.ts:23:5 › should intercept POSTing of 10MB payload (1.4s)
REQUEST INTERCEPTED: http://localhost:3000/api/foo POST
[browser]: response payload size: 10485780
✓ 3 [firefox] › tests/request_interception.spec.ts:29:5 › should intercept PUTing of 10MB payload (1.3s)
REQUEST INTERCEPTED: http://localhost:3000/api/foo PUT
[browser]: response payload size: 10485780

Actual

When the request payload becomes equal or larger than 1MB, the request interception does not occur. Thus, the route handler is executed only once:

✓ 1 [firefox] › tests/request_interception.spec.ts:17:5 › should intercept POSTing of 10KB payload (1.7s)
REQUEST INTERCEPTED: http://localhost:3000/api/foo POST
[browser]: response payload size: 10260
✓ 2 [firefox] › tests/request_interception.spec.ts:23:5 › should intercept POSTing of 10MB payload (1.4s)
[browser]: response payload size: 10485780
✓ 3 [firefox] › tests/request_interception.spec.ts:29:5 › should intercept PUTing of 10MB payload (1.3s)
[browser]: response payload size: 10485780

So in conclusion, as far as I understand, the problem appears when:

The request payload becomes >= 1MB (I've tested it with payload of size 1023KB and it worked fine).

Running the tests with Firefox.

Issue 2:
Your header model generally looks something like this:

playwright/types/types.d.ts

Lines 13228 to 13231
in
9da26f9

/**

* Returns the object with HTTP headers associated with the response. All header names are lower-case.

*/

headers(): { [key: string]: string; };

Strictly speaking, headers are not a key/value map - and in practice, this causes some problems, for example with set-cookie, which frequently occurs more than once.

Apparently, the way you address this, is by concatenating multiple header-values with a \n (line-break) character.

It doesn't look like this detail is described in documentation - and by the time you uncover this, it makes it quite difficult and clumsy to work with the model.

For example, the widely-used set-cookie-parser package has some extremely weird behavior when you pass it a multi-value header like this - and the splitCookiesString function doesn't help here either, as it expects multi-value headers to be separated by commas rather than line-breaks.

It's not obvious how to add a header either - doing so correctly is pretty clumsy:

function addHeader(headers, name, value) {
if (name in headers) {
headers[name] = header[name] + "\n" + value;
} else {
headers[name] = value;
}
}

It's not clear to me if the line-breaks detail is the only detail either, or just the one I've discovered

Is there anything else I need to know?

Either way, I would suggest a deprecation of the existing methods and a replacement with some sort of abstraction/type to properly deal with headers?

That or a wrapper-type for the current model, to take care of the the splitting and recombining, adding/removing headers, etc. - which I will most likely write under any circumstances to avoid these issues.

At the very least, these details should be documented.

I am happy to help with whatever course of action you prefer. 🙂