fast-gateway 6 is a reliability release. We put the gateway through several rounds of adversarial review, looking for requests that slip past routes, hooks that crash the process and WebSockets that hang. We fixed everything we could reproduce, and the test suite went from 57 to 131 tests with 100% coverage.
It also moves to restana 7 and Node.js 24, so it's a major version: please read the upgrade notes below before updating.
⬆️ Upgrading from 5.x
Most gateways only need the first two checks.
- Use Node.js 24 or newer. restana 7 requires it.
- Check the case of your paths. Routes now match case-sensitively, so
GET /Users/42no longer reaches a route withprefix: '/users'. To keep the old behavior:gateway({ restana: { caseSensitive: false }, routes: [/* ... */] })
- Check
prefixRewritevalues that contain$. They're now used literally, so$&and other replacement patterns are no longer expanded. - Check clients that send
.or..path segments. These requests now get a400, including encoded forms such as%2e%2eand/..;/. - Check tests that assert error bodies. restana's default error handler now uses the standard status text, e.g.
{"code":404,"message":"Not Found"}instead of"Internal Server Error".
The full list of behavior changes is in the v6.x breaking changes.
🔒 Safer by default
- Path traversal is blocked. Before,
/public/../admincould get past the/publicroute's middlewares and reach a different service. - The hostnames hook no longer leaks memory. Requests to random subdomains under a wildcard pattern used to fill an unbounded cache.
- Your route config is no longer modified. The routes and hooks you pass to
gateway()stay unchanged, so you can share them between routes and gateways.
🐛 Fewer crashes and hangs
- An
onErrorhook that sends its own response no longer crashes the process withERR_HTTP_HEADERS_SENT. - A rejected async
proxyHandlerreachesonErrorinstead of leaving the request hanging. - A Lambda response without a
statusCode, or with an objectbody, no longer crashes the gateway.isBase64Encodedis honored as well. - Large chunked downloads over
Connection: close(Python's urllib, for example) are streamed instead of failing with502. Memory stays capped at 1MB.
🔌 Better WebSockets
- Close codes and reasons reach the other side, in both directions.
- Messages sent while an async
onOpenhook runs are queued and delivered, not dropped. - Unreachable upstreams, clients that disconnect, and upgrade requests that aren't WebSocket no longer leave connections open forever.
🧭 More predictable routing and proxying
prefix: '/'works as a catch-all route, and a prefix ending in/matches nested paths.- A route's
timeout: 0disables the global timeout, as documented. - Repeated query parameters (
?a=1&a=2) are forwarded as sent. - The
http-legacyproxy type is accepted at startup, and/services.jsonshows RegExp prefixes.
📦 Dependencies
restana7 (migration guide), plus the latest versions of everything else.npm auditreports no vulnerabilities in production dependencies.
What's Changed
- v6.0.0: fix functional bugs found by adversarial review, upgrade to restana 7 by @jkyberneees in #105
Full Changelog: v5.0.1...v6.0.0