nx_h2_client_over_tls.nx
buildroot/runtime/nx_h2_client_over_tls.nx
about
nx_h2_client_over_tls.nx -- TUTOR-BOOTSTRAP SCAFFOLD (Claude, authored under
the R4-H2 HTTP/2-transport-ladder workflow, capstone NBC-FETCH-001), NOT
credited as team self-authoring.
THE HTTP/2 CLIENT REQUEST/RESPONSE DRIVER carried over the sovereign TLS 1.3
application-data channel. Given a CONNECTED *Tls13ClientSession whose ALPN
negotiated "h2" (via nx_tls13_client_session_run_h2), it performs ONE HTTP/2
GET:
send (one TLS app-data record): preface + empty SETTINGS + HEADERS(stream 1,
END_STREAM|END_HEADERS) wrapping an HPACK GET block (= h2_build_client_open)
+ a SETTINGS-ACK once the peer SETTINGS arrives.
recv (loop TLS records -> decrypt -> append to an h2 frame buffer):
walk frames, HPACK-decode the response HEADERS block's :status, and
reassemble DATA payloads into the body until END_STREAM.
The h2 frame bytes ARE the allowed internet-boundary (RFC 9113/7541 dictate the
octets); the implementation is pure NishiLang -- no nghttp2, no openssl.
FOUNDED ON (composes, does NOT reinvent -- anti-orphan law; imported EXACTLY
ONCE each, RC6 double-import avoided):
- nx_h2_conformance.nx (R4-H2-006, GREEN): h2_build_client_open + the frame
builders/reader + HPACK encoders/decoders + flow windows, all pulled
transitively through its single import (it splices h2_flow -> h2_frame ->
hpack -> str -> syscalls, plus h2_stream and tls13_ext).
- nx_tls13_record.nx: AEAD app-data encrypt/decrypt (nx_tls13_record_*_v2).
- nx_tls13_read_record_from_fd.nx: one inbound TLS record (partial-read framer).
- nx_tls13_client_session.nx: the *Tls13ClientSession struct (app keys/iv/seq).
nx_tls13_record / read_record / client_session all transitively import
nx_tls13.nx and nx_syscalls.nx -- included once by the linker guards.
BACK-FILL: the team RE-AUTHORS this from the DATA spec
(knowledge/specs/2026-06-13-http2-transport-ladder.md) via the
emitter-of-emitters (X-AUT-006c/e/f); this hand scaffold is the sanctioned
one-time bootstrap only (meter-integrity, mirror nx_h2_conformance.nx:1-4).
GATE (main): synthesizes a server h2 response with OUR frame builders (peer
SETTINGS + SETTINGS-ACK + HEADERS :status 200 = HPACK 0x88 + DATA "hello h2"
END_STREAM), feeds it through h2_extract_status_and_body, and asserts the
recovered :status == 200 and the exact reassembled body, byte-for-byte. PLUS a
TAMPER case on a SEPARATE buffer: a HEADERS block carrying :status 404 must
recover 404 (not silently coerced to 200), and a body-less END_STREAM HEADERS
dependencies 4 imports · 6 importers
imports: nx_h2_conformance.nxnx_tls13_record.nxnx_tls13_read_record_from_fd.nxnx_tls13_client_session.nx
imported by: _h2_fetch_google.nx_h2_fetch_rumble.nx_h2_probe_imgsearch.nx_h2_probe_imgsearch_ua.nx_h2_reach_probe.nxnx_h2_server.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 51 | const NX_MAGIC_16645: i64 = 16645 |
| 52 | const NX_MAGIC_2048: i64 = 2048 |
| 53 | const NX_MAGIC_300000: i64 = 300000 |
| 54 | const NX_MAGIC_8192: i64 = 8192 |
| 55 | const NX_MAGIC_16384: i64 = 16384 |
| 56 | const NX_MAGIC_4096: i64 = 4096 |
| 304 | const NX_H2_STAGE_CAP: i64 = 65536 |
functions
| 59 | func hc_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } called by 1: main |
| 60 | func hc_putn(v: i64) -> i64 called by 1: main |
| 68 | func hc_fdn(fd: i64, v: i64) -> i64 called by 1: main |
| 90 | func h2_status_from_static_index(idx: i64) -> i64 called by 1: h2_decode_status |
| 101 | func h2_atoi_n(buf: *u8, off: i64, len: i64) -> i64 called by 1: h2_decode_status |
| 116 | func h2_decode_status(block: *u8, off: i64, lim: i64) -> i64 |
| 193 | func h2_extract_status_and_body( |
| 240 | func h2_tls_send(s: *Tls13ClientSession, fd: i64, payload: *u8, n: i64) -> i64 |
| 268 | func h2_stream1_ended(buf: *u8, lim: i64) -> i64 calls 1: h2_frame_read_header |
| 336 | func h2_stream_consume( |
| 417 | func h2_tls_get( |
| 523 | func h2_tls_drain(s: *Tls13ClientSession, fd: i64, out_body: *u8, out_cap: i64, out_status: *i64) -> i64 |
| 587 | func h2_tls_get_ua( |
| 609 | func hc_synth_response(resp: *u8, status_byte: i64, body: *u8, blen: i64, with_data: i64) -> i64 |
| 623 | func main() -> i64 |