Files
rose-ash/next/kernel/http_server.erl
giles b45ea2aa16
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s
fed-sx-m1: Step 8b-route — http_server:route/1 pure dispatch + ok/not_found helpers + 11 tests
2026-05-28 08:06:01 +00:00

50 lines
1.7 KiB
Erlang

-module(http_server).
-export([route/1, ok_response/1, not_found_response/0, welcome_body/0]).
%% HTTP request router per design §16.1.
%%
%% Request shape (mirrors what the SX-side `http-listen` builds and
%% the http:listen/2 BIF bridge marshals into a proplist):
%% [{method, Binary}, {path, Binary}, {query, Binary},
%% {headers, [{Name, Value}, ...]}, {body, Binary}]
%%
%% Response shape:
%% [{status, Integer}, {headers, [{Name, Value}, ...]}, {body, Binary}]
%%
%% Real dispatch (actor docs, outbox listings, /activity POST,
%% /.well-known/sx-capabilities, etc.) lands in Step 8c+. Step 8b
%% wires the route/1 shape and a single hello-world handler that
%% proves the request→response round-trip.
%%
%% Method/path comparison uses integer-segment binaries because
%% `<<"GET">>` truncates to a single byte in this port.
route(Req) ->
M = field(method, Req),
P = field(path, Req),
dispatch(M, P).
%% 71 69 84 = "GET" | 47 = "/"
dispatch(<<71, 69, 84>>, <<47>>) ->
ok_response(welcome_body());
dispatch(_, _) ->
not_found_response().
%% "fed-sx kernel m1\n" — 17 bytes, hand-spelled.
%% f e d - s x _ k e r n e l _ m 1 \n
welcome_body() ->
<<102,101,100,45,115,120,32,107,101,114,110,101,108,32,109,49,10>>.
ok_response(Body) ->
[{status, 200}, {headers, []}, {body, Body}].
not_found_response() ->
[{status, 404}, {headers, []},
{body, <<110,111,116,32,102,111,117,110,100,10>>}]. % "not found\n"
%% Internal property-list field lookup. Returns nil when missing
%% so the route falls into the not_found arm gracefully.
field(K, [{K, V} | _]) -> V;
field(K, [_ | Rest]) -> field(K, Rest);
field(_, []) -> nil.