diff --git a/test/max-response-size.js b/test/max-response-size.js index cb5d120..62e75da 100644 --- a/test/max-response-size.js +++ b/test/max-response-size.js @@ -3,7 +3,7 @@ const { tspl } = require('@matteo.collina/tspl') const { test, after, describe } = require('node:test') const { once } = require('node:events') -const { Client, H2CClient, errors } = require('..') +const { Agent, Client, H2CClient, errors, request } = require('..') const { createServer } = require('node:http') const { createServer: createH2CServer } = require('node:http2') @@ -118,6 +118,49 @@ describe('max response size', async (t) => { await t.completed }) + for (const useMilo of [false, true]) { + test(`should count the whole body when it arrives in small chunks (useMilo: ${useMilo})`, async (t) => { + t = tspl(t, { plan: 2 }) + + const server = createServer({ joinDuplicateHeaders: true }) + after(() => { + server.closeAllConnections?.() + server.close() + }) + + // Every chunk is below the limit, but together they exceed it. With + // chunked encoding each chunk reaches the parser as its own body event. + server.on('request', async (req, res) => { + res.on('error', () => {}) + for (let i = 0; i < 16 && !res.destroyed; i++) { + res.write('abcd') + await new Promise((resolve) => setImmediate(resolve)) + } + res.end() + }) + + server.listen(0) + await once(server, 'listening') + + const agent = new Agent({ maxResponseSize: 16, useMilo }) + after(() => agent.close()) + + let error = null + let received = '' + try { + const { body } = await request(`http://localhost:${server.address().port}`, { dispatcher: agent }) + received = await body.text() + } catch (err) { + error = err + } + + t.ok(error instanceof errors.ResponseExceededMaxSizeError, `expected ResponseExceededMaxSizeError, got ${error} with ${received.length} bytes`) + t.strictEqual(received, '') + + await t.completed + }) + } + test('should throw an error if the response is too big over h2c', async (t) => { t = tspl(t, { plan: 1 })