<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: v1.33.0</li>
<li>Operating System: Ubuntu 22.04</li>
<li>Browser: Firefox</li>
<li>Other info:</li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Link to the GitHub repository with the repro</strong></p>
<p dir="auto"><a href="https://github.com/ppath/playwright-firefox-buggy-large-req-payload">https://github.com/ppath/playwright-firefox-buggy-large-req-payload</a></p>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>npm install</li>
<li>npm run test</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">For each test, the <a href="https://github.com/ppath/playwright-firefox-buggy-large-req-payload/blob/main/tests/request_interception.spec.ts#L11">route/request interception</a> should occur. Therefore, the message <code class="notranslate">REQUEST INTERCEPTED: http://localhost:3000/api/foo &lt;METHOD&gt;</code> should be printed three times:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  ✓  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"><pre class="notranslate"><code class="notranslate">  ✓  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
</code></pre></div>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">When the request payload becomes equal or larger than 1MB, the request interception does not occur. Thus, the route handler is executed only once:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  ✓  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"><pre class="notranslate"><code class="notranslate">  ✓  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
</code></pre></div>
<p dir="auto">So in conclusion, as far as I understand, the problem appears when:</p>
<ul dir="auto">
<li>The request payload becomes &gt;= 1MB (I've tested it with payload of size 1023KB and it worked fine).</li>
<li>Running the tests with Firefox.</li>
</ul>
<p dir="auto">Your header model generally looks something like this:</p>
<p dir="auto"></p><div class="Box Box--condensed my-2">
  <div class="Box-header f6">
    <p class="mb-0 text-bold">
      <a href="https://github.com/microsoft/playwright/blob/9da26f9534adcbd855e37b1584a94ca673e7f4bf/types/types.d.ts#L13228-L13231">playwright/types/types.d.ts</a>
    </p>
    <p class="mb-0 color-fg-muted">
        Lines 13228 to 13231
      in
      <a data-pjax="true" class="commit-tease-sha" href="/microsoft/playwright/commit/9da26f9534adcbd855e37b1584a94ca673e7f4bf">9da26f9</a>
    </p>
  </div>
  <div itemprop="text" class="Box-body p-0 blob-wrapper blob-wrapper-embedded data">
    <table class="highlight tab-size mb-0 js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">

        <tbody><tr class="border-0">
          <td id="L13228" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="13228"></td>
          <td id="LC13228" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">   <span class="pl-c">/**</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L13229" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="13229"></td>
          <td id="LC13229" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-c">   * Returns the object with HTTP headers associated with the response. All header names are lower-case.</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L13230" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="13230"></td>
          <td id="LC13230" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-c">   */</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L13231" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="13231"></td>
          <td id="LC13231" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">   <span class="pl-c1">headers</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-kos">{</span> <span class="pl-kos">[</span><span class="pl-s1">key</span>: <span class="pl-smi">string</span><span class="pl-kos">]</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">;</span> </td>
        </tr>
    </tbody></table>
  </div>
</div>
<p></p>
<p dir="auto">Strictly speaking, headers are not a key/value map - and in practice, this causes some problems, for example with <code class="notranslate">set-cookie</code>, which frequently occurs more than once.</p>
<p dir="auto">Apparently, the way you address this, is by concatenating multiple header-values with a <code class="notranslate">\n</code> (line-break) character.</p>
<p dir="auto">It doesn't look like this detail is described in <a href="https://playwright.dev/docs/api/class-request#request-headers" rel="nofollow">documentation</a> - and by the time you uncover this, it makes it quite difficult and clumsy to work with the model.</p>
<p dir="auto">For example, the widely-used <a href="https://www.npmjs.com/package/set-cookie-parser" rel="nofollow">set-cookie-parser</a> package has some extremely weird behavior when you pass it a multi-value header like this - and the <code class="notranslate">splitCookiesString</code> function doesn't help here either, as it expects multi-value headers to be separated by commas rather than line-breaks.</p>
<p dir="auto">It's not obvious how to add a header either - doing so correctly is pretty clumsy:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function addHeader(headers, name, value) {
  if (name in headers) {
    headers[name] = header[name] + &quot;\n&quot; + value;
  } else {
    headers[name] = value;
  }
}"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">addHeader</span><span class="pl-kos">(</span><span class="pl-s1">headers</span><span class="pl-kos">,</span> <span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">value</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">name</span> <span class="pl-k">in</span> <span class="pl-s1">headers</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-s1">headers</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">header</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span> <span class="pl-c1">+</span> <span class="pl-s">"\n"</span> <span class="pl-c1">+</span> <span class="pl-s1">value</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span>
    <span class="pl-s1">headers</span><span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-s1">value</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">It's not clear to me if the line-breaks detail is the only detail either, or just the one I've discovered</p>
<p dir="auto">Is there anything else I need to know?</p>
<p dir="auto">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?</p>
<p dir="auto">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.</p>
<p dir="auto">At the very least, these details should be documented.</p>
<p dir="auto">I am happy to help with whatever course of action you prefer. 🙂</p>