Closed olizilla closed 1 year ago
Oh wow, a lot to unpack here.
After reading the draft with proposed changes I wrote down some highlights with interesting changes and potential pain points (below).
Will follow V3 as it unfolds, but it is very likely it will bring us additional maintenance cost.
In Manifest V3, this API will be discouraged (and likely limited) in its blocking form. The non-blocking implementation of the
webRequest
API, which allows extensions to observe network requests, but not modify, redirect, or block them (and thus doesn't prevent Chrome from continuing to process the request) will not be discouraged. As an alternative, we plan to provide adeclarativeNetRequest
API . The details of what limitations we may put in thewebRequest
API are to be determined. [..]
- While deciding whether a request is to be blocked or redirected, the
declarativeNetRequest
API is given priority over thewebRequest
API because it allows for synchronous interception.
- Evaluation of
declarativeNetRequest
rulesets is performed during theonBeforeRequest
stage of a network request.
We use blocking capability of webRequest
API to inspect headers, detect IPFS resources, do DNSLink lookups and other things – src/lib/ipfs-companion.js#L95-L97:
browser.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, { urls: ['<all_urls>'] }, ['blocking', 'requestHeaders'])
browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, { urls: ['<all_urls>'] }, ['blocking'])
browser.webRequest.onHeadersReceived.addListener(onHeadersReceived, { urls: ['<all_urls>'] }, ['blocking', 'responseHeaders'])
Personally I don't think this change will stick in the form proposed in the draft as having declarativeNetRequest
as the only blocking option makes it impossible to write things like uBlock Origin or uMatrix, which could create terrible PR for Google, given their Ad business.
If the worst comes to the worst, for the basic functionality we may be okay with declarativeNetRequest
and some elaborate rules for redirecting https?://*/ip(f|n)s/*
and https?://*.ip(f|n)s.*/
, but supporting DNSLink in current seamless form may be difficult/impossible (or would require user action/opt-in per site).
We plan to replace background pages with ServiceWorkers, registered at install time and granted access to extension APIs. [..] We will be able to reduce the amount of extension-specific code since, instead of implementing a custom background-running presence, we can extend the existing ServiceWorker context. Most importantly, the platform will evolve with the open web; as improvements to ServiceWorkers and the web platform are made, the extensions platform benefits from those same improvements.
We need a stable, persistent background presence to be able to run embedded js-ipfs node. It does not sound like SeviceWorkers, which is often killed by the browser when idle. I hope there will be an inexpensive and reliable way to keep SW alive in WebExtension context.
If not, @Gozala had some ideas on keeping ServiceWorker alive in https://github.com/ipfs/in-web-browsers/issues/137#issuecomment-450530548, but the net result will be to actually use more CPU by artificially keeping it alive than when having a background page.
In Manifest V3, host permissions will be granted by the user at runtime (similar to activeTab, but with options for the user to choose to always run on a specific site or all sites), rather than install-time.
In Manifest V3, we want activeTab-style host permissions to be the default, with a number of extra options. Instead of being granted access to all URLs on installation, extensions will be unable to request
<all_urls>
, and instead the user can choose to invoke the extension on certain websites, like they would withactiveTab
. Additional settings will be available to the user post-installation, to allow them to tweak behavior if they so desire.[..] In the default case (click-to-run), it is clear to the user when the extension is running, and has a safe default (not running on any site). When the user chooses to invoke the extension on a given site, there is implicit understanding that the extension will "see" the contents of the page.
This sounds bad, as it suggests by default it will be click-to-run, but in later section about host permissions support for <all_urls>
is described as open question:
Open question: Should
activeTab
be removed in favor of specifyingin the host_permissions key of the manifest?
Also, this blogpost from 2018 suggests how the UI will look like:
Beginning in Chrome 70, users will have the choice to restrict extension host access to a custom list of sites, or to configure extensions to require a click to gain access to the current page.
Beginning in Manifest V3, content scripts will not be given special privileges regarding the requests they can make. If a content script needs access to data fetched from a cross-origin server that requires authentication, it can proxy the request through its background page using extension messaging.
As long they limit this restriction to Content Scripts, we should be fine.
We do CORS-but-not-really to IPFS API only from the background page. "Not really" because we remove Origin header from requests made to API URL by js-ipfs-http-client running in WebExtension context to remove need for manual whitelisting via Access-Control-Allow-Origin
at go-ipfs: src/lib/ipfs-request.js#L119-L151.
Extension APIs will be promise-based. The older callback version will continue to be supported.
I was about to say its cool, as there will be no need for mozilla/webextension-polyfill, but we will probably need a polyfill for all the other breaking changes. Time will tell, so far issues to follow:
browser.*
to match the WebExtensions specwe can allow extensions to dynamically add and remove, or enable and disable, content scripts. This would allow extensions to only add these scripts once they have permission to do so.
There are additional situations in which this is beneficial, as well. Currently, the advice for extensions wishing to dynamically inject scripts based on some knowledge at runtime is to use the
tabs.executeScript API
; however, this is insufficient for certain use cases. In particular, this cannot (reliably) insert a script before the page finishes loading, which is a feature that content scripts provide. Allowing dynamic content scripts would solve this use case.
This is good news, as it would solve issue with window.ipfs
described in https://github.com/ipfs-shipyard/ipfs-companion/issues/362#issuecomment-362231167
(browser.contentScripts
works in Firefox, but it's not implemented in Chrome yet)
Additional work and duplicated code, but nothing critical.
Sad realization: even if Firefox follows these V3 API changes, for some time it won't, while Chromium will, so it will be like writing websites in 90s with similar level of code duplication for achieving the same thing in two different browsers :|
ps. what a perfect issue number :ok_hand:
If not, @Gozala had some ideas on keeping ServiceWorker alive in ipfs/in-web-browsers#137 (comment), but the net result will be to actually use more CPU by artificially keeping it alive than when having a background page.
Note that keeping SW alive is going to be an arms race with browsers. Also was proposing for Safari (As replacement for SharedWorker due to lack of it) is different as you'll have a clients (documents served from it) which is considered as legitimate case.
Personally I don't think this change will stick in the form proposed in the draft as having
declarativeNetRequest
as the only blocking option makes it impossible to write things like uBlock Origin or uMatrix, which could create terrible PR for Google, given their Ad business.
Not so sure about it, they might ship their own content blocker (that would likely don't harm their Ad business) and call it a day https://bugs.chromium.org/p/chromium/issues/detail?id=896897&desc=2#c23
I'm not sure if there are some way to engage with the corresponding people driving these changes but I think best bet would be to convince them to expose SharedWorker (or equivalent) for long lived tasks or maybe an official API that would provide a way to keep ServiceWorker alive.
Extensions Developer Advocate at Chrome is doing office hours! I grabbed the very first free slot (April 12, 16:30 UTC).
My plan is to give an overview of what ipfs-companion does, potential API improvements and our concerns around Manifest V3.
Update: We gave a brief demo and an overview of our needs during the office hours.
There is still a lot of unknowns around Manifest V3 (especially no details on if/how Service-Worker-like API is going to replace JS process running in persistent background pages).
As for webRequest
, activeTab
and <all_urls>
Privacy Badger team has written up some relevant requests for changes: Chrome team requests-Privacy Badger.pdf
We need to wait until another draft is published to see if our concerns are adressed.
not sure if it's related to this but looks like it by the APIs involved:
on chromium Version 71.0.3578.98 (Developer Build) (64-bit)
the extension breaks on activation with the attached log from the background script: nibjojkomfdiaoajekhjakgkdhaomnch-1555915381867.log
Some updates/clarifications from Simeon (Extensions Developer Advocate): https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/veJy9uAwS00/9iKaX5giAQAJ
[.. ] I want to emphasize that the Manifest V3 design document is not exhaustive or immutable. The extensions team is pursuing the goals outlined in this design document and iterating on design and implementation details. The best way for developers to really understand the changes is to experiment with the Manifest V3 platform.
[..] the extensions team is currently working on a Developer Preview of Manifest V3. Our goal with this preview is to give developers a way to start experimenting with some of the most significant changes to the platform in order to provide targeted feedback.
When they ship Developer Preview, we will prototype a port and see how V3 impacts Companion in practice, but based on analisys from Raymond Hill (uBlockOrigin) I would not be too optimistic:
The blocking ability of the webRequest API is still deprecated, and Google Chrome's limited matching algorithm will be the only one possible, and with limits dictated by Google employees
It's annoying that they keep saying "the webRequest API is not deprecated" as if developers have been worried about this -- and as if they want to drown the real issue in a fabricated one nobody made. – https://github.com/uBlockOrigin/uBlock-issues/issues/338#issuecomment-496009417
Response from the Ghostery team suggests the manifest v3 performance claim does not hold. https://whotracks.me/blog/adblockers_performance_study.html tl;dr degradation is milliseconds at worst
Update from Google https://blog.chromium.org/2019/06/web-request-and-declarative-net-request.html
Chrome provides enterprise controls through its administrator policies. The blocking version of the Web Request API remains available for managed extensions because of the deep integrations that enterprises may have between their software suites and Chrome.
Pretty bad news, means current onBeforeRequest
it won't work out of the box and we need to re-implement entire redirect logic using "The Declarative Net Request API"
The Declarative Net Request API now allows for the registration and removal of dynamic rules - specified at runtime rather than statically in the manifest. We’ve also added the capability to remove common tracking headers, such as Referer, Cookie, and Set-Cookie.
In our case the devil is in the details.
Setting up a crude redirect of /ipfs/{cid}
paths with this API should work fine. When changing gateway Companion would remove/add new redirect rule for /ipfs/*
paths.
Problem: we lose ability to do CID validation, so we need to work round false-positives.
We could do DNSLink check in non-blocking onBeforeRequest
and add redirect rules based on that (similar to current best-effort strategy, but it will continue to yield false-negatives on initial request.
We may lose ipfs://
handler done via search-query hack, so would be great if real handler landed before that happens:
Shall see when Developer Preview lands.
Related discussion thread: https://groups.google.com/a/chromium.org/forum/#!msg/chromium-extensions/qFNF3KqNd2E/8R9PWdCbBgAJ
A number of extension developers have reached out to ask how Mozilla plans to respond to the changes proposed in v3. Following are answers to some of the frequently asked questions.
ipfs-companion/issues/808: Permanent in-depth review on Chrome Web Store:
Google makes it more and more difficult to publish powerful extensions such as IPFS Companion.
In preparation for Manifest v3 (https://github.com/ipfs-shipyard/ipfs-companion/issues/666) Chrome Web Store artificially slows down publishing of extensions that requesti access to certain APIs.
Chrome team rolled out Manifest V3 into Canary: https://groups.google.com/a/chromium.org/forum/#!msg/chromium-extensions/hG6ymUx7NoQ/TiAe0gI5AQAJ
In order to help developers start experimenting with and transitioning to MV3 we've put together a migration guide. This doc provides a high-level look at what's changing and what developers will need to do to adapt. We also have a guide specifically for migrating from background pages to service workers.
I will dig into this deeper next week, but from a quick read it seems we need to refactor most of Companion to support both V2 (Brave, Firefox) and V3 (Google Chrome, future Chromium). It is unclear if we will be able to persist an embedded js-ipfs node in V3 at all.
Quick API Checklist vs Impact on IPFS Companion (:ballot_box_with_check: means YES)
chrome.tabs.executeScript({code: '...'})
, eval()
, or new Function()
in background contexts or content scripts? Redirects with V3 are broken at the moment:
Manifest V3 now seems inevitable. After we wrap ongoing work in Q4, should build a PoC.
Adblocker Dev Summit 2020
- Some history of ad blocking and limitations of declarative filtering approach on Apple platforms: https://www.youtube.com/watch?v=_dduavvDj6s
- Status of Manifest v3 in Firefox: https://www.youtube.com/watch?v=tpDFS-GUytg
- Status update on Chrome side: https://www.youtube.com/watch?v=zxWG2yUcTFA
Originally posted in https://github.com/uBlockOrigin/uBlock-issues/issues/338#issuecomment-725727365
Google, Microsoft, Apple, and Mozilla have launched the WebExtensions Community Group (WECG) to collaborate on standardizing browser extensions:
Working towards removing annoying differences between vendors is a good news, it also means the direction of "Manifest V3" is no longer controlled by Google on their own, and Microsoft's experiments with PWA and protocol handlers have some overlap with our use cases.
Thin on details, time will tell if we end up in better place.
Mozilla will implement it as well: https://blog.mozilla.org/addons/2021/05/27/manifest-v3-update/
As of this writing, we are hoping to complete enough work on this project to support developer testing in Q4 2021 and start accepting v3 submissions in early 2022.
Google published Manifest V2 support timeline
Over the past week or so I've been familiarizing myself with the current ipfs-companion
extension and the limits of the manifest v3 spec.
I've put together a repo of very basic prototypes of local node redirects with DeclarativeNetRequest
and ServiceWorker
. Most of the pros and cons have been documented above but I've included the most glaring from this experiment below.
👉 Repo https://github.com/meandavejustice/ipfs-mv3-prototype
Pros:
Cons:
Pros:
Cons:
I had a misunderstanding around the removal of <all_urls>
. We can still access the urls we need with "https://*/"
and "http://*/"
being added to host_permissions
key.
This makes me feel much better about our options here. I will add a prototype of adding new rules with updateDynamicRules
api to https://github.com/meandavejustice/ipfs-mv3-prototype shortly. (this is essentially what @lidel describes above in https://github.com/ipfs/ipfs-companion/issues/666#issuecomment-502072347)
Opinion piece from EFF: https://www.eff.org/deeplinks/2021/11/manifest-v3-open-web-politics-sheeps-clothing
I've added a branch to ipfs-mv3-prototype to support dnslink domains.
Steps used are:
/api/v0/dns
to confirm the domain has a dnslink mapping.updateDynamicRules
method.When running the extension you'll see a console message with the rule id, domain, and cid. On next load of the domain it will be redirected to local gateway.
This exposed our limitation of making requests to the IPFS API, we need to have a way to update the Access-Control-Allow-Origin
headers. We used to do this with the onBeforeSendHeaders
listener, but we've lost that with the webRequest blocking api. This is being tracked in #1036
For the record, two years later (https://github.com/ipfs/ipfs-companion/issues/666#issuecomment-590852186), redirects and UI updates based on navigation with Manifest V3 are still effectively broken in Chromium:
chrome.tabs.onUpdated.addListener
or chrome.webRequest.onCompleted.addListener
reliably because stopped service worker (background page) does not get wake up correctly every time.
@lidel Re
service worker (background page) does not get wake up correctly every time.
i18n.getMessage
not supported in mv3 extensions
tracking => https://bugs.chromium.org/p/chromium/issues/detail?id=1268098
EDIT: Looks like it was fixed at end of January, just hasn't showed up in stable yet. Will verify in chromium latest
https://bugs.chromium.org/p/chromium/issues/detail?id=1268098#c13
Filed issue with chromium tracker for matching ipfs://
protocol urls with the declarativeNetRequest api https://bugs.chromium.org/p/chromium/issues/detail?id=1306869
I thought I had filed this issue last week, turns out I didn't so here is the new one => https://bugs.chromium.org/p/chromium/issues/detail?id=1309190
Above is an issue documenting running into the limits of regexFilter
in declarativeNetRequest
Bugzilla meta issue for MV3 last updated 9 months ago
I've had some trouble logging into Mozilla's replacement for IRC, https://wiki.mozilla.org/Matrix, I've reached out to friend who's at mozilla to try and get some info on MV3 status.
Manifest v3 in Firefox: Recap & Next Steps (https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-firefox-recap-next-steps/):
Mozilla will maintain support for blocking WebRequest in MV3. To maximize compatibility with other browsers, we will also ship support for declarativeNetRequest.
we have decided to support Event Pages in MV3, and our developer preview will not include Service Workers (we’re continuing to work on supporting these for a future release).
Work is continuing in parallel, and we expect to launch MV3 support for all users by the end of 2022.
HN discussion: AdGuard publishes the first ad blocker built on Manifest V3
Timeline changed! Google postpones MV2 shutoff in Chrome stable to June 2023:
- Starting in January in Chrome 112, Chrome may run experiments to turn off support for Manifest V2 extensions in Canary, Dev, and Beta channels.
- Starting in June in Chrome 115, Chrome may run experiments to turn off support for Manifest V2 extensions in all channels, including stable channel.
- In January 2023, use of Manifest V3 will become a prerequisite for the Featured badge as we raise the security bar for extensions we highlight in the store.
In June 2023, the Chrome Web Store will no longer allow Manifest V2 items to be published with visibility set to Public. All existing Manifest V2 items with visibility set to Public at that time will have their visibility changed to Unlisted.
HN discussion: https://news.ycombinator.com/item?id=33012057
In January 2024, following the expiration of the Manifest V2 enterprise policy, the Chrome Web Store will remove all remaining Manifest V2 items from the store.
Rather strong language there. Clearly the owners.
Here's an idea: Create your own MV2 developer site. We are already on GitHub...
It’s like they say - if the system fails you, you create your own system. - Michael K. Williams, Black Market
Mozilla finally started accepting MV3 on their store starting November 21:
Starting November 21, 2022 add-on developers are welcome to upload their Firefox Manifest version 3 (MV3) compatible extensions to addons.mozilla.org (AMO) and have them signed as MV3 extensions.
This is good news, means for the first time we can make a MV3 release and publish the same code to both Mozilla and Google.
@tinytb @lidel https://groups.google.com/a/chromium.org/g/chromium-extensions/c/zQ77HkGmK9E
We get some breathing room here, pushed to March '23
Thanks @ricmk
The work we're doing for mv3 has been mostly encapsulated into a singular issue at https://github.com/ipfs/ipfs-companion/issues/1152
@whizzzkid do we still need this issue?
Update on March 29, 2023: https://groups.google.com/u/0/a/chromium.org/g/chromium-extensions/c/zQ77HkGmK9E
Looks like MV3 deadline has been moved forward.
@whizzzkid : what are the conditions for closing this issue? We have an answer for "what to do about Manifest v3" that is being tracked in https://github.com/ipfs/ipfs-companion/issues/1152 . Can we resolve this and have the updates related to the rollout occur there?
Implementation Plan exists: https://github.com/ipfs/ipfs-companion/issues/1152
Work is in progress!
Work happening in https://github.com/ipfs/ipfs-companion/pull/1182, let's keep this open until it lands in main
.
For anyone still watching this issue for updates on Manifest V3, Google resumed the Manifest V2 deprecation plan.
We will begin disabling Manifest V2 extensions in pre-stable versions of Chrome (Dev, Canary, and Beta) as early as June 2024, in Chrome 127 and later.
Enterprises using the ExtensionManifestV2Availability policy to ensure the continued functioning of Manifest V2 extensions in their organization will have one additional year - until June 2025 - to migrate the Manifest V2 extensions in their organization.
More details in https://developer.chrome.com/blog/resuming-the-transition-to-mv3/
As flagged by @dignifiedquire the proposed webextention api changes under the banner of the v3 manifest work will reduce the scope of what ipfs-companion is able to do to bring ipfs to the browser
Proposed changes: https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit?usp=sharing
Tracking issue: https://bugs.chromium.org/p/chromium/issues/detail?id=896897&desc=2
Most significant is the move away from the webRequest api to the declarativeNetRequest api https://developer.chrome.com/extensions/declarativeNetRequest
The
webRequest
api is blocking. Chromium asks the webextention what to do about each outbound http request at runtime. IPFS Companion makes use of this to let the user toggle between redirecting ipfs addresses to a local daemon or the public gateway.The
declarativeNetRequest
requires extentions to tell chromium in advance, what urls patterns they wish to block or redirect by defining them statically as rules in themanifest.json
There may well be other important changed for us in that doc, but this one stands out as the most significant.