ipfs-shipyard / service-worker-gateway-2019-poc

[ARCHIVED] 2019 PoC of IPFS gateway fully running on a Service Worker. For modern (2024+) version see https://github.com/ipfs-shipyard/service-worker-gateway
MIT License
61 stars 11 forks source link

Exposing API instance when embedded via iframe #30

Open lidel opened 5 years ago

lidel commented 5 years ago

Part of https://github.com/ipfs/in-web-browsers/issues/55

Background

I remember having a brief discussion about this workaround with someone in the past but I think we were hoping foreign fetch will land, so it never went anywhere. Now that foreign fetch got removed from ServiceWorker spec we should revisit and look into this once again.

Summary

So the idea is we could avoid having multiple instances of js-ipfs being spawned by ipfs-service-workers running on multiple pages by exposing API of a single service-worker-gateway's instance (eg. js.ipfs.io) over iframe's postMessage+ipfs-postmsg-proxy making all those SW instances talk to that one js-ipfs instance instead of spawning their own.

Example

Additional context extracted from https://github.com/arewedistributedyet/arewedistributedyet/issues/32#issuecomment-438859014:

  • Use of "iframe + SW" as I described earlier was also proposed. I was also pointed out that "embedding limitation" I was concerned with could be addressed in few different ways:

    • Embedding images or other self contained files isn't a huge deal you could obtain ArrayBuffer for it and then make blob url to embed.
    • For things like CSS / JS that imports other stuff, little more tricky but doable sever steps:
      1. App e.g. peerpad.net can register own service worker.
      2. App can embed hidden iframe for ipfs.io which registers IPFS node as service worker.
      3. App obtains MessagePort though iframe from ipfs.io service worker and transfers it to own service worker.
      4. Now two service workers have message channel for direct exchange which allows peerpad.net to serve any content from IPFS through it's SW by forwarding data from message channel.

Prior Discussions

hugomrdias commented 5 years ago

https://github.com/ipfs/developer-meetings/blob/master/sessions/deep-dive/service-worker.md

Berlin dev meetings we did a deep dive, would love to prototype this with anyone interested.

vasco-santos commented 5 years ago

We discussed this in Berlin and we got some nice conclusions

The main problem that I remember is having the same repo shared for different web apps, allowing them to get data from each other. I discussed this with someone after the presentation

Gozala commented 5 years ago

I just want to point out there is also some interesting and not very obvious opportunity with this:

  1. This might eliminate need for including any of the ipfs-js stuff into your app, as long as ipfs-node API is exposed via service worker. Which additionally has some benefits / concerns - On one hand IPFS could push out upgrades and it's automatically deployed everywhere, but on the other it would require a way for apps build with it to stay on older version for sometime.

  2. IPFS companion extension also will be free to just target that API iframe rather than everything. And users of IPFS node won't need to know or care.

  3. You could layer permissions management on top of all this. And make user in control of what data is being stored on the node and what apps have access to what.

  4. This also provides an opportunity to let user configure to interact with say other gateway of choice.

Gozala commented 5 years ago

The main problem that I remember is having the same repo shared for different web apps, allowing them to get data from each other. I discussed this with someone after the presentation

Hi @vasco-santos could you provide little more details on this ? I think allowing data to be shared is useful no ? But restrictions on what is and isn't shared is important indeed & I think that should be part of the node's responsibility to manage. When embedded requests an API MessagePort iframe can decide what to expose per embedders origin.

vasco-santos commented 5 years ago

Hey @Gozala you just provided all the details 😀

We ended up not having time to discuss how we would tackle those restrictions, and it is still an open problem that we need to think. So, that is the point that we need to revisit for going with this new step. Thanks for your suggestion, I feel it may be a good direction.

lidel commented 5 years ago

@hugomrdias ah, thank you for the link! I remember I proposed that session but missed it due to scheduling conflict 😞


I had some initial success with iframe+sw, Service Worker seems to work in iframe as long parent page belongs to Secure Context (https or localhost), and parent page is able to access it over ipfs-postmsg-proxy (x2!):

iframe-working-2018-11-22--02-15-12

(note that iframe has different Origin due to port number)

I will post updates later this week, need to do some additional tests and cleanup first, but so far looks really promising.

Gozala commented 5 years ago

just posting this link here https://github.com/ipfs/in-web-browsers/issues/137 due to relevancy