-
Notifications
You must be signed in to change notification settings - Fork 22
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
intercept calls to res.writeHead #33
Conversation
@@ -59,6 +86,7 @@ module.exports = function(fn) { | |||
|
|||
res.end = function(chunk, encoding, cb) { | |||
debug('end called'); | |||
endCalled = true; |
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.
Shouldn't you be calling the original writeHead
in this function?
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.
In the overwritten res.writeHead method, I'll do one of the following things:
- If we're not supposed to be intercepting, I'll call originalWriteHead.
- If end has been called already, I'll call originalWriteHead. (this will most likely result in an error writing headers after first chunk, but I'm just obeying orders from whoever is using me).
- If we should intercept, and end haven't been called, I'll unpack the res.writeHeaders call, by calling
res.status
andres.set
.
Due to the unpacking in option 3, I wont have to call writeHead again. The reason that I do this is first and foremost that it's not really the idiomatic express-way to use res.writeHead directly. And secondly, it would be quite hard and error prone to attempt to cache the values and call them again later. If what we are intercepting is setting a header with res.writeHead, and we were just calling res.writeHead with the same values later, we would not be able to overwrite or alter that header for that request. Unpacking it and setting the values independently with res.set allows us to do just that.
The only drawback to this approach is that I cannot figure out how to support the custom status messages, but that seemed like an OK compromise to me.
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 you could also add an example addressing this case.
The only drawback to this approach is that I cannot figure out how to support the custom status messages, but that seemed like an OK compromise to me.
What do you think about this guys @flockonus @papandreou @David-Hari ?
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.
It is not possible to support the reason argument in 0.10 at least. In node 4.0 it can be done though. This is how we did it in express-hijackresponse, and that haven't been problematic for us until now.
Since submitting this pull request, I've had to resort to rewriting express-hijackresponse, in order to cover our use cases. The new module is just called hijackresponse and works like express-hijackresponse. It doesn't have any of the downsides though (it doesn't patch the global http-response object). It will allow you to do streaming and support conditional GETs, which turned out to be problematic with express-interceptor. In general, people not confident with HTTP semantics will find express-interceptor to be a simpler abstraction, but it will not be able to support streaming or conditional GET (at least not fully) as it relies on buffering the response. If that is all you need, then express-interceptor is the right choice. Otherwise, I'll suggest that you take a look at hijackresponse. |
This is my attempt at solving #32
I'm not sure I covered all cases with my tests, so please chip in if you can spot any areas that I haven't covered.