-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix 677 #692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
mcollina
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
I'll wait for fastify/middie#17 before merge this. |
|
|
||
| function hookIterator (fn, state, next) { | ||
| function hookIterator (fn, state, next, release) { | ||
| if (state.res.finished === true) return release() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the hook sends a stream, will res.finished be true here? You may need to use res.headersSent instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll test this tomorrow :)
|
There should probably be some documentation to tell people using the callback version of hooks/middleware that if they send a response early, they must still call |
| }) | ||
| }) | ||
|
|
||
| test('onRequest hooks should be able to block a request', t => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe these cases should be worded: "should be able to terminate a request"? The word "block" seems to imply something more sinister to me.
jsumners
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The associated issue speaks specifically about using async handlers. Can we get a test that shows how those should work?
|
@delvedor oops, I see. |
jsumners
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
I've added a test case for streams. The issue is that |
docs/Hooks.md
Outdated
|
|
||
| // async api | ||
| fastify.addHook('preHandler', async (request, reply) => { | ||
| reply.code(401).send(new Error('Unauthorized')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better example would be to send something that isn't an Error because you can already do this with next(new Error('Unauthorized') for callbacks and throw new Error('Unauthorized') for async.
|
@delvedor Thanks for figuring out how to make this work with streams :) There's 1 case missing though. If the very last hook/middleware sends a response, then you also need to check |
|
@nwoltman nice catch! :) |
|
LOL, 42 additions of docs, 12 of core library and 555 of tests :D |
nwoltman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there! Just one last bit for the middlewares.
| } | ||
|
|
||
| function middlewareCallback (err, state) { | ||
| if (state.res.finished === true) return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing in onRunMiddlewares
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no need for that test. The middlewares are handled by middie, and the res.finished check is performed before to call the iterator or complete. :)
https://github.com/fastify/middie/blob/master/middie.js#L70-L77
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that's included in middie. Cool!
nwoltman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
mcollina
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is ok. I would not document the stream parts of preHandler as it should not be used that way, especially with async/await.
docs/Hooks.md
Outdated
| Note: If you change the payload, you may only change it to a `string`, a `Buffer`, a `stream`, or `null`. | ||
|
|
||
| ### Respond to a request from an hook | ||
| If need you can respond to a request before you reach the route handler, an example could be an authentication hook. If you are using `onRequest` or a middleware just use `res.end`, if you are using the `preHandler` hook use `reply.send`. Remember to always call `next` if you are using the standard hook api, if you are working with *async* hooks it will be done automatically by Fastify. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not true. If you 'forget' to call next, the only harm you will cause is to potentially increase the memory consumption, and you will prevent one of our optimizations to kick in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docs/Hooks.md
Outdated
| const stream = fs.createReadStream('some-file', 'utf8') | ||
| stream.pipe(res) | ||
| res.once('finish', next) | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be careful that this code is substantially wrong because it will leak a file descriptor if stream errors. How about using pump?
docs/Hooks.md
Outdated
| fastify.addHook('preHandler', (request, reply, next) => { | ||
| const stream = fs.createReadStream('some-file', 'utf8') | ||
| reply.send(stream) | ||
| reply.res.once('finish', next) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should really not be needing this.
We should not really be encouraging anyone to do this, so it's better if we do not document this behavior.
Doing this in their code is substantially wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So your suggestion is to remove the documentation about respond with streams inside the hooks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say so. We definitely need a better story for this hook, and there is solid work already done here which I do not want to block. Can you open a separate issue about replying with streams in a 'preHandler'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I've updated the docs.
docs/Hooks.md
Outdated
| const stream = fs.createReadStream('some-file', 'utf8') | ||
| stream.pipe(res) | ||
| res.once('finish', resolve) | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is even worse.
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This pr fixes #677.
In addition will release the reusify holder which is running the hooks, in this way the memory usage will not increase during time.
Related: delvedor/fast-iterator#8 and fastify/middie#17.
Checklist
npm run testandnpm run benchmark