feat(gateway): offer inbrowser.link, dweb's successor, alongside Filebase - #126
Merged
Conversation
…base
dweb.link is being switched off on 2026-09-21 and ALREADY redirects to
`<cid>.ipfs.inbrowser.link`, so that is where the traffic ends up either way.
The picker now offers that successor directly rather than a host about to
disappear. Filebase remains the default.
WHAT inbrowser.link ACTUALLY IS (measured 2026-09-12, not assumed)
It is a SERVICE-WORKER gateway, and it behaves unlike every other option:
* BROWSER-ONLY. A request without a browser User-Agent is refused with 403
(the body points at the self-hosting guide); with one it returns 200. So a
person opening the link sees the site, while social-preview crawlers,
indexers and any programmatic fetch are turned away. A link shared here
renders but shows no preview card.
* What it returns is an ~11KB bootstrap, not the content. A service worker
fetches the real bytes client-side.
* It is SUBDOMAIN-style, so a published site's relative asset references
cannot reach its assets -- they are on another host. The injected fallback
chain recovers them from an absolute gateway, so the site is fine, but
choosing this gateway moves the PAGE only, not its images. Verified live:
the image loaded with data-fx-try="1", i.e. via the chain.
Social previews are unaffected regardless of what a user picks, because
og:image is pinned to the SERVICE default gateway rather than the user's
template -- a decision made in pinning-service#94 that pays off here.
CONSEQUENT CHANGES
* `dweb` returns to `retiredTemplates`, so anyone still holding it is moved
to the default at startup. That is safe precisely BECAUSE it is no longer
offered: a template that is both offered and migrated away from would
silently revert on the next launch. The two sets must never intersect, and
a test pins that.
* `dweb` is removed from the Worker allowlist, so links pinned to `?gw=dweb`
fall back instead of pointing at a host being switched off.
* SUBDOMAIN_SAFE_CID is restored. `inbrowser` is the first subdomain-style
entry in the allowlist, and the CID lands in the HOSTNAME there, where a
case-sensitive CIDv0 (`Qm...`) or a CID past the 63-character DNS label
limit is silently mangled into a DIFFERENT cid. Such a CID is now served
from the default path-style gateway rather than a URL that cannot work.
Also removes a raw NUL byte from the Worker test file. It was written as a
literal control character instead of the escape \0 and shipped in 5245531,
which made git classify the file as BINARY -- its diffs were unreviewable in
both merged PRs and no reviewer could have caught anything by reading them. The
test's behaviour is unchanged: a raw NUL is exactly what the control-character
guard must reject, so it was testing the right thing for the wrong reason.
Tests: 39 worker (4 new for the subdomain hazard and the retired key), 30
gateway-helper, full Flutter suite, analyzer clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwMWmCivEpYTmmzzmjSTAf
ehsan6sha
force-pushed
the
feat/offer-dweb-choice
branch
from
September 12, 2026 18:05
34e9751 to
1e4f29b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dweb.link is switched off on 2026-09-21 and already redirects to
<cid>.ipfs.inbrowser.link, so that is where the traffic lands either way. The picker now offers that successor directly rather than a host about to disappear. Filebase remains the default.What inbrowser.link actually is (measured, not assumed)
It is a service-worker gateway, and that one fact drives everything below — the origin only ever ships a bootstrap, and the service worker fetches the real bytes from IPFS client-side.
On that last point: the fallback chain recovers the images from an absolute gateway, so the site is fine, but choosing this gateway moves the page, not its images. Verified live — the image loaded with
data-fx-try="1", i.e. via the chain.Social previews are unaffected by whatever a user picks, because
og:imageis pinned to the service default gateway rather than the user's template — a decision from pinning-service#94 that pays off here.Consequent changes
dwebreturns toretiredTemplates, so anyone still holding it is moved to the default at startup. Safe precisely because it is no longer offered — a template that is both offered and migrated away from would silently revert on the next launch. The two sets must never intersect, and a test pins that.dwebremoved from the Worker allowlist, so links pinned to?gw=dwebfall back instead of pointing at a host being switched off.SUBDOMAIN_SAFE_CIDrestored.inbrowseris the first subdomain-style entry, and there the CID lands in the hostname, where a case-sensitive CIDv0 (Qm…) or a CID past the 63-character DNS label limit is silently mangled into a different cid. Those now serve from the default path-style gateway instead of a URL that cannot work.Incidental fix
Removes a raw NUL byte from the Worker test file — written as a literal control character instead of the escape
\0and shipped in 5245531. It made git classify the file as binary, so its diffs were unreviewable in both previously merged PRs. Behaviour unchanged: a raw NUL is exactly what the control-character guard must reject, so it was testing the right thing for the wrong reason. (The diff here still shows binary because it is compared against the NUL version on main; subsequent diffs will be text.)Testing
39 worker (4 new: subdomain hazard, retired key) · 30 gateway-helper · 1081 Flutter ·
flutter build web --release✓ · analyzer clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01AwMWmCivEpYTmmzzmjSTAf