Skip to content
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

feat: Add support to callback in protocol interceptor handler without argument to perform as if no interceptors. #41929

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mrchaofan
Copy link

@mrchaofan mrchaofan commented Apr 22, 2024

Description of Change

To SAVE your life while doing protocol intercept.
These changes were made to allow you writting code blow.

protocol.interceptProtocol('https', (req, callback) => {
    // map request to file.
    if (shouldMapToLocal(req)) {
        callback({
            path: getLocalFilePathOf(req)
        })
        return
    }
    // Trigger the default behavior of loading https request
    // You never need to care about the net.fetch and handle the redirect may happen in net.fetch.
    // Just call callback();
    // NOTE that only protocol.intercept(Any)Protocol is allowed to call callback without argument.
    // if you are doing a protocol register you have to give the response data in callback too.
    callback();
})

Just DO NOT use the documented way.

protocol.handle('app', (req) => {
  if (shouldResponseByOthers(req) {
    return giveReponseByOthers(req)
  }
  // To work as you don't intercept it.
  return net.fetch(req)
})

The document's code is perfect but in real it has tons of bug.

problems

  1. losing blob data of req. If you post a file created by a input tag. you'll lose the most important part of the request🐶.(fixed in fix: properly stream uploadData in protocol.handle() #41052)
    image
  2. exception caused by web stream contains undefined data.
  3. You cannot perceive redirection in net.fetch API. If you're loading a page you can't response the data of yyyy.html while rendering xxxx.html. You need to perceive the navigation and response with a object created by Response.redirect("yyyy.html").

cc: @codebytere @nornagon

Checklist

Release Notes

notes: Add support to callback in protocol interceptor handler without argument to perform as if no interceptors.

Copy link

welcome bot commented Apr 22, 2024

💖 Thanks for opening this pull request! 💖

We use semantic commit messages to streamline the release process. Before your pull request can be merged, you should update your pull request title to start with a semantic prefix.

Examples of commit messages with semantic prefixes:

  • fix: don't overwrite prevent_default if default wasn't prevented
  • feat: add app.isPackaged() method
  • docs: app.isDefaultProtocolClient is now available on Linux

Things that will help get your PR across the finish line:

  • Follow the JavaScript, C++, and Python coding style.
  • Run npm run lint locally to catch formatting errors earlier.
  • Document any user-facing changes you've made following the documentation styleguide.
  • Include tests when adding/changing behavior.
  • Include screenshots and animated GIFs whenever possible.

We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened in the last 24 hours label Apr 22, 2024
Copy link
Member

@codebytere codebytere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is an user-facing API change, we'll need to update API documentation as well as add tests to ensure coverage for this change.

@mrchaofan mrchaofan force-pushed the electron_url_loader_factory branch 2 times, most recently from 7867b60 to b733e96 Compare April 23, 2024 03:16
@mrchaofan
Copy link
Author

As this is a user-facing API change, we'll need to update API documentation as well as add tests to ensure coverage for this change.

Okay. I'll write some tests for it.

@mrchaofan
Copy link
Author

@codebytere @nornagon I've add some test for protocol.interceptProtocol api. But It is a private api so I don't know how to write document for it. But It is ok to work with calling protocol.interceptHttpProtocol api.

protocol.interceptHttpProtocol('https', (req, callback) => {
    // a Electron.ProtocolResponse or undefined or null or {};
    const maybeSpecialRes = getSpecialRes(req); // null or {url, uploadData}
    // If maybeSpecialRes is not a Electron.ProtocolResponse then the behavior should perform like no interceptor.
    callback(maybeSpecialRes);
})

But the interceptHttpProtocol api forces you to send only http.But protocol.interceptProtocol has more exciting features.

protocol.interceptProtocol('https', (req, callback) => {
    if (/^https:\/\/docs\.qq\.com\/desktop($|\?|\/)/.test(req.url)) {
        // Map request to local file.
        callback({
            path: path.join(__dirname, 'index.html')
        })
        return
    }
    // Perform default http request behavior.
    callback();
});

@mrchaofan mrchaofan changed the title feat: Use default URLLoaderFactory if protocal.handle was callbacked without arg. feat: Add support to callback in protocol interceptor handler without argument to perform as if no interceptors. Apr 23, 2024
@mrchaofan
Copy link
Author

ElectronURLLoaderFactory can be used for protocol intercept and protocol register. There are much differences. If start loading was called by intercept, the receiver is ProxyingURLLoaderFactory, so you can call remote to trigger it. But if it was called by protocol register, you can't call remote to attempt to take the benefit of the default behavior, the receiver is its self, that will lead to death loop. We should treat intercept and register differently.
I'm totally wrong. 😂 The issue dialog made me feel socially dead.

@mrchaofan mrchaofan marked this pull request as draft April 24, 2024 06:05
@mrchaofan mrchaofan marked this pull request as ready for review April 24, 2024 07:53
Copy link
Author

@mrchaofan mrchaofan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codebytere @nornagon If you have time, please could you review my code?
I've done my changes. I think I'm back on the right way to support that you can call callback() to call the Remote created in the ElectronBrowserClient::WillCreateURLLoaderFactory only if you are intercepting a protocol. If the new protocol you registered you can't, you have to call callback function with argument.

I changed the ProxingURLLoaderFactory to treat intercept differently from register a new protocol and updated test files.

And I see a test of webview-spec.ts failed. I think it's irrelevant.

@mrchaofan mrchaofan force-pushed the electron_url_loader_factory branch 2 times, most recently from b9196c2 to 8a667f0 Compare April 26, 2024 08:50
@electron-cation electron-cation bot removed the new-pr 🌱 PR opened in the last 24 hours label May 1, 2024
@Imperat
Copy link
Contributor

Imperat commented May 2, 2024

Hi @mrchaofan
Thanks for this change 🙏

@codebytere @nornagon I've add some test for protocol.interceptProtocol api. But It is a private api so I don't know how to write document for it. But It is ok to work with calling protocol.interceptHttpProtocol api.

Please just made relevant changes inside https://github.com/electron/electron/tree/main/docs/api 👍

@mrchaofan mrchaofan force-pushed the electron_url_loader_factory branch from 9493c25 to 2031c18 Compare May 2, 2024 12:55
@mrchaofan
Copy link
Author

@Imperat I've just updated the document and It seems electron.d.ts was automatically updated too.
@codebytere I think it is reasonable to do nothing in the protocol interception handler and just perform as if it hasn't been intercepted. But just for the interception. So I changes some codes to treat registration and interception differently.

@mrchaofan mrchaofan force-pushed the electron_url_loader_factory branch from 2031c18 to f21ba84 Compare May 2, 2024 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants