Closed
Bug 1343940
Opened 7 years ago
Closed 7 years ago
Need to know when webRequest.*.addListener event registration completes
Categories
(WebExtensions :: Untriaged, defect)
Tracking
(Not tracked)
RESOLVED
DUPLICATE
of bug 1300234
People
(Reporter: imprec, Unassigned)
References
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:54.0) Gecko/20100101 Firefox/54.0 Build ID: 20170302030206 Steps to reproduce: Both WebRequest.onBeforeSendHeaders and WebRequest.onSendHeaders are async whereas the other events registration are synchronous. Here's what I do : ``` chrome.webRequest.onBeforeSendHeaders.addListener((details) => console.log('onBeforeSendHeaders', details.url), { urls: ['<all_urls>'] }); chrome.webRequest.onCompleted.addListener((details) => console.log('onCompleted', details.url), { urls: ['<all_urls>'] }); chrome.webRequest.onErrorOccurred.addListener((details) => console.log('onErrorOccurred', details.url), { urls: ['<all_urls>'] }); chrome.webRequest.onHeadersReceived.addListener((details) => console.log('onHeadersReceived', details.url), { urls: ['<all_urls>'] }) chrome.webRequest.onResponseStarted.addListener((details) => console.log('onResponseStarted', details.url), { urls: ['<all_urls>'] }) chrome.webRequest.onSendHeaders.addListener((details) => console.log('onSendHeaders', details.url), { urls: ['<all_urls>'] }) fetch('https://blackfire.io'); ``` And I got this in the console: ``` onHeadersReceived "https://blackfire.io/" onResponseStarted "https://blackfire.io/" onCompleted "https://blackfire.io/" ``` Note : When I do the fetch on next tick: ``` chrome.webRequest.onBeforeSendHeaders.addListener((details) => console.log('onBeforeSendHeaders', details.url), { urls: ['<all_urls>'] }); chrome.webRequest.onCompleted.addListener((details) => console.log('onCompleted', details.url), { urls: ['<all_urls>'] }); chrome.webRequest.onErrorOccurred.addListener((details) => console.log('onErrorOccurred', details.url), { urls: ['<all_urls>'] }); chrome.webRequest.onHeadersReceived.addListener((details) => console.log('onHeadersReceived', details.url), { urls: ['<all_urls>'] }) chrome.webRequest.onResponseStarted.addListener((details) => console.log('onResponseStarted', details.url), { urls: ['<all_urls>'] }) chrome.webRequest.onSendHeaders.addListener((details) => console.log('onSendHeaders', details.url), { urls: ['<all_urls>'] }) setTimeout(() => fetch('https://blackfire.io')); ``` I got the expected output in the console: ``` onBeforeSendHeaders "https://blackfire.io/" onSendHeaders "https://blackfire.io/" onHeadersReceived "https://blackfire.io/" onResponseStarted "https://blackfire.io/" onCompleted "https://blackfire.io/" ``` Actual results: See previous box Expected results: See previous box
Comment 1•7 years ago
|
||
All events are asynchronous. The other events just happen to be dispatched later.
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
Resolution: --- → INVALID
Reporter | ||
Comment 2•7 years ago
|
||
Hello [:kmag] and thank you for taking time for this ticket. I think we misunderstood, at least I did not express myself very well. My ticket is not about event dispatching but event handlers registration. Functions WebRequest.onBeforeSendHeaders.addListener and WebRequest.onSendHeaders.addListener are supposed to be synchronous, listener should be called once they have been called. It appears this is true for all WebRequest.*.addListener functions except the both I mentioned. Please have a look at the code I mentioned above. For the both function, listener are called on next tick. Hope you'll better understand what I report. Regards,
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
Reporter | ||
Updated•7 years ago
|
Summary: WebRequest.onBeforeSendHeaders and WebRequest.onSendHeaders are async whereas all WebRequest.* events are sync → WebRequest.onBeforeSendHeaders.addListener and WebRequest.onSendHeaders.addListener are async whereas all WebRequest.*.addListener events are sync
Comment 3•7 years ago
|
||
Request event handler registration is always asynchronous. The reason that some events fire in your case and others don't is that some events happen later than others.
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago → 7 years ago
Resolution: --- → INVALID
Reporter | ||
Comment 4•7 years ago
|
||
Hello again, Actually, if it's asynchronous, there's no way to know an event listener has been registered at the moment. This is an issue for two reason: - the addListener function should return a promise, or a extra argument should be passed as a callback to know when the listener is registered - The Chrome implementation is synchronous Regards,
Comment 5•7 years ago
|
||
(In reply to Romain Neutron from comment #4) > - The Chrome implementation is synchronous The Chrome implementation isn't synchronous, it just has different timing characteristics, and the listener happens to be registered in the parent process before the initial stages of the fetch request are proxied to it.
Reporter | ||
Comment 6•7 years ago
|
||
At my code level, it appears synchronous. Anyway, an asynchronous call should return a promise, a callback or anything that could determine when it's been done, otherwise how would you do?
Comment 7•7 years ago
|
||
(In reply to Romain Neutron from comment #6) > Anyway, an asynchronous call should return a promise, a callback or anything > that could determine when it's been done, That would probably be a good idea, yes. > otherwise how would you do? That depends. What exactly are you trying to do?
Comment 8•7 years ago
|
||
(In reply to Kris Maglione [:kmag] from comment #7) > (In reply to Romain Neutron from comment #6) > > Anyway, an asynchronous call should return a promise, a callback or anything > > that could determine when it's been done, > > That would probably be a good idea, yes. > > > otherwise how would you do? > > That depends. What exactly are you trying to do? Can't speak for Giorgio, but a very plausible use case that I have encountered multiple times is: 1. Register webRequest handler for a specific URL. 2. Trigger request to that URL 3. When the request finishes, remove the webRequest handler. What I currently do is execute step 1, call any async API (e.g. browser.runtime.getPlatformInfo), and in its callback continue at step 2. I know that it works in the current implementation, but there is no guarantee that it will work in the future. Having addListener return a Promise would be good IMO. It also allows add-on devs to handle errors in a more graceful way (this can be useful for feature detection when we extend the webRequest API filters/blocking responses in the future).
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: INVALID → ---
Summary: WebRequest.onBeforeSendHeaders.addListener and WebRequest.onSendHeaders.addListener are async whereas all WebRequest.*.addListener events are sync → Need to know when webRequest.*.addListener event registration completes
Comment 9•7 years ago
|
||
(In reply to Rob Wu [:robwu] from comment #8) > Can't speak for Giorgio, but a very plausible use case that I have Sorry, I meant Romain (the reporter). I've read too much reports from Giorgio today ;)
Updated•7 years ago
|
Status: REOPENED → RESOLVED
Closed: 7 years ago → 7 years ago
Resolution: --- → DUPLICATE
Updated•6 years ago
|
Product: Toolkit → WebExtensions
You need to log in
before you can comment on or make changes to this bug.
Description
•