ipfs / in-web-browsers

Tracking the endeavor towards getting web browsers to natively support IPFS and content-addressing
https://docs.ipfs.tech/how-to/address-ipfs-on-web/
MIT License
344 stars 29 forks source link

Leverage Service Worker and WebTransport on Public Gateways #207

Open lidel opened 1 year ago

lidel commented 1 year ago

This is a stub/meta issue for tracking work to leverage Service Workers (SW) as a fallback on public gateways.

cc historical SW threads for discovery: #57 https://github.com/ipfs/in-web-browsers/issues/171 https://github.com/ipfs/in-web-browsers/issues/158 https://github.com/ipfs/kubo/issues/4025 https://github.com/ipfs/in-web-browsers/issues/55

Broad strokes idea

Prior art

There are two ways one can fetch blocks:

I think the thing we want to create something robust that does do both, and use all public gateways as a fallback

Open questions

When SW is registered / used

First HTTP GET will always hit the gateway. Response could register worker and reload. Future requests will hit SW, as long they come from the same Origin (see "no foreign fetch" below)

No foreign fetch

:warning: before anyone gets too creative, read an understand fundamental limitation of ServiceWorkers: the lack of foreign fetch. tldr: this means SW is active only if the root document loaded in the browser comes from the same Origin.

Use case ideas

(A) Client-side recovery

When gateway returns error (list tbd, could be 429 and maybe also 502 503 and 504), and it knows request comes from web browser, return text/html response (https://github.com/ipfs/boxo/issues/262).

Augument text/html response to include an option to recover from page load error via a Service Worker IPFS node.

This is a good candidate for dipping our toes, does not impact "successful" flow, but allows for recovery from 429 Too Many Requests and Saturn CDN hiccups we will see in the near future.

Recovery could be based on Helia and WebTransport and/or verifiable HTTP block/car requests to public gateways

(B) Ability to register global worker

Giving user ability to prefer local JS for future requests, not only for errors, but all responses.

(C) Ability to isolate path gateway

We could do something related to https://github.com/ipfs/in-web-browsers/issues/157 where actual payload is loaded in sandboxed iframe

whizzzkid commented 1 year ago

Nice! @lidel a few questions:

First HTTP GET will always hit the gateway. Response could register worker and reload.

I am not sure how this would work, serviceWorker.register() can only be called from the navigator context. Which means, calling gateway directly won't register a service worker. To register a service worker, the gateway needs to be loaded explicitly which can call navigator.serviceWorker.register().

Giving user ability to prefer local JS for future requests

I feel the users should be oblivious to the fact where the content is being loaded from. This should be local first by-default and recover from a public gateway if needed.

Other Thoughts

lidel commented 1 year ago

[..] The gateway needs to be loaded explicitly which can call navigator.serviceWorker.register().

Yes, just like you noted, the idea is the gateway will return HTML that loads JS responsible for registering SW.

Initially, we would be doing that (A) on HTTP 502 and 504 error pages (show a button, which when clicked, registers worker, and reloads page). This allows us to figure out SW parts without having to implement full gateway (we only implement flat files).

I feel the users should be oblivious to the fact where the content is being loaded from. This should be local first by-default and recover from a public gateway if needed. [..] loads the gateway in an iframe [..]

Yes, that would be the endgame for same origin requests send by web browser for the root document. But I urge everyone to NOT focus on that, and instead prioritize MVP that will make (A) HTTP error recovery UX pleasant and useful.

Rationale: start with smaller scope, make things robust first, Reimplementing the full gateway spec in JS to support for anything other than flat deserialized files will be a lot of work, and we need to have a reliable way of testing (gateway tests are wip).

lidel commented 1 year ago

Dropping some thoughts on core pieces:

SgtPooki commented 1 year ago

2023-03-17 Discussion in weekly standup

End Goal

basic plan

potential showoff items

workstreams:

initial action items

open questions

callouts