rsnext/packages/next/server/lib/start-server.ts
JJ Kasper b15a976e11
Handle rewriting WebSocket requests (#39463)
This ensures we properly handle rewrites when the request is a WebSocket request. This also adds an integration test to ensure it is working as expected in dev and production mode. 

## Bug

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

Fixes: https://github.com/vercel/next.js/issues/32634
Closes: https://github.com/vercel/next.js/pull/38455
2022-08-10 17:00:30 +00:00

72 lines
1.7 KiB
TypeScript

import type { NextServerOptions, NextServer, RequestHandler } from '../next'
import { warn } from '../../build/output/log'
import http from 'http'
import next from '../next'
interface StartServerOptions extends NextServerOptions {
allowRetry?: boolean
keepAliveTimeout?: number
}
export function startServer(opts: StartServerOptions) {
let requestHandler: RequestHandler
const server = http.createServer((req, res) => {
return requestHandler(req, res)
})
if (opts.keepAliveTimeout) {
server.keepAliveTimeout = opts.keepAliveTimeout
}
return new Promise<NextServer>((resolve, reject) => {
let port = opts.port
let retryCount = 0
server.on('error', (err: NodeJS.ErrnoException) => {
if (
port &&
opts.allowRetry &&
err.code === 'EADDRINUSE' &&
retryCount < 10
) {
warn(`Port ${port} is in use, trying ${port + 1} instead.`)
port += 1
retryCount += 1
server.listen(port, opts.hostname)
} else {
reject(err)
}
})
let upgradeHandler: any
if (!opts.dev) {
server.on('upgrade', (req, socket, upgrade) => {
upgradeHandler(req, socket, upgrade)
})
}
server.on('listening', () => {
const addr = server.address()
const hostname =
!opts.hostname || opts.hostname === '0.0.0.0'
? 'localhost'
: opts.hostname
const app = next({
...opts,
hostname,
customServer: false,
httpServer: server,
port: addr && typeof addr === 'object' ? addr.port : port,
})
requestHandler = app.getRequestHandler()
upgradeHandler = app.getUpgradeHandler()
resolve(app)
})
server.listen(port, opts.hostname)
})
}