|
| 1 | +# Implementation Notes for Browsers and URI parsers |
| 2 | + |
| 3 | +Below is the suggested heuristic for detecting content-addressed resources |
| 4 | +on the web, and presenting additional user interface for interacting with them. |
| 5 | + |
| 6 | +TBD if this document will live in this repo, https://docs.ipfs.tech or become part of https://github.com/ipfs/specs/ |
| 7 | + |
| 8 | +## Detecting IPFS Resources and Hints |
| 9 | + |
| 10 | +```mermaid |
| 11 | +graph TD |
| 12 | + Start[Top-level navigation event] |
| 13 | + IsGateway{Is it a Gateway URL?<br/>foo.tld/ip?s/id/..<br/>id.ns.foo.com/..} |
| 14 | +
|
| 15 | + Start -->|new URL in address bar| IsGateway |
| 16 | + IsGateway ==>|YES| IsPathOrSubdomain |
| 17 | + IsPathOrSubdomain -->|Path Gateway| ExtractFromPath |
| 18 | + IsPathOrSubdomain -->|Subdomain Gateway| ExtractFromSubdomain |
| 19 | +
|
| 20 | + subgraph GwURLToPath [Convert Gateway URL to a Content Path] |
| 21 | + IsPathOrSubdomain{Is the Gateway URL 'path' <br/> or 'subdomain' based?} |
| 22 | + ExtractFromPath[Extract URL.pathname] |
| 23 | + ExtractFromSubdomain[Read namespace and identifier from <br/> URL.hostname and prepend to URL.pathname. <br/> E.g., turn id.ns.foo.com/pathname <br/> into /ns/id/pathname] |
| 24 | + end |
| 25 | +
|
| 26 | + PotentialContentPath[Found a Potential Content Path] |
| 27 | +
|
| 28 | + ExtractFromPath --> PotentialContentPath |
| 29 | + ExtractFromSubdomain --> PotentialContentPath |
| 30 | + PotentialContentPath -->|/ipxs/id/sub/path..| IsIpfsOrIpns |
| 31 | +
|
| 32 | + subgraph PathValidation [Is the Content Path valid?] |
| 33 | + IsIpfsOrIpns{Is it /ipfs/ or /ipns/?} |
| 34 | + ValidateRootCID{Is 'id' is a valid CID?} |
| 35 | + ValidateIPNSKey{Is 'id' is a valid CID <br/> with libp2p-key codec?} |
| 36 | + ValidateDNSLink{Is 'id' a DNSLink name <br/> with TXT record? <br/> dnslink=/ipfs/<br/> or =/ipns/} |
| 37 | +
|
| 38 | + IsIpfsOrIpns --->|/ipfs/id/..| ValidateRootCID |
| 39 | + IsIpfsOrIpns -->|/ipns/id/..| ValidateIPNSKey |
| 40 | + ValidateIPNSKey -->|NO| ValidateDNSLink |
| 41 | + end |
| 42 | +
|
| 43 | + subgraph FoundValidIPFSContent [Confirmed we've found a Valid IPFS Resource] |
| 44 | + ValidIPFSCID[Valid /ipfs/cid/.. Content Path] |
| 45 | + ValidIPNSKey[Valid /ipns/key/.. Content Path] |
| 46 | + ValidDNSLink[Valid /ipns/dnslink/.. Content Path] |
| 47 | +
|
| 48 | + ValidateRootCID ===>|YES, /ipfs/cid/..| ValidIPFSCID |
| 49 | + ValidateIPNSKey ===>|YES, /ipns/key/..| ValidIPNSKey |
| 50 | + ValidateDNSLink ===>|YES, /ipfs/dnslink/..| ValidDNSLink |
| 51 | + end |
| 52 | +
|
| 53 | + subgraph NonGwURLToPath [See if non-Gateway URL has a Content Path] |
| 54 | + IsCachedDNSLink{Does URL.hostname <br/> match a cached <br/> DNSLink domain?} |
| 55 | + IsHeaderPresent{Is X-Ipfs-Path <br/> header present?} |
| 56 | + IsError{Did request fail? <br/> HTTP error>500 <br/> or network error} |
| 57 | + IsDNSLinkAtHostname{Does DNSLink exists <br/> at URL.hostname?<br/>/ipns/example.com} |
| 58 | + PathFromHeader[Read value from X-Ipfs-Path] |
| 59 | + end |
| 60 | +
|
| 61 | + IsGateway -->|NO| IsCachedDNSLink |
| 62 | + IsCachedDNSLink ==>|YES| ValidDNSLink |
| 63 | + IsCachedDNSLink -->|NO| IsHeaderPresent |
| 64 | + IsHeaderPresent ==>|YES| IsDNSLinkAtHostname |
| 65 | + IsHeaderPresent -->|NO| IsError |
| 66 | + IsError ==>|YES| IsDNSLinkAtHostname |
| 67 | + IsDNSLinkAtHostname ==>|YES| ValidDNSLink |
| 68 | + IsDNSLinkAtHostname -->|NO| PathFromHeader |
| 69 | + PathFromHeader --> PotentialContentPath |
| 70 | +``` |
| 71 | + |
| 72 | +## What to do with detected Content Paths? |
| 73 | + |
| 74 | +### Immutable `/ipfs/cid/..` |
| 75 | + |
| 76 | +- Display "Open via IPFS" button in UI |
| 77 | + - Clicking it should open `ipfs://cid/path?query#hash` (preserving any `?query` or `#hash` from the original HTTP URL) |
| 78 | +- If IPFS Gateway Redirect is enabled, and the HTTP URL was a gateway one, redirect automatically to `ipns://dnslink/path?query#hash` |
| 79 | + |
| 80 | +### Mutable `/ipns/key/..` |
| 81 | +- Display "Open via IPFS" button in UI |
| 82 | + - Clicking it should open `ipns://key/path?query#hash` (preserving any `?query` or `#hash` from the original HTTP URL) |
| 83 | +- If IPFS Gateway Redirect is enabled, and the original HTTP URL was a gateway one, redirect automatically to `ipns://dnslink/path?query#hash` |
| 84 | + |
| 85 | +### Mutable `/ipns/dnslink/..` |
| 86 | + |
| 87 | +- Display "Open via IPFS" button in UI |
| 88 | + - Clicking it should open `ipns://dnslink/path?query#hash` (preserving `?query` or `#hash` from the original HTTP URL) |
| 89 | +- If DNSLink Website redirect is enabled, redirect automatically to `ipns://dnslink/path?query#hash` |
| 90 | +- It is a good practice to internally cache the fact that domain has a valid DNSLink. |
| 91 | + - TTL from TXT record can be used as a hint when to expire cache entry. |
| 92 | + - Performance can be improved further by using cached flag and revalidating it asynchronously, without blocking browser navigation. |
0 commit comments