Expose lifecycle cleanup for replaced middleware instances

Author: OskarEichlerCreated Sep 1, 2026Updated Sep 8, 2026

Problem

A host that replaces a proxy middleware instance at runtime cannot detach the old instance safely. After its first HTTP request, each instance installs its own anonymous close listener and bound upgrade listener on the HTTP server. RequestHandler exposes upgrade, but no lifecycle/disposal method.

This affects webpack-dev-server callback proxy configurations: recreating middleware accumulates WebSocket upgrade handlers. Its current workaround removes every server close listener, which also removes listeners owned by the host or other middleware and still cannot remove the old upgrade handler.

Minimal reproduction

Using [email protected]:

javascript
let middleware = createProxyMiddleware({ target, ws: true });
const server = http.createServer((req, res) => middleware(req, res));

await request(server);
console.log(server.listenerCount("close"), server.listenerCount("upgrade"));
// 1 1

middleware = createProxyMiddleware({ target, ws: true });
await request(server);
console.log(server.listenerCount("close"), server.listenerCount("upgrade"));
// 2 2

The exact result was reproduced on Node 22.23.2. The counts continue increasing with replacement.

Expected lifecycle contract

Could RequestHandler expose an idempotent lifecycle method such as dispose() or close() that:

  • removes only the close and internally registered upgrade listeners owned by that middleware instance
  • handles every HTTP server to which the instance subscribed
  • releases the underlying proxy resources with defined behavior for active requests/WebSockets
  • is safe to call more than once

I have not proposed a listener-diff workaround because concurrent requests can register the anonymous listeners after replacement, and removing all listeners is unsafe. I would be happy to prepare a focused implementation and regression tests once the desired active-request/WebSocket semantics and method name are confirmed.

Source: chimurai/http-proxy-middleware