fix: memory leak caused by storing base64 encoded files recieved by CDP Network.requestWillBeSent (#22460)

* filtering out data urls from networkRequestWillBeSent CDP requests

* fix: memory leak caused by storing base64 encoded files recieved by CDP Network.requestWillBeSent

* Update packages/server/lib/browsers/cdp_automation.ts

grammar :)

Co-authored-by: Sam Tsai <samtsai@gmail.com>

* Update packages/server/lib/browsers/cdp_automation.ts

grammar :)

Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>

* added unit tests

Co-authored-by: Matt Henkes <mjhenkes@gmail.com>
Co-authored-by: Sam Tsai <samtsai@gmail.com>
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
This commit is contained in:
Dylan Schlabach
2022-06-23 12:35:49 -04:00
committed by GitHub
parent a21c942ee4
commit 75a5daf9d5
2 changed files with 99 additions and 2 deletions

View File

@@ -202,6 +202,15 @@ export class CdpAutomation {
// in Firefox, the hash is incorrectly included in the URL: https://bugzilla.mozilla.org/show_bug.cgi?id=1715366
if (url.includes('#')) url = url.slice(0, url.indexOf('#'))
// Filter out "data:" urls from being cached - fixes: https://github.com/cypress-io/cypress/issues/17853
// Chrome sends `Network.requestWillBeSent` events with data urls which won't actually be fetched
// Example data url: "data:font/woff;base64,<base64 encoded string>"
if (url.startsWith('data:')) {
debugVerbose('skipping `data:` url %s', url)
return
}
// Firefox: https://searchfox.org/mozilla-central/rev/98a9257ca2847fad9a19631ac76199474516b31e/remote/cdp/domains/parent/Network.jsm#397
// Firefox lacks support for urlFragment and initiator, two nice-to-haves
const browserPreRequest: BrowserPreRequest = {

View File

@@ -71,15 +71,103 @@ context('lib/browsers/cdp_automation', () => {
this.sendDebuggerCommand = sinon.stub()
this.onFn = sinon.stub()
this.sendCloseTargetCommand = sinon.stub()
this.automation = {
onBrowserPreRequest: sinon.stub(),
onRequestEvent: sinon.stub(),
}
this.automation = await CdpAutomation.create(this.sendDebuggerCommand, this.onFn, this.sendCloseTargetCommand, null, false)
this.cdpAutomation = await CdpAutomation.create(this.sendDebuggerCommand, this.onFn, this.sendCloseTargetCommand, this.automation, false)
this.sendDebuggerCommand
.throws(new Error('not stubbed'))
.withArgs('Browser.getVersion')
.resolves()
this.onRequest = this.automation.onRequest
this.onRequest = this.cdpAutomation.onRequest
})
describe('.onNetworkRequestWillBeSent', function () {
it('triggers onBrowserPreRequest', function () {
const browserPreRequest = {
requestId: '0',
type: 'other',
request: {
method: 'GET',
url: 'https://www.google.com',
headers: {},
},
}
this.onFn
.withArgs('Network.requestWillBeSent')
.yield(browserPreRequest)
expect(this.automation.onBrowserPreRequest).to.have.been.calledWith({
requestId: browserPreRequest.requestId,
method: browserPreRequest.request.method,
url: browserPreRequest.request.url,
headers: browserPreRequest.request.headers,
resourceType: browserPreRequest.type,
originalResourceType: browserPreRequest.type,
})
})
it('removes # from a url', function () {
const browserPreRequest = {
requestId: '0',
type: 'other',
request: {
method: 'GET',
url: 'https://www.google.com/foo#',
headers: {},
},
}
this.onFn
.withArgs('Network.requestWillBeSent')
.yield(browserPreRequest)
expect(this.automation.onBrowserPreRequest).to.have.been.calledWith({
requestId: browserPreRequest.requestId,
method: browserPreRequest.request.method,
url: 'https://www.google.com/foo', // we only care about the url
headers: browserPreRequest.request.headers,
resourceType: browserPreRequest.type,
originalResourceType: browserPreRequest.type,
})
})
it('ignore events with data urls', function () {
this.onFn
.withArgs('Network.requestWillBeSent')
.yield({ request: { url: 'data:font;base64' } })
expect(this.automation.onBrowserPreRequest).to.not.be.called
})
})
describe('.onResponseReceived', function () {
it('triggers onRequestEvent', function () {
const browserResponseReceived = {
requestId: '0',
response: {
status: 200,
headers: {},
},
}
this.onFn
.withArgs('Network.responseReceived')
.yield(browserResponseReceived)
expect(this.automation.onRequestEvent).to.have.been.calledWith(
'response:received', {
requestId: browserResponseReceived.requestId,
status: browserResponseReceived.response.status,
headers: browserResponseReceived.response.headers,
},
)
})
})
describe('get:cookies', () => {