nx_nishipages_serve.nx
buildroot/runtime/nx_nishipages_serve.nx
about
nx_nishipages_serve.nx -- sovereign self-contained static server for
nishi-pages.
Built per operator directive 2026-06-30: "build the apis that will do
what you are trying to do in shell" + "sovereign live server first".
WHY SELF-CONTAINED (not composing nx_pages_static / nx_http_server):
those modules pull nx_syscalls.nx, which needs nx_syscalls_x86_64.nx
for __syscall/sys_mmap -- but the two modules BOTH define 26 of the
same sys_* symbols, so any organ pulling both double-emits every
sys_* label and `as` rejects the duplicate (this is exactly why the
"shipped" nx_audit_server_* organs do not assemble on the current
toolchain). nx_syscalls.nx has 6098 importers, so it cannot be
edited. We therefore import ONLY the leaf x86_64 syscall layer
(every socket + file syscall, zero further imports) plus the pure,
import-free CWE-22 canonicalizer. Result: no symbol overlap, clean
link, fully sovereign.
Serves the whole dist/ tree with clean URLs:
"/" -> dist/index.html
"/foo/" -> dist/foo/index.html
"/foo" -> dist/foo (file) else dist/foo/index.html else dist/foo.html
"/a/b.ext" -> dist/a/b.ext (literal; MIME by extension, incl. .wasm)
Path traversal (../, NUL, backslash, leading /) is rejected by
nx_path_canonicalize before any file is opened -- defense at the boundary.
Build (x86_64 native Linux ELF):
cd nishi-core/nxc2
./nxc2.exe --target x86_64 runtime/nx_nishipages_serve.nx > /tmp/nps.s
wsl bash -c "gcc -no-pie /tmp/nps.s -o /tmp/nx_nishipages_serve"
Run from the nishi-pages checkout so the relative "dist" root resolves:
cd nishi-pages && /tmp/nx_nishipages_serve # listens on :8090
nx_capability_claims:
needs: [x86_64_syscalls, cwe_22_canonicalize]
provides: [nishipages_static_serve, clean_url_routing,
full_dist_tree_serve, wasm_mime]
safety: [cwe_22_canonicalize_at_boundary, get_only,
bounded_request_buffer, no_floating_point,
jpl_rule2_bounded_accept_loop]
dependencies 2 imports · 0 importers
imports: nx_syscalls_x86_64.nxnx_path_canonicalize.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 50 | const NPS_MAGIC_2048: i64 = 2048 |
| 51 | const NPS_MAGIC_2040: i64 = 2040 |
| 53 | const NPS_PORT: i64 = 8090 |
| 54 | const NPS_BACKLOG: i64 = 128 |
| 55 | const NPS_REQ_CAP: i64 = 16384 |
| 56 | const NPS_BUDGET: i64 = 1000000 // JPL-rule-2 bounded accept loop |
functions
| 60 | func nps_strlen(s: *u8) -> i64 |
| 67 | func nps_write_all(fd: i64, buf: *u8, n: i64) -> i64 |
| 79 | func nps_puts(buf: *u8, off: i64, s: *u8) -> i64 called by 1: nps_send_200 |
| 92 | func nps_putdec(buf: *u8, off: i64, v: i64) -> i64 called by 1: nps_send_200 |
| 116 | func nps_cat(dst: *u8, a: *u8, a_n: i64, b: *u8) -> i64 called by 1: nps_serve |
| 130 | func nps_ends_with(s: *u8, n: i64, suf: *u8, suf_n: i64) -> i64 called by 1: nps_mime |
| 140 | func nps_mime(path: *u8, n: i64) -> *u8 |
| 159 | func nps_has_ext(rel: *u8, rel_n: i64) -> i64 called by 1: nps_serve |
| 170 | func nps_send_404(cfd: i64) -> i64 |
| 176 | func nps_send_405(cfd: i64) -> i64 |
| 184 | func nps_send_200(cfd: i64, mime: *u8, body: *u8, body_n: i64) -> i64 |
| 201 | func nps_try_file(rel: *u8, rel_n: i64, body_pp: **u8, len_p: *i64) -> i64 |
| 220 | func nps_serve(cfd: i64, path: *u8, path_n: i64) -> i64 |
| 270 | func nps_handle(cfd: i64) -> i64 |
| 295 | func main() -> i64 |