electron: Registering and intercepting stream protocols fails (interceptStreamProtocol)
-
2.0.2 and 2.0.3:
-
Operating System (Platform and Version):
Ubuntu 18.04 and MacOS (latest)
- Last known working Electron version:
None
Expected Behavior
Registering or intercepting a stream protocol should work and the browser should show the proper content.
Actual behavior
The browser actually shows an empty document with no content. No errors present.
I’ve verified that the same code works fine with ‘string’ protocols. Just not ‘stream’ protocols.
I created a repository here:
https://github.com/burtonator/electron-protocol-examples
With all my examples.
The key ones are:
intercept-stream-protocol-http.js : FAILS intercept-string-protocol-http.js: WORKS
I simplified the code greatly and I use the examples in the documentation. I’ve read the protocol documentation 2-3x to see if I was missing something. Does’t seem to be the case.
Additionally there is this case:
intercept-stream-protocol-with-default-protocol.js
… I’d like to have a way to revert to the default protocol handler if possible. A comment on my previous issue stated that this was possible but it still doesn’t appear to work. Doesn’t work with string protocols either.
To Reproduce
Just clone my repository and run the examples.
https://github.com/burtonator/electron-protocol-examples
git clone https://github.com/burtonator/electron-protocol-examples.git
cd electron-protocol-examples
npm install
## this will work and the content will be shown in the browser.
./node_modules/.bin/electron intercept-string-protocol-http.js
## this will NOT work and no content will be shown to the browser
./node_modules/.bin/electron intercept-stream-protocol-http.js
Screenshots
with sting protocol (working)

with stream protocol (not working)

About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 30 (12 by maintainers)
@sofianguy I think this problem returned or were never fixed. I’m using electron
8.0.0-beta.6onmacOS Catalina 10.15.2and got the same results as mentioned above. But in my case I can’t see any connection between async/ or sync nature of callback, it behave randomly 😢I’m 100% sure it works with the buffers, check #13623
Hi,
I think the issue might be in the passthrough code.
I was seeing that the request remained stuck in
loadingwhen inspecting it through the devtools window. It would just remain in limbo for a very long time. I think that the networking code relies on ReadableStream to emit thecloseevent which in its turn closes the request? If the close event is emitted before it protocol handler can latch on to it, it probably doesn’t resubmit.Note that the createStream had an additional delay to writing the null byte to indicate it has finished. Even a small timeout of 1 ms helped still worked.
EDIT: a better and more reliable fix would be the following: We pause the PassThrough stream, using
pause(). We return it to the networkcallback(..)and thenresume()the stream which will force the close event to trigger.@burtonator I am very sorry that the reply is late. You can try this code,it work well on my mac。You must use async/await or setTimeout in the interceptStreamProtocol callback,It is very strange,maybe it is a bug or feature?
const electron = require(‘electron’); const app = electron.app; const protocol = electron.protocol; const BrowserWindow = electron.BrowserWindow; const {PassThrough} = require(‘stream’)
/**
STATUS: fails.
@param request
@param callback */ function interceptStreamProtocol(request, callback) {
// The usage is similar to the other register{Any}Protocol, except that the
// callback should be called with either a Readable object or an object that // has the data, statusCode, and headers properties. setTimeout(()=> { callback({ statusCode: 200, headers: { ‘content-type’: ‘text/html’ }, data: createStream(‘HTTP 200 OK\r\n
Response
’) }); }, 2000)}
function createStream (text) { const rv = new PassThrough(); rv.push(text); rv.push(null); return rv; }
function createMainWindow() {
}
app.on(‘ready’, async function() {
});
@bpasero Yes. I’m 95% certain it works with register/intercept buffer protocol. I can update the code I posted to reflect this. I think this is just stream protocol. Stream is the important one though as it’s cleaner , faster, more real time, and supports headers.