code wiki / (root) / nx_h2_client_over_tls.nx

nx_h2_client_over_tls.nx

buildroot/runtime/nx_h2_client_over_tls.nx

44335 B834 linesdepth 11pulls 42 transitivereach 12 importersview sourcekind tooltopic h2
docsdependenciesstructsconstsfunctions

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

nx_h2_conformance.nx nx_tls13_record.nx nx_tls13_read_record_from_fd.nx nx_tls13_client_session.nx nx_h2_client_over_tls.nx _h2_fetch_google.nx _h2_fetch_rumble.nx _h2_probe_imgsearch.nx _h2_probe_imgsearch_ua.nx _h2_reach_probe.nx nx_h2_server.nx

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

main hc_puts hc_synth_response h2_frame_write_settings_em h2_frame_write_header tls_write_u24_be h2_write_u32_be h2_frame_write_settings_ac h2_frame_write_header ↻ h2_frame_write_headers h2_frame_write_header ↻ h2_frame_write_data h2_frame_write_header ↻ h2_extract_status_and_body h2_frame_read_header tls_read_u24_be h2_read_u32_be h2_decode_status hpack_decode_int h2_status_from_static_inde hpack_decode_str hpack_decode_int ↻ h2_atoi_n hc_putn hpack_encode_lit_inc_index hpack_encode_int hpack_encode_str_raw hpack_encode_int ↻ h2_frame_write_headers ↻ h2_frame_write_data ↻ h2_stream_consume h2_frame_read_header ↻ h2_decode_status ↻ h2_frame_write_header ↻ sys_openat_append hc_fdn

structs

none

consts

51const NX_MAGIC_16645: i64 = 16645
52const NX_MAGIC_2048: i64 = 2048
53const NX_MAGIC_300000: i64 = 300000
54const NX_MAGIC_8192: i64 = 8192
55const NX_MAGIC_16384: i64 = 16384
56const NX_MAGIC_4096: i64 = 4096
304const NX_H2_STAGE_CAP: i64 = 65536

functions

59func 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
60func hc_putn(v: i64) -> i64
called by 1: main
68func hc_fdn(fd: i64, v: i64) -> i64
called by 1: main
90func h2_status_from_static_index(idx: i64) -> i64
called by 1: h2_decode_status
101func h2_atoi_n(buf: *u8, off: i64, len: i64) -> i64
called by 1: h2_decode_status
116func h2_decode_status(block: *u8, off: i64, lim: i64) -> i64
193func h2_extract_status_and_body(
240func h2_tls_send(s: *Tls13ClientSession, fd: i64, payload: *u8, n: i64) -> i64
268func h2_stream1_ended(buf: *u8, lim: i64) -> i64
336func h2_stream_consume(
417func h2_tls_get(
523func h2_tls_drain(s: *Tls13ClientSession, fd: i64, out_body: *u8, out_cap: i64, out_status: *i64) -> i64
587func h2_tls_get_ua(
609func hc_synth_response(resp: *u8, status_byte: i64, body: *u8, blen: i64, with_data: i64) -> i64
623func main() -> i64