Last Comment Bug 653533 - JavaScript-based channel listener (via nsITraceableChannel) causes errors to be swallowed
: JavaScript-based channel listener (via nsITraceableChannel) causes errors to ...
Product: Core
Classification: Components
Component: XPConnect (show other bugs)
: Trunk
: All All
: -- normal with 6 votes (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
Depends on:
Blocks: abp 515051
  Show dependency treegraph
Reported: 2011-04-28 12:27 PDT by Wladimir Palant
Modified: 2011-11-26 15:02 PST (History)
7 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

Testcase (1.41 KB, application/x-xpinstall)
2011-04-28 12:27 PDT, Wladimir Palant
no flags Details

Description Wladimir Palant 2011-04-28 12:27:13 PDT
Created attachment 528926 [details]

A user complained that Adblock Plus causes errors thrown by XHR handlers to be swallowed. I traced the problem to the stream listener that Adblock Plus registers via nsITraceableChannel.newStreamListener() - it seems that having this listener immediately causes errors to be ignored. This seems to be the same issue as bug 515051, maybe bug 515051 only fixed "readystatechanged" but not "load" event?

To reproduce install the attached extension and open chrome://testextension/content/test.html. Click first button, check error console after a few seconds. Click second button, check error console again.

Expected results:
For both buttons two messages should be added to the console:
* "Page loaded, error message should follow"
* "Error!"

Actual results:
The first button only produces the first message. The error that is thrown in the "load" event handler is swallowed. This is apparently because a JavaScript-based channel listener is defined in this case.

Reproduced in Firefox 4.0 and current mozilla-central nightly on Windows 7.
Comment 1 Boris Zbarsky [:bz] 2011-04-28 13:44:56 PDT
Bug 515051 was "fixed" by not using a JS-implemented nsIStreamListener in Firebug as the argument to setNewListener and using a stream listener tee instead.  Since they just wanted to snoop, not modify, this worked.
Comment 2 Wladimir Palant 2011-04-28 13:48:51 PDT
Ouch... I guess that in my case nsIStreamListenerTee would only create unnecessary overhead by duplicating all the data - I don't care about the data (yet), I only want to know when it is done.
Comment 3 Boris Zbarsky [:bz] 2011-04-29 21:46:00 PDT
And in particular, there is no good solution for this on the platform side for the reasons described in bug 515051, short of giving you a way to register just a request observer tee....
Comment 4 Wladimir Palant 2011-11-16 23:58:16 PST
Anyway, I've given up on the attempts to clean up the data attached to the channel:

WONTFIX I guess.
Comment 5 Loic Duros 2011-11-25 10:11:32 PST

I am working on a Firefox add-on which intercepts http responses and modifies those that are of type text/html them before they get parsed by Firefox.
To do this I have somewhat followed the following blog post:

However, onDataAvailable, I do not have the following line:       this.originalListener.onDataAvailable(request, context, inputStream, offset, count);

Instead I've placed this line in "onStopRequest", and I use a concatenated string of all the bits gathered from onDataAvailable. However, it seems that sometimes onStopRequest is completely bypassed and none of the logic I have inside of it gets executed at all. I see that onDataAvailable is triggered, often many times, but then onStopRequest isn't. It does not happen every time, far from it, and it seems to occur more often on certain pages or website, that is the case, I found, with the product detail pages on Amazon, such as:

Here is the original file:

You can see the first chunk is "onDataAvailable", and instead of passing the chunk of data back to the original listen, it pushes it in an array to be concatenated when "onStopRequest" gets triggered. If I place a console.log('onStopRequest triggered'); at the very top of onStopRequest, I'll see it most of the time, however from time to time (with cache cleared everytime) I won't see it, and none of the code in onStopRequest is triggered.

That's quite a problem since my add-on needs to modify the response at that time. I also don't understand why the page would still load even though the data isn't passed to the original listener from onDataAvailable.

Is the problem I'm describing similar to this bug that won't be fixed? I see in the adblockplus diff file that the chunk with onStopRequest was removed.

Thanks for your help,
Comment 6 Boris Zbarsky [:bz] 2011-11-25 19:38:30 PST
> Is the problem I'm describing similar to this bug that won't be fixed?


If you're not getting an onStopRequest, then something is _seriously_ broken.  Necko guarantees that it will deliver onStopRequest.

> I also don't understand why the page would still load even though the data isn't passed
> to the original listener from onDataAvailable.

It wouldn't, if you're actually intercepting the respose involved.
Comment 7 Loic Duros 2011-11-26 12:09:30 PST
Hi Boris,

Thanks much for your answer. The issue I described is totally unrelated to onStopData; it is due to the fact that I'm using an iframe to sandbox the html page, and the Amazon full product pages actually don't have a doctype and thus are rendered in quirks mode.

Thanks again for your help!
Comment 8 Loic Duros 2011-11-26 15:02:26 PST
As it turns out, the response not being caught was due to a conditional, I was checking for: request.contentType === 'text/html'. In the case of Amazon, from time to time, the contentType will be undefined.

Note You need to log in before you can comment on or make changes to this bug.