Skip to content

fix: don't ever execute middleware in lambda #2249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 10, 2023
Merged

Conversation

pieh
Copy link
Contributor

@pieh pieh commented Aug 8, 2023

Description

This change make next-server's runMiddleware no-op in lambdas. There are some scenarios where next-server would attempt that (example one seems to be rendering page in preview mode). The middleware is executed at the edge so executing it at lambda would cause:

  • it to run twice causing unknown effects
  • rather unknown behavior and support for various middleware APIs (geo? text rewrite)
  • crash when using @netlify/next enhanced middleware as that would execute in Nodejs env which cause early bail because it's not Deno env.
  • when SPLIT_* (api / render ) mode is enabled in next runtime we would not bundle required files to run middleware (common missing module is .next/server/edge-runtime-webpack.js and middleware module itself) - we could bundle those but because of all of above it seems better to not even try to run middleware at lambda.

Making runMiddleware always no-op in lambda seems safe for now as Next middleware is supposed to run only at edge, but vercel/next.js#46722 is a feature request asking to make middleware environment configurable, but at least as of now there was no reply from Next.js maintainers

next-server in general does have capability to run in Nodejs env as that's what is used locally (next start) through Next.js sandbox environment ( https://github.com/vercel/next.js/tree/canary/packages/next/src/server/web/sandbox )

It does seem like there is some difference in behavior between recent next versions (I could reproduce missing module problem with [email protected], but it didn't seem to happen with [email protected]), but even if things don't crash, it still seems valid to not run middleware in lambda ever if it runs at edge already.

Documentation

Tests

Added cypress tests for middleware demo site

Relevant links (GitHub issues, etc.) or a picture of cute animal

https://github.com/netlify/pod-ecosystem-frameworks/issues/588

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for netlify-plugin-nextjs-nx-monorepo-demo ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-nx-monorepo-demo/deploys/64d4eadf00f2ca0007eaef86
😎 Deploy Preview https://deploy-preview-2249--netlify-plugin-nextjs-nx-monorepo-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for netlify-plugin-nextjs-static-root-demo ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-static-root-demo/deploys/64d4eadf0adc5f000971ac02
😎 Deploy Preview https://deploy-preview-2249--netlify-plugin-nextjs-static-root-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for next-plugin-edge-middleware ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-edge-middleware/deploys/64d4eadf33ed8a0008a4e2bb
😎 Deploy Preview https://deploy-preview-2249--next-plugin-edge-middleware.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@github-actions github-actions bot added the type: chore work needed to keep the product and development running smoothly label Aug 8, 2023
@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for netlify-plugin-nextjs-next-auth-demo failed.

Name Link
🔨 Latest commit 9fdd493
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-next-auth-demo/deploys/64d4cd92b6c3ae00088679b1

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for netlify-plugin-nextjs-demo ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-demo/deploys/64d4eae03c692f00085d400a
😎 Deploy Preview https://deploy-preview-2249--netlify-plugin-nextjs-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for nextjs-plugin-custom-routes-demo ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/nextjs-plugin-custom-routes-demo/deploys/64d4eadf9447a500085b0886
😎 Deploy Preview https://deploy-preview-2249--nextjs-plugin-custom-routes-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for next-i18next-demo ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/next-i18next-demo/deploys/64d4eadf85b3890008f5cec3
😎 Deploy Preview https://deploy-preview-2249--next-i18next-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for next-plugin-canary ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-canary/deploys/64d4eadf413c4900080bf8e7
😎 Deploy Preview https://deploy-preview-2249--next-plugin-canary.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link

netlify bot commented Aug 8, 2023

Deploy Preview for netlify-plugin-nextjs-export-demo ready!

Name Link
🔨 Latest commit 05eb294
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-export-demo/deploys/64d4eadf7687a20008eafa36
😎 Deploy Preview https://deploy-preview-2249--netlify-plugin-nextjs-export-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@pieh pieh force-pushed the middleware-preview-test branch 4 times, most recently from 9fdd493 to 7e71458 Compare August 10, 2023 11:46
@pieh pieh force-pushed the middleware-preview-test branch from 7e71458 to a5f2f74 Compare August 10, 2023 11:55
Comment on lines +1 to +34
describe('Preview Mode', () => {
it('enters and exits preview mode', () => {
Cypress.Cookies.debug(true)
cy.getCookies().then((cookie) => cy.log('cookies', cookie))

cy.intercept('/previewTest', (req) => {
req.continue((res) => {
expect(res.headers?.['x-middleware-executed']).to.equal('true')
})
}).as('previewTestVisit')

// preview mode is off by default
cy.visit('/previewTest')
cy.findByText('Is preview? No', { selector: 'h1' })

// enter preview mode
cy.request('/api/enterPreview').then((response) => {
expect(response.body).to.have.property('name', 'preview mode')
})

// exptected content is rendered
cy.visit('/previewTest')
cy.findByText('Is preview? Yes!', { selector: 'h1' })

// exit preview mode
cy.request('/api/exitPreview')
cy.visit('/previewTest')
cy.findByText('Is preview? No', { selector: 'h1' })

// we should hit /previewTest 3 times (before entering preview, after entering preview, after exiting preview)
// this assertion is mainly to ensure interception works and assertion on response header is made
cy.get('@previewTestVisit.all').should('have.length', 3)
})
})
Copy link
Contributor Author

@pieh pieh Aug 10, 2023

Choose a reason for hiding this comment

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

This test does assert things correctly, but the version of Next used in middleware demo actually doesn't have the bug included, so the fix is only relevant to older next versions which we don't run test against currently :/

I think it's still worthwhile to include the test, but we should figure out test setup to run against more versions of next.js.

[email protected] does fail this test without the fix ( https://cloud.cypress.io/projects/yn8qwi/runs/2299/overview?roarHideRunsWithDiffGroupsAndTags=1 ) but with setup as-is we won't be using that version of next :/

Choose a reason for hiding this comment

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

It's good to have this like you mentioned and if we get around to running these tests on older versions, this will definitely be helpful.

@pieh pieh changed the title chore: add previewMode to middleware demo fix: don't ever execute middleware in lambda Aug 10, 2023
@github-actions github-actions bot added the type: bug code to address defects in shipped code label Aug 10, 2023
@pieh pieh marked this pull request as ready for review August 10, 2023 13:26
@pieh pieh requested a review from a team as a code owner August 10, 2023 13:26
Copy link

@nickytonline nickytonline left a comment

Choose a reason for hiding this comment

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

Thanks for sorting this out @pieh! :shipit:

Comment on lines +1 to +34
describe('Preview Mode', () => {
it('enters and exits preview mode', () => {
Cypress.Cookies.debug(true)
cy.getCookies().then((cookie) => cy.log('cookies', cookie))

cy.intercept('/previewTest', (req) => {
req.continue((res) => {
expect(res.headers?.['x-middleware-executed']).to.equal('true')
})
}).as('previewTestVisit')

// preview mode is off by default
cy.visit('/previewTest')
cy.findByText('Is preview? No', { selector: 'h1' })

// enter preview mode
cy.request('/api/enterPreview').then((response) => {
expect(response.body).to.have.property('name', 'preview mode')
})

// exptected content is rendered
cy.visit('/previewTest')
cy.findByText('Is preview? Yes!', { selector: 'h1' })

// exit preview mode
cy.request('/api/exitPreview')
cy.visit('/previewTest')
cy.findByText('Is preview? No', { selector: 'h1' })

// we should hit /previewTest 3 times (before entering preview, after entering preview, after exiting preview)
// this assertion is mainly to ensure interception works and assertion on response header is made
cy.get('@previewTestVisit.all').should('have.length', 3)
})
})

Choose a reason for hiding this comment

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

It's good to have this like you mentioned and if we get around to running these tests on older versions, this will definitely be helpful.

@@ -118,6 +119,13 @@ const getNetlifyNextServer = (NextServer: NextServerType) => {
}
}

// eslint-disable-next-line class-methods-use-this, require-await
async runMiddleware(): Promise<{ finished: boolean }> {

Choose a reason for hiding this comment

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

@pieh pieh added automerge and removed type: chore work needed to keep the product and development running smoothly labels Aug 10, 2023
@kodiakhq kodiakhq bot merged commit b9e87d1 into main Aug 10, 2023
@kodiakhq kodiakhq bot deleted the middleware-preview-test branch August 10, 2023 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge type: bug code to address defects in shipped code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants