Skip to content

Commit

Permalink
Fix getServerSideProps hanging in dev on early end (#33366)
Browse files Browse the repository at this point in the history
This fixes the case where calling `res.end()` is `getServerSideProps` would cause the request to hang in development due to our `Proxy` around `res` causing internal `ServerResponse` fields to not be available ([related post](https://javascript.info/proxy#built-in-objects-internal-slots)). I also migrated our `getServerSideProps` test suite to an e2e suite with a test for this case. 

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`

Fixes: #15118
Fixes: #32824
Closes: #33129
  • Loading branch information
ijjk committed Jan 16, 2022
1 parent 10c4f5d commit 02405e2
Show file tree
Hide file tree
Showing 28 changed files with 119 additions and 139 deletions.
10 changes: 9 additions & 1 deletion packages/next/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,15 @@ export async function renderToHTML(
warn(message)
}
}
return Reflect.get(obj, prop, receiver)
const value = Reflect.get(obj, prop, receiver)

// since ServerResponse uses internal fields which
// proxy can't map correctly we need to ensure functions
// are bound correctly while being proxied
if (typeof value === 'function') {
return value.bind(obj)
}
return value
},
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
import Link from 'next/link'
import path from 'path'
import fs from 'fs'
import findUp from 'find-up'

export async function getServerSideProps() {
const text = fs
.readFileSync(
findUp.sync('world.txt', {
// prevent webpack from intercepting
// eslint-disable-next-line no-eval
cwd: eval(`__dirname`),
}),
'utf8'
)
.readFileSync(path.join(process.cwd(), 'world.txt'), 'utf8')
.trim()

return {
Expand Down
12 changes: 12 additions & 0 deletions test/e2e/getserversideprops/app/pages/early-request-end.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function getServerSideProps({ res }) {
res.statusCode = 200
res.end('hello from gssp')

return {
props: {},
}
}

export default function Page(props) {
return <p>early request end</p>
}
File renamed without changes.
Loading

0 comments on commit 02405e2

Please sign in to comment.