nx_https_url_for_fetch.nx source
↩ module page · 122 lines · 4784 B
1// nx_https_url_for_fetch.nx -- step 1 of the HTTPS fetch
2// orchestrator: parse + validate an HTTPS URL.
3//
4// Phase 0b §I.5 piece 1 of the nx_https_client wiring arc. Takes
5// a NUL-terminated URL string, calls the shipped nx_url_parse to
6// get its components, validates that scheme == "https", and
7// defaults port to 443 when unspecified. Returns a populated
8// NxHttpsTarget that the rest of the fetch pipeline consumes.
9//
10// This is a deliberately tiny primitive -- the next-step orchestrator
11// (queued: nx_https_url_connect.nx, which does URL+DNS+TCP into a
12// connected socket) composes this on top. Per Cardinal 22
13// (composition over configuration): small primitives stack into
14// a working HTTPS fetcher.
15//
16// Public API:
17// struct NxHttpsTarget {
18// url: *NxUrl, -- shipped from nx_url
19// port: i64, -- resolved (default 443)
20// }
21// nx_https_url_for_fetch(url_str, out_target) -> verdict
22// nx_https_url_verdict_is_valid(v) -> 0|1
23//
24// Sealed verdict enum:
25// NX_HTTPS_URL_OK parse + scheme + port all good
26// NX_HTTPS_URL_BAD_PARSE nx_url_parse returned negative
27// NX_HTTPS_URL_WRONG_SCHEME scheme != "https"
28// NX_HTTPS_URL_BAD_PORT port out of valid range
29//
30// Currently rejects http:// -- this primitive is HTTPS-only. An
31// "http or https" variant for non-secure fetches is queued
32// separately (nx_http_url_for_fetch.nx).
33//
34// Per Cardinals 9 (single-responsibility -- step 1 only; DNS / TCP /
35// TLS are separate steps), 12 (defensive at boundaries -- scheme
36// + port range checks), 23 (preamble names the queued variants).
37//
38// license_tier: INDEPENDENT_REDERIVE
39// genealogy_id: international-research-sources/ietf/rfc_3986
40// lineage_id: nishi_https_url_for_fetch_q10
41
42// nx_safety_envelope:
43// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
44// sil_target: SIL1
45// evidence: [bulk_applied_2026-05-19, https-url-fetch-step-1]
46// verdict: NOT_YET_EVALUATED
47
48import "nx_syscalls.nx"
49import "nx_url.nx"
50const NX_MAGIC_65535: i64 = 65535
51
52const NX_HTTPS_URL_OK: i64 = 1
53const NX_HTTPS_URL_BAD_PARSE: i64 = 2
54const NX_HTTPS_URL_WRONG_SCHEME: i64 = 3
55const NX_HTTPS_URL_BAD_PORT: i64 = 4
56const NX_HTTPS_URL_VERDICT_N: i64 = 5
57
58const NX_HTTPS_DEFAULT_PORT: i64 = 443
59
60struct NxHttpsTarget {
61 url: *NxUrl,
62 port: i64,
63}
64
65func nx_https_url_verdict_is_valid(v: i64) -> i64 {
66 if v < NX_HTTPS_URL_OK { return 0 }
67 if v >= NX_HTTPS_URL_VERDICT_N { return 0 }
68 return 1
69}
70
71// Returns 1 if the buffer at scheme_off..scheme_off+scheme_len bytes
72// equals ASCII "https" (case-insensitive, RFC 3986 §3.1).
73// scheme_off here refers to position WITHIN url_str.
74func _scheme_is_https(url_str: *u8, scheme_off: i64, scheme_len: i64) -> i64 {
75 if scheme_len != 5 { return 0 }
76 // Case-insensitive compare against "https"
77 let c0: i64 = url_str[scheme_off] & 0xff
78 let c1: i64 = url_str[scheme_off + 1] & 0xff
79 let c2: i64 = url_str[scheme_off + 2] & 0xff
80 let c3: i64 = url_str[scheme_off + 3] & 0xff
81 let c4: i64 = url_str[scheme_off + 4] & 0xff
82 // To-lower: if 'A'..'Z' add 0x20
83 var l0: i64 = c0; if c0 >= 0x41 { if c0 <= 0x5A { l0 = c0 + 0x20 } }
84 var l1: i64 = c1; if c1 >= 0x41 { if c1 <= 0x5A { l1 = c1 + 0x20 } }
85 var l2: i64 = c2; if c2 >= 0x41 { if c2 <= 0x5A { l2 = c2 + 0x20 } }
86 var l3: i64 = c3; if c3 >= 0x41 { if c3 <= 0x5A { l3 = c3 + 0x20 } }
87 var l4: i64 = c4; if c4 >= 0x41 { if c4 <= 0x5A { l4 = c4 + 0x20 } }
88 if l0 != 0x68 { return 0 } // 'h'
89 if l1 != 0x74 { return 0 } // 't'
90 if l2 != 0x74 { return 0 } // 't'
91 if l3 != 0x70 { return 0 } // 'p'
92 if l4 != 0x73 { return 0 } // 's'
93 return 1
94}
95
96// Parse URL + populate NxHttpsTarget. out_target.url must be a
97// caller-allocated NxUrl pointer (use nx_url_new()).
98func nx_https_url_for_fetch(url_str: *u8, out_target: *NxHttpsTarget) -> i64 {
99 let rc: i64 = nx_url_parse(url_str, out_target.url)
100 if rc != 0 { return NX_HTTPS_URL_BAD_PARSE }
101
102 if _scheme_is_https(url_str, out_target.url.scheme_off, out_target.url.scheme_len) != 1 {
103 return NX_HTTPS_URL_WRONG_SCHEME
104 }
105
106 // Default port = 443 if unspecified. nx_url_parse sets port = 0
107 // when no ":port" was in the URL.
108 if out_target.url.port == 0 {
109 out_target.port = NX_HTTPS_DEFAULT_PORT
110 } else {
111 if out_target.url.port < 1 { return NX_HTTPS_URL_BAD_PORT }
112 if out_target.url.port > NX_MAGIC_65535 { return NX_HTTPS_URL_BAD_PORT }
113 out_target.port = out_target.url.port
114 }
115
116 return NX_HTTPS_URL_OK
117}
118
119// Compile-only smoke. Real KAT in nx_https_url_for_fetch_test.nx.
120func main() -> i64 {
121 return 0
122}