end event missed in client http response

131 views
Skip to first unread message

Kris Walker

unread,
Jun 26, 2011, 8:06:54 AM6/26/11
to nodejs
While investigating another HTTP problem I discovered that there are
times when the 'end' event is sometimes never emitted on an HTTP
client response object.

You can run this test script like Curl, by passing in a single
argument; the full HTTP URL of your target.

https://gist.github.com/1047559

For example:

If I call `node test_request.js http://www.example.com` or `node
test_request.js http://www.amazon.com` I always see the 'end' event
fired.

But, sometimes, when I do `node test_request.js http://www.google.com`
the 'end' event is sometimes never called, but not always.

Any ideas on why this is? Is it expected? And if so, what are some
common workarounds to confirming the whole body has been received?

Bruno Jouhier

unread,
Jun 26, 2011, 12:08:54 PM6/26/11
to nodejs
You should also trap the "error" event. If an error occurs, you will
get an error event, but you won't get any end event.

Bruno

On Jun 26, 2:06 pm, Kris Walker <kixxa...@gmail.com> wrote:
> While investigating another HTTP problem I discovered that there are
> times when the 'end' event is sometimes never emitted on an HTTP
> client response object.
>
> You can run this test script like Curl, by passing in a single
> argument; the full HTTP URL of your target.
>
> https://gist.github.com/1047559
>
> For example:
>
> If I call `node test_request.jshttp://www.example.com`or `node
> test_request.jshttp://www.amazon.com`I always see the 'end' event
> fired.
>
> But, sometimes, when I do `node test_request.jshttp://www.google.com`

Tom

unread,
Nov 6, 2012, 3:16:06 AM11/6/12
to nod...@googlegroups.com
Actually when a response is ended not many things happen. You can test this by hooking the emit function:

var _emit = res.emit;
        res.emit = function() {
            console.log('RESPONSE EMIT : %s', arguments[0]);
            _emit.apply(this, arguments);
        };

Using node 0.8.14 this only results in:
4: 6-11 15:6:18: RESPONSE EMIT : header
4: 6-11 15:6:18: RESPONSE EMIT : finish

So, the `finish` event indicates somekind of end. However, it is not official and undocumented.

Response inherits from WritableStream. Therefore it should emit the end and close events.

Why is this not happening?

mscdex

unread,
Nov 6, 2012, 7:37:28 AM11/6/12
to nodejs
On Nov 6, 3:16 am, Tom <tommed...@gmail.com> wrote:
> Why is this not happening?

AFAIK the 'end' event for the net module (which http uses) is only
emitted when a packet with the TCP FIN flag is set. The 'close' event
is always emitted as the last event (and can also be emitted when a
packet with the TCP RST flag set).

Tom

unread,
Nov 6, 2012, 11:01:52 AM11/6/12
to nod...@googlegroups.com
I'm afraid that the `close` event does not emit either, as becomes clear when hooking into the emit function as described earlier.

Only `header` and `finish` emit.

Why is this so?

Op dinsdag 6 november 2012 19:37:41 UTC+7 schreef mscdex het volgende:

mscdex

unread,
Nov 6, 2012, 3:02:52 PM11/6/12
to nodejs
On Nov 6, 11:01 am, Tom <tommed...@gmail.com> wrote:
> I'm afraid that the `close` event does not emit either, as becomes clear
> when hooking into the emit function as described earlier.
>
> Only `header` and `finish` emit.
>
> Why is this so?

What if you inspect events emitted on the underlying socket object
(req/res.socket or req/res.connection)?

Tom

unread,
Nov 6, 2012, 11:07:27 PM11/6/12
to nod...@googlegroups.com
That may work, but that does not resolve the situation.

I would like to know when the WritableStream `res` (which it is) is no longer writable. The documentation stipulates that it should emit a `close` event, but it does not.

This means that it's a bug by definition, right?

Anyway, I do not know if the underlying socket actually closing also means that the response cannot be written to anymore at this exact point, or if the response was closed somewhat earlier already. Therefore I do not think it is appropriate to listen to the underlying socket: the higher level response may be unwritable earlier than that.

Tom 

Op woensdag 7 november 2012 03:03:05 UTC+7 schreef mscdex het volgende:

Tom

unread,
Nov 6, 2012, 11:15:57 PM11/6/12
to nod...@googlegroups.com
I would like to add to the above that req/res.connection or req/res.socket are not officially supported according to the docs (http://nodejs.org/api/all.html#all_class_http_clientrequest).

Tom

Op woensdag 7 november 2012 11:07:27 UTC+7 schreef Tom het volgende:

mscdex

unread,
Mar 4, 2013, 12:21:12 PM3/4/13
to nodejs
On Mar 4, 11:30 am, Jonathan Gold <jgold...@gmail.com> wrote:
> Did this ever get filed as a bug or otherwise addressed? I can confirm the
> same behavior and discrepancies in the docs, and it's not clear how I'm
> supposed to correctly end my client reading of a 200 response (which just
> hangs with no end/error/close events).

What node version are you using?

Jonathan Gold

unread,
Mar 4, 2013, 3:23:41 PM3/4/13
to nod...@googlegroups.com
0.8.21 compiled from source on a macbook (mountain lion 10.8.2).

I just tried writing a test case to reproduce and that did get the 'end' event. I then tried just pulling out the parts of my real code that were hanging without 'end' into a separate util method, and that util method *did* get the 'end' event. Maybe there was some other value in my original scope which was affecting things, though I can't pin down what it might have been.

Sorry I can't provide a better report than this. I'm willing to write it off as some likely transient error in my code though and if I can catch it in the act again I'll send along the report and test script.

jonathan
Reply all
Reply to author
Forward
0 new messages