Split out of #206 (plugin-zero results comment): second seam forced by mounting Tideholm inside JSS.
Problem
Fastify's content parsers consume the request stream before handlers run. A plugin that hands requests to an existing node-style handler ((req, res) — any wrapped HTTP app, reverse proxy, or framework adapter) then blocks forever: the wrapped app listens for data/end on a stream that has already been drained. This cost an hour of debugging in the Tideholm adapter and will bite every plugin of this shape.
Workaround today (works, but is folklore)
Scoped registration with a pass-through parser, plus reply.hijack():
await fastify.register(async (scope) => {
scope.removeAllContentTypeParsers();
scope.addContentTypeParser('*', (req, payload, done) => done(null, payload));
scope.all(prefix, handler); // handler: reply.hijack(); app.handle(request.raw, reply.raw)
scope.all(prefix + '/*', handler);
});
Proposal
When the #206 loader lands, api.fastify (or a helper like api.mountApp(prefix, nodeHandler)) should offer this as a declared mode — e.g. rawBody: true in the plugin manifest or register options — so plugin authors never rediscover the scoped-parser incantation. api.mountApp is the stronger shape: it can bundle the prefix registration, the parser escape, the hijack, and the appPaths WAC exemption (see sibling issue) into one call, since every wrapped-app plugin needs all four together.
Acceptance
Split out of #206 (plugin-zero results comment): second seam forced by mounting Tideholm inside JSS.
Problem
Fastify's content parsers consume the request stream before handlers run. A plugin that hands requests to an existing node-style handler (
(req, res)— any wrapped HTTP app, reverse proxy, or framework adapter) then blocks forever: the wrapped app listens fordata/endon a stream that has already been drained. This cost an hour of debugging in the Tideholm adapter and will bite every plugin of this shape.Workaround today (works, but is folklore)
Scoped registration with a pass-through parser, plus
reply.hijack():Proposal
When the #206 loader lands,
api.fastify(or a helper likeapi.mountApp(prefix, nodeHandler)) should offer this as a declared mode — e.g.rawBody: truein the plugin manifest or register options — so plugin authors never rediscover the scoped-parser incantation.api.mountAppis the stronger shape: it can bundle the prefix registration, the parser escape, the hijack, and the appPaths WAC exemption (see sibling issue) into one call, since every wrapped-app plugin needs all four together.Acceptance