From d416e1f027734900fba8685de2648ffb6c4432e5 Mon Sep 17 00:00:00 2001 From: Shivanshu Singh Date: Wed, 12 Feb 2025 16:27:46 +0530 Subject: [PATCH] added check for resources greater than 100mb (#1858) * added check for resources greater than 100mb * fixed coverage --- packages/core/src/network.js | 9 +++++-- packages/core/test/discovery.test.js | 35 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/core/src/network.js b/packages/core/src/network.js index 5bdf5d3f2..98fc2da10 100644 --- a/packages/core/src/network.js +++ b/packages/core/src/network.js @@ -467,6 +467,13 @@ async function saveResponseResource(network, request, session) { url, responseStatus: response?.status }; + // Checing for content length more than 100MB, to prevent websocket error which is governed by + // maxPayload option of websocket defaulted to 100MB. + // If content-length is more than our allowed 25MB, no need to process that resouce we can return log. + let contentLength = parseInt(response.headers['Content-Length']); + if (contentLength > MAX_RESOURCE_SIZE) { + return log.debug('- Skipping resource larger than 25MB', meta); + } let resource = network.intercept.getResource(url); if (!resource || (!resource.root && !resource.provided && disableCache)) { @@ -484,8 +491,6 @@ async function saveResponseResource(network, request, session) { return log.debug('- Skipping remote resource', meta); } else if (!body.length) { return log.debug('- Skipping empty response', meta); - } else if (body.length > MAX_RESOURCE_SIZE) { - return log.debug('- Skipping resource larger than 25MB', meta); } else if (!ALLOWED_STATUSES.includes(response.status)) { return log.debug(`- Skipping disallowed status [${response.status}]`, meta); } else if (!enableJavaScript && !ALLOWED_RESOURCES.includes(request.type)) { diff --git a/packages/core/test/discovery.test.js b/packages/core/test/discovery.test.js index 05ae96dc4..b29474969 100644 --- a/packages/core/test/discovery.test.js +++ b/packages/core/test/discovery.test.js @@ -535,6 +535,41 @@ describe('Discovery', () => { ); }); + it('skips file greater than 100MB', async () => { + server.reply('/large.css', () => [200, 'text/css', 'A'.repeat(100_000_000)]); + percy.loglevel('debug'); + + await percy.snapshot({ + name: 'test snapshot', + url: 'http://localhost:8000', + domSnapshot: testDOM.replace('style.css', 'large.css') + }); + + await percy.idle(); + + expect(captured[0]).toEqual([ + jasmine.objectContaining({ + attributes: jasmine.objectContaining({ + 'resource-url': jasmine.stringMatching(/^\/percy\.\d+\.log$/) + }) + }), + jasmine.objectContaining({ + attributes: jasmine.objectContaining({ + 'resource-url': 'http://localhost:8000/' + }) + }), + jasmine.objectContaining({ + attributes: jasmine.objectContaining({ + 'resource-url': 'http://localhost:8000/img.gif' + }) + }) + ]); + + expect(logger.stderr).toContain( + '[percy:core:discovery] - Skipping resource larger than 25MB' + ); + }); + it('does not capture duplicate root resources', async () => { let reDOM = dedent`