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

Cross-node serving

A node-prefixed URL means the same thing on every machine in the subnet. Paste http://localhost:5474/kitsubito/f/report.md into a browser on hfenduleam and the local daemon fetches the file from kitsubito and answers with it. Nothing is copied: the owner serves the bytes, and the requesting node keeps none of them.

How a peer’s URL is answered

The local listener resolves the first path segment. When it names a known subnet member (a node in this node’s roster, by its advertised label), the daemon opens one stream to that node and relays the owner’s answer:

  • The owner resolves the path through the same router its own listener uses, so a registered file is read at request time. An edit is visible on the next fetch; a removed entry or a deleted source answers the owner’s own 404.
  • HEAD returns the owner’s headers with no body. Content-Type is the owner’s.
  • A Range header is forwarded as-is. The owner answers 206 Partial Content with Content-Range; a range past the end answers 416 naming the length. The same grammar applies to a local file: bytes=a-b, bytes=a-, bytes=-n.
  • The body streams back in bounded chunks as the owner sends it. A large file never needs its size in memory on either node, and nothing is written under the requesting node’s $SPT_HOME.
  • The peer’s index page and its ?json twin are fetched the same way: /<peer>/ lists what that node serves.

Reserved facets stay router-first on the requesting node: /<peer>/f/ with no name, and the unbuilt m/, bin/ and install facets, are answered locally and open no stream.

Who decides: the owner

The owning node runs its WEB access check before serving anything. The origin it checks is the requesting node’s identity as proven by the transport handshake, never a value in the request. The subject is the endpoint that registered the entry, so a rule written against that endpoint governs its served files wherever they are fetched from. See Viewing access rules and posture for the WEB row.

What each status means

StatusBody starts withMeaning
200 / 206the owner’s bytesServed by the owner.
403ACCESS_DENIED: WEB:The owner’s access rules refuse this node. The body names the surface, not a sender: WEB carries no sender identity yet.
404NOT_FOUND: served resource <name>The owner has no such served name (or its source is gone).
404NO_DOCS_LANDED: or the docs page 404The first segment is not a known subnet member, so the request fell through to the local docs compatibility surface.
502NODE_UNAVAILABLE: <node>:The owner is a known member but could not be reached, dropped the stream, or never answered within the deadline. The body names the node and says why.

A 502 arrives within a bounded time. The dial and each read are held to the daemon’s peer deadlines, so an owner that is offline, or that runs a version without cross-node serving, produces an answer rather than a hang.

Trying it

On the owning node:

spt serve add ./report.md
spt serve list

On any other node in the subnet, using the owner’s node name:

curl -s http://localhost:5474/<owner>/f/report.md
curl -sI http://localhost:5474/<owner>/f/report.md
curl -s -r 0-3 http://localhost:5474/<owner>/f/report.md