Skip to content

Commit

Permalink
Warn when response body is larger than 5mb (vercel#26831)
Browse files Browse the repository at this point in the history
This PR adds a warning when api responses exceed 5mb since this will end up failing once deployed. In a future version this scenario will throw an error.

## Bug

- [x] Integration tests added

## Documentation / Examples

- [x] Make sure the linting passes
  • Loading branch information
padmaia authored Jul 2, 2021
1 parent bdd1d85 commit 538095c
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 0 deletions.
13 changes: 13 additions & 0 deletions errors/api-routes-body-size-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# API Routes Body Size Limited to 5mb

#### Why This Error Occurred

API Routes are meant to respond quickly and are not intended to support responding with large amounts of data. The maximum size of responses is 5 MB.

#### Possible Ways to Fix It

Limit your API Route responses to less than 5 MB. If you need to support sending large files to the client, you should consider using a dedicated media host for those assets. See link below for suggestions.

### Useful Links

[Tips to avoid the 5 MB limit](https://vercel.com/support/articles/how-to-bypass-vercel-5mb-body-size-limit-serverless-functions)
4 changes: 4 additions & 0 deletions errors/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
"title": "amp-export-validation",
"path": "/errors/amp-export-validation.md"
},
{
"title": "api-routes-body-size-limit",
"path": "/errors/api-routes-body-size-limit.md"
},
{
"title": "api-routes-static-export",
"path": "/errors/api-routes-static-export.md"
Expand Down
20 changes: 20 additions & 0 deletions packages/next/server/api-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ export async function apiResolver(
)
}

let contentLength = 0
const writeData = apiRes.write
const endResponse = apiRes.end
apiRes.write = (...args: any[2]) => {
contentLength += Buffer.byteLength(args[0])
return writeData.apply(apiRes, args)
}
apiRes.end = (...args: any[2]) => {
if (args.length && typeof args[0] !== 'function') {
contentLength += Buffer.byteLength(args[0])
}

if (contentLength >= 5 * 1024 * 1024) {
console.warn(
`API response for ${req.url} exceeds 5MB. This will cause the request to fail in a future version. https://nextjs.org/docs/messages/api-routes-body-size-limit`
)
}

endResponse.apply(apiRes, args)
}
apiRes.status = (statusCode) => sendStatusCode(apiRes, statusCode)
apiRes.send = (data) => sendData(apiReq, apiRes, data)
apiRes.json = (data) => sendJson(apiRes, data)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default (req, res) => {
for (let i = 0; i <= 5 * 1024 * 1024; i++) {
res.write('.')
}
res.end()
}
4 changes: 4 additions & 0 deletions test/integration/api-support/pages/api/large-response.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default (req, res) => {
let body = '.'.repeat(5 * 1024 * 1024)
res.send(body)
}
14 changes: 14 additions & 0 deletions test/integration/api-support/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,20 @@ function runTests(dev = false) {
expect(data).toBe('hi')
})

it('should warn if response body is larger than 5MB', async () => {
let res = await fetchViaHTTP(appPort, '/api/large-response')
expect(res.ok).toBeTruthy()
expect(stderr).toContain(
'API response for /api/large-response exceeds 5MB. This will cause the request to fail in a future version.'
)

res = await fetchViaHTTP(appPort, '/api/large-chunked-response')
expect(res.ok).toBeTruthy()
expect(stderr).toContain(
'API response for /api/large-chunked-response exceeds 5MB. This will cause the request to fail in a future version.'
)
})

if (dev) {
it('should compile only server code in development', async () => {
await fetchViaHTTP(appPort, '/api/users')
Expand Down

0 comments on commit 538095c

Please sign in to comment.