pnpm aborted a request once its total time passed `fetchTimeout`, body included, so `pnpm runtime set node` could never finish its ~62 MB download on a slow connection. pnpm v12 set reqwest's client-level `timeout`, a deadline for the whole request; pnpm v11 passed `AbortSignal.timeout` to undici, which aborts the response body too. Both stacks now bound inactivity instead. pnpm v12 sets reqwest's `read_timeout`, which restarts on every chunk received. pnpm v11 drops the abort signal and lets the undici dispatcher enforce `headersTimeout` and `bodyTimeout`, which behave the same way; the global dispatcher sets per dispatch, through an interceptor composed onto the dispatcher that would have served the request. The agents pnpm builds for a proxy or custom TLS take their connect bounds from the same value, which the abort signal used to cover. A connection that stops delivering data still fails after `fetchTimeout` in both. Closes pnpm/pnpm#14604
29 lines
804 B
TypeScript
29 lines
804 B
TypeScript
import { createServer, type ServerResponse } from 'node:http'
|
|
import type { AddressInfo } from 'node:net'
|
|
|
|
export interface TestServer extends AsyncDisposable {
|
|
url: string
|
|
}
|
|
|
|
export async function startServer (respond: (res: ServerResponse) => void): Promise<TestServer> {
|
|
const server = createServer((_req, res) => {
|
|
res.writeHead(200, { 'content-type': 'application/octet-stream' })
|
|
respond(res)
|
|
})
|
|
await new Promise<void>((resolve) => {
|
|
server.listen(0, '127.0.0.1', resolve)
|
|
})
|
|
const { port } = server.address() as AddressInfo
|
|
return {
|
|
url: `http://127.0.0.1:${port}/`,
|
|
async [Symbol.asyncDispose] () {
|
|
server.closeAllConnections()
|
|
await new Promise<void>((resolve) => {
|
|
server.close(() => {
|
|
resolve()
|
|
})
|
|
})
|
|
},
|
|
}
|
|
}
|