Skip to content

Commit

Permalink
support redirected requests
Browse files Browse the repository at this point in the history
  • Loading branch information
mschile committed Apr 20, 2024
1 parent 0b7c585 commit 9ee2791
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 10 deletions.
29 changes: 29 additions & 0 deletions packages/driver/cypress/e2e/e2e/service-worker.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -684,4 +684,33 @@ describe('service workers', { defaultCommandTimeout: 1000, pageLoadTimeout: 1000
cy.get('#output').should('have.text', 'done')
validateFetchHandlers({ listenerCount: 1 })
})

it('supports a redirected request', () => {
const script = () => {
self.addEventListener('fetch', function (event) {
return
})
}

cy.intercept('/fixtures/service-worker.js', (req) => {
req.reply(`(${script})()`,
{ 'Content-Type': 'application/javascript' })
})

cy.intercept('/fixtures/1mb*', (req) => {
req.reply({
statusCode: 302,
headers: {
location: '/fixtures/redirected',
},
})
})

cy.intercept('/fixtures/redirected', (req) => {
req.reply('redirected')
})

cy.visit('fixtures/service-worker.html')
cy.get('#output').should('have.text', 'done')
})
})
21 changes: 13 additions & 8 deletions packages/proxy/lib/http/util/service-worker-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ export class ServiceWorkerManager {
return false
}

if (browserPreRequest.hasRedirectResponse) {
debug('skipping request with redirect response: %o', browserPreRequest)

return false
}

let requestPotentiallyControlledByServiceWorker = false
let activatedServiceWorker: ServiceWorker | undefined
const paramlessURL = browserPreRequest.url?.split('?')[0] || ''
Expand Down Expand Up @@ -242,19 +248,17 @@ export class ServiceWorkerManager {

if (activatedServiceWorker) {
if (requestPotentiallyControlledByServiceWorker) {
isControlled = await this.isURLControlledByServiceWorker(browserPreRequest.url)
isControlled = await this.isURLControlledByServiceWorker(browserPreRequest)

if (isControlled) {
debug('Request is controlled by service worker: %o', browserPreRequest.url)
debug('Request is controlled by service worker: %o', { url: browserPreRequest.url, requestId: browserPreRequest.requestId })
activatedServiceWorker.controlledURLs.add(paramlessURL)

return true
}

debug('Request is not controlled by service worker: %o', browserPreRequest.url)
}

debug('Request is not controlled by service worker: %o', { browserPreRequest, requestPotentiallyControlledByServiceWorker })
debug('Request is not controlled by service worker: %o', { url: browserPreRequest.url, requestId: browserPreRequest.requestId, requestPotentiallyControlledByServiceWorker })
}

return false
Expand Down Expand Up @@ -345,13 +349,14 @@ export class ServiceWorkerManager {
* @param url the URL to check
* @returns a promise that resolves to `true` if the URL is controlled by a service worker, `false` otherwise.
*/
private isURLControlledByServiceWorker (url: string) {
private isURLControlledByServiceWorker (browserPreRequest: BrowserPreRequest) {
const url = browserPreRequest.url
const fetches = this.pendingServiceWorkerFetches.get(url)

if (fetches) {
const isControlled = fetches.shift()

debug('found pending service worker fetch: %o', { url, isControlled })
debug('found pending service worker fetch: %o', { url, isControlled, requestId: browserPreRequest.requestId })

if (fetches.length === 0) {
this.pendingServiceWorkerFetches.delete(url)
Expand All @@ -370,7 +375,7 @@ export class ServiceWorkerManager {
const deferred = pDefer<boolean>()

promises.push(deferred)
debug('adding pending controlled request promise: %s', url)
debug('adding pending controlled request promise: %o', { url, requestId: browserPreRequest.requestId })

return deferred.promise
}
Expand Down
1 change: 1 addition & 0 deletions packages/proxy/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export type BrowserPreRequest = {
errorHandled?: boolean
initiator?: Protocol.Network.Initiator
documentURL: string
hasRedirectResponse: boolean
cdpRequestWillBeSentTimestamp: number
cdpRequestWillBeSentReceivedTimestamp: number
}
Expand Down
12 changes: 10 additions & 2 deletions packages/proxy/test/unit/http/util/service-worker-manager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import sinon from 'sinon'
import { ServiceWorkerManager, serviceWorkerClientEventHandler } from '../../../../lib/http/util/service-worker-manager'

const createBrowserPreRequest = (
{ url, initiatorUrl, callFrameUrl, documentUrl, isPreload, originalResourceType }:
{ url: string, initiatorUrl?: string, documentUrl?: string, callFrameUrl?: string, isPreload?: boolean, originalResourceType?: string },
{ url, initiatorUrl, callFrameUrl, documentUrl, isPreload, originalResourceType, hasRedirectResponse }:
{ url: string, initiatorUrl?: string, documentUrl?: string, callFrameUrl?: string, isPreload?: boolean, originalResourceType?: string, hasRedirectResponse?: boolean },
) => {
return {
requestId: 'id-1',
Expand All @@ -13,6 +13,7 @@ const createBrowserPreRequest = (
headers: {},
resourceType: 'fetch' as const,
originalResourceType: originalResourceType || 'Fetch' as const,
hasRedirectResponse: hasRedirectResponse || false,
...(isPreload
? {
initiator: {
Expand Down Expand Up @@ -532,6 +533,13 @@ describe('lib/http/util/service-worker-manager', () => {

expect(await result).to.be.true
})

it('supports a redirected request', async () => {
expect(await manager.processBrowserPreRequest(createBrowserPreRequest({
url: 'http://localhost:8080/foo.js',
hasRedirectResponse: true,
}))).to.be.false
})
})

context('without any controlled urls', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/server/lib/browsers/cdp_automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ export class CdpAutomation implements CDPClient {
originalResourceType: params.type,
initiator: params.initiator,
documentURL: params.documentURL,
hasRedirectResponse: params.redirectResponse != null,
// wallTime is in seconds: https://vanilla.aslushnikov.com/?Network.TimeSinceEpoch
// normalize to milliseconds to be comparable to everything else we're gathering
cdpRequestWillBeSentTimestamp: params.wallTime * 1000,
Expand Down

5 comments on commit 9ee2791

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 9ee2791 Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.8.1/linux-x64/mschile/service_worker_uncontrolled-9ee2791b931f2dc3ffdf0743f753f927c572e3c7/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 9ee2791 Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.8.1/linux-arm64/mschile/service_worker_uncontrolled-9ee2791b931f2dc3ffdf0743f753f927c572e3c7/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 9ee2791 Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.8.1/darwin-arm64/mschile/service_worker_uncontrolled-9ee2791b931f2dc3ffdf0743f753f927c572e3c7/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 9ee2791 Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.8.1/darwin-x64/mschile/service_worker_uncontrolled-9ee2791b931f2dc3ffdf0743f753f927c572e3c7/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 9ee2791 Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.8.1/win32-x64/mschile/service_worker_uncontrolled-9ee2791b931f2dc3ffdf0743f753f927c572e3c7/cypress.tgz

Please sign in to comment.