A reckoner seed: net's request/response half — machines/seeds/seednet.shoddy
NETGET fetches a URL from the prompt.
NETREQUEST sends whatever you like and hands back the whole
reply. NETALLOWED — seedbuiltin's,
not this seed's — says whether either can work at all. And
seedhttps is what takes a reply apart.
> "https://example.com/" NETGET HTTPBODY
x: "<!doctype html><html lang=\"en\"><head><title>Example Domain</title>…"
Three objections stood in the way, and only one was real.
| Objection | What became of it |
|---|---|
| The handle. A socket — a live network connection — must not reach the stack. | Never does. A request opens, talks and closes inside one word. Unlike a file or a window, there is no life between lines, so this seed does not use the resource table at all. |
The capability. The tree recorded this as decisive: --allow-net is not something a session can obtain half way through. | True, and it does not follow. A mill started with the flag has it. What was missing was a way to ask, since every socket builtin begins by aborting when the network is off. NetAllowed is that question, and it is deliberately not gated itself. |
| The aborts. | The real obstacle, and the largest. TCPSend and TCPRecv die eight ways between them on plain network faults, and TCPSecure takes the handle with it on a failed handshake. |
So the runtime guards the whole conversation, not the parts.
TryTcpRequest connects, optionally secures, sends, reads to
the end of the reply and closes. It answers Ok(reply) or
Err(why, 0). A bridge built from guarded pieces
would be a socket that must be closed on each of a dozen error paths, and
leaked on the one that was missed. Here the socket cannot outlive the
word, because every exit runs through the same close.
TryReadFile settled the same question the same
way: it guards a whole read rather than open/read/close.
It cannot hang, which matters more at a prompt than in
a program. net's own RecvAll polls
until the peer closes, so against a keep-alive server — one that
holds the connection open for the next request — it never returns.
A session would sit there with no way back. The runtime's read is bounded
by a deadline, and it gives back what it has.
A bare host means HTTPS. A bare host — an
address typed with no http:// or https:// in
front — means HTTPS on the modern web, so it means HTTPS here.
net's own HttpGet speaks plaintext on
port 80 and its header says as much. That is enough for a demo and not
enough for the web. Write http:// explicitly if that is what
you want.
This seed does not call net.
net's Request is Connect/Send/RecvAll/Close over the
aborting builtins. So net is the thing being replaced rather than
the thing being wrapped — exactly as
seedfile rebuilds ReadLines
rather than calling it.
What is not bridged: the server half —
Listen, Accept, Serve1 — and
the raw socket words. A listener is a live resource with a life between
lines, so it would want the named table. But a server that cannot run a
loop is not a server, and a reckoner line answers and ends. That is a
different design.
> NETALLOWED
x: True
> "https://example.com/" NETGET HTTPBODY
x: "<!doctype html>…"
> "example.com" NETGET ' a bare host is https
x: "HTTP/1.1 200 OK…"
> "http://example.com:8080/status" NETGET ' scheme and port both honoured
x: "…"
> "https://no.such.host.invalid/" NETGET
NETGET: CANNOT REACH 'no.such.host.invalid:443' (NO SUCH HOST)
> "example.com" 443 True "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n" NETREQUEST
x: "…"
Without --allow-net every fetch refuses with
THE NETWORK IS OFF — START THE MILL WITH --allow-net.
The session carries on either way. That refusal is the branch this seed
exists to make possible, and it used to be an abort.
| Word | Description |
|---|---|
| NETGET ( url -- str ) | Fetch a URL and answer the whole reply, headers and all. http:// and https:// both work, and a bare host is taken as HTTPS. A port in the URL is honoured. |
| NETREQUEST ( host port secure msg -- str ) | Send msg to host on that port, with TLS (the encryption layer behind https) when secure is True, and answer the whole reply. The raw form NETGET is built on, for a protocol that is not HTTP. |
There was a NETBODY here, and
seedhttps is where it went.
HTTPBODY is https's own and does the
job properly, so keeping both would have been the second spelling of a word
the dictionary already had.
The refusals are all answered before anything is dialled: a URL with no host, a port that is not a number, a port outside 1–65535, an argument of the wrong kind. The network being off is asked first of all, so that the message can name the remedy rather than reading like the host's fault.
| User | How | |
|---|---|---|
| halifax | The calculator's fetch words. Without --allow-net they refuse and say so, which is an ordinary answer at a prompt. | |
| sparky | Sparky folds it too, and it is the whole of the server's network surface: the request half is bridged and the server half is not. |
A mill claims this seed by folding RckSeedNet over its
reckoner state, which is all halifax does.
| Machine | Why | |
|---|---|---|
| cuttle | The Cell type the reply crosses the bridge as. | |
| reckoner | RckReg and the argument readers every registered word is built from. | |
| seq | Pair, for reading the arguments the two-and-more-argument words take. | |
| str | StartsWith, for telling a scheme from a bare host. |
Not net itself, and that is the
point: its Request is built on the aborting builtins, so this
seed replaces it rather than calling it.