From ec93f55eac62e54e5b416f52dd1dcf9d4b246af1 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Jan 2020 09:44:39 -0600 Subject: [PATCH 1/2] Update to not show API not ended warning when response is piped to --- packages/next/next-server/server/api-utils.ts | 14 +++++++++++++- .../api-support/pages/api/test-res-pipe.js | 10 ++++++++++ test/integration/api-support/test/index.test.js | 8 ++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 test/integration/api-support/pages/api/test-res-pipe.js diff --git a/packages/next/next-server/server/api-utils.ts b/packages/next/next-server/server/api-utils.ts index 33c6d45f4ce73..5dccc334eda49 100644 --- a/packages/next/next-server/server/api-utils.ts +++ b/packages/next/next-server/server/api-utils.ts @@ -55,9 +55,21 @@ export async function apiResolver( apiRes.json = data => sendJson(apiRes, data) const resolver = interopDefault(resolverModule) + let wasPiped = false + + if (process.env.NODE_ENV !== 'production') { + // listen for pipe event and don't show resolve warning + const handlePipe = () => { + wasPiped = true + res.removeListener('pipe', handlePipe) + } + res.addListener('pipe', handlePipe) + } + + // Call API route method await resolver(req, res) - if (process.env.NODE_ENV !== 'production' && !isResSent(res)) { + if (process.env.NODE_ENV !== 'production' && !isResSent(res) && !wasPiped) { console.warn( `API resolved without sending a response for ${req.url}, this may result in stalled requests.` ) diff --git a/test/integration/api-support/pages/api/test-res-pipe.js b/test/integration/api-support/pages/api/test-res-pipe.js new file mode 100644 index 0000000000000..c127f79c1fb9c --- /dev/null +++ b/test/integration/api-support/pages/api/test-res-pipe.js @@ -0,0 +1,10 @@ +import fetch from 'node-fetch' + +export default async (req, res) => { + const dataRes = await fetch( + `http://localhost:${req.query.port}/api/query?hello=from-pipe` + ) + + res.status(dataRes.status) + dataRes.body.pipe(res) +} diff --git a/test/integration/api-support/test/index.test.js b/test/integration/api-support/test/index.test.js index c66556733b2db..c4e5c7d389b37 100644 --- a/test/integration/api-support/test/index.test.js +++ b/test/integration/api-support/test/index.test.js @@ -363,6 +363,14 @@ function runTests(dev = false) { `API resolved without sending a response for /api/test-no-end, this may result in stalled requests.` ) }) + + it('should not show warning when the API resolves and the response is piped', async () => { + const startIdx = stderr.length > 0 ? stderr.length - 1 : stderr.length + await fetchViaHTTP(appPort, `/api/test-res-pipe`, { port: appPort }) + expect(stderr.substr(startIdx)).not.toContain( + `API resolved without sending a response for /api/test-res-pipe` + ) + }) } else { it('should build api routes', async () => { const pagesManifest = JSON.parse( From 39e3074ef77fe72bc04735a14d97fcf271e6b6b8 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Sun, 2 Feb 2020 21:27:18 -0600 Subject: [PATCH 2/2] Update to use res.once --- packages/next/next-server/server/api-utils.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/next/next-server/server/api-utils.ts b/packages/next/next-server/server/api-utils.ts index 5dccc334eda49..85d0156b97007 100644 --- a/packages/next/next-server/server/api-utils.ts +++ b/packages/next/next-server/server/api-utils.ts @@ -59,11 +59,7 @@ export async function apiResolver( if (process.env.NODE_ENV !== 'production') { // listen for pipe event and don't show resolve warning - const handlePipe = () => { - wasPiped = true - res.removeListener('pipe', handlePipe) - } - res.addListener('pipe', handlePipe) + res.once('pipe', () => (wasPiped = true)) } // Call API route method