Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

sithbit-gateway: the IPFS HTTP gateway

Standard port(s): bind 8183, health 8198.

A read-only IPFS path gateway (GET/HEAD /ipfs/{cid}) serving mail blobs straight out of the same block/pin bucket the node writes — deserialized file bytes by default, trustless raw-block and CARv1 responses via ?format=raw|car (or the matching Accept types), with the standard immutable-caching, conditional-request, and range semantics of the IPFS gateway specs.

It is deliberately local-content-only: a CID whose blocks are not in the bucket answers 404 — the gateway never fetches foreign content from the IPFS network. Point [blobs] at the shared S3 bucket (or share the local ipfs/ directory) and it serves exactly what the node/cluster pinned, nothing else.

When you need it: only when pinned mail blobs should be fetchable over plain HTTP — a recipient’s client verifying an on-chain CID without running IPFS, a load-balancer-friendly read path in front of the bucket, or public retrievability without opening the swarm port. Mail delivery itself never needs it; sithbitd and decentralized clients read blobs through IPFS directly.

Quickstart:

cargo run -p ipfs-gateway

Config file ipfs_gateway.toml, or point IPFS_GATEWAY_CONFIG at an alternate path.

Subdomain (Host-based) gateway

Alongside the path gateway, sithbit-gateway can answer subdomain requests of the form <base32-cidv1>.ipfs.<public_host>, where the CID lives in the leftmost DNS label rather than the URL path. This is the gateway form that gives each CID its own web origin, so browsers isolate one blob’s scripts, cookies, and storage from another’s.

It is off by default. Turn it on by setting the base domain:

public_host = "example.com"

Left unset (the default), the gateway is path-only and the subdomain dispatch is a no-op on every request. With it set:

  • A Host of <label>.ipfs.example.com serves the CID named by <label>, reusing the exact same format negotiation (?format=raw|car), range, and caching behavior as the path route.
  • Both entry surfaces canonicalize to lowercase base32 CIDv1, matching Kubo:
    • Label surface. A Host whose label is a CIDv0 (base58) or otherwise non-canonical answers a 301 to the canonical host (//<base32-cidv1>.ipfs.example.com/…), preserving path and query.
    • Path→subdomain surface. A request to the bare public_host itself (Host: example.com) with a path of /ipfs/{cid} answers a 301 into the subdomain form: //<base32-cidv1>.ipfs.example.com/, scheme-relative, query preserved. This is the redirect Kubo issues to move a path request onto its own origin, so a blob reached by path lands on one stable origin too.
  • Only the bare subdomain root resolves. A sub-path under a subdomain host (.../some/file) returns 404 — mail blobs are single-file DAGs, so the gateway does no directory resolution.

This surface is conformance-tested against a live Kubo (v0.42.0) node, and the canonicalization on both surfaces now tracks it. Two deliberate, spec-legal differences remain:

  • Sub-path 404 shape. A path of /ipfs/{cid}/<sub> on the bare host is, on Kubo, a 301 into the subdomain followed by a 404 there; ours short-circuits to a direct 404 — same observable end state, one fewer hop (no directory resolution to attempt on a single-file DAG).
  • Location shape. Our redirects are scheme-relative (//host/…); Kubo emits absolute (https://host/…). Both are RFC 7231 §7.1.2-legal and resolve identically in browsers.

Honest scope: this surface is spec-conformance and future-proofing for a public deployment. The SithBit mail client fetches blobs by path (GET /ipfs/{cid}) and never needs subdomain origins; the subdomain gateway only adds the browser origin-isolation semantics that a general web-facing IPFS gateway is expected to provide, which this private, read-only gateway does not itself consume. Leave public_host unset unless you are exposing the gateway to third-party browsers.

See the Configuration reference for the full key/default table.