nx_http_redirect.nx
buildroot/runtime/nx_http_redirect.nx
about
nx_http_redirect.nx -- HTTP 3xx redirect emitter.
Five sealed-enum redirect types per RFC 7231 §6.4:
301 Moved Permanently -- old URL is permanently gone; UA + cache
both update. Method MAY change to GET.
302 Found -- temporary; UA does not cache; some UAs
historically change POST->GET.
303 See Other -- POST-then-GET pattern. UA always
switches to GET. Standard for after-
form-submit.
307 Temporary Redirect -- like 302 but PRESERVES method (POST
stays POST). Per RFC 7231 §6.4.7.
308 Permanent Redirect -- like 301 but PRESERVES method. Per
RFC 7538.
Choice matrix:
permanent? method-preserving? -> 308
permanent? method-may-change? -> 301
temporary? method-preserving? -> 307
temporary? method-may-change? -> 302
POST-form-submit? -> 303
Substrate's structural safety:
- Location value is validated: REJECTS bytes that would inject
CR or LF into the response header (preventing CRLF injection
vulnerability class).
- Location value should ALSO be passed through scheme allowlist
to prevent open-redirect attacks; that's a CALLER decision
(substrate doesn't impose a policy).
Per cardinal feedback-no-third-party-trust-native-or-nothing:
substrate's own redirect emitter; no res.redirect() framework,
no nginx return-directive translation.
nx_capability_claims:
needs: [sealed_enum, byte_ops]
provides: [http_redirect_emit, crlf_injection_prevention]
safety: [no_unchecked_deref, no_floating_point, no_syscall,
bounded_iteration, crlf_injection_rejected]
dependencies 1 imports · 2 importers
imports: nx_syscalls_x86_64.nx
imported by: nx_cms_redirect_gate.nxnx_http_redirect_test.nx
structs
| none |
consts
| 47 | const NXR_MAGIC_1024: i64 = 1024 |
| 51 | const NXR_PERMANENT_301: i64 = 0 |
| 52 | const NXR_FOUND_302: i64 = 1 |
| 53 | const NXR_SEE_OTHER_303: i64 = 2 |
| 54 | const NXR_TEMP_307: i64 = 3 |
| 55 | const NXR_PERM_308: i64 = 4 |
| 56 | const NXR_KIND_N: i64 = 5 |
| 101 | const NXR_OK: i64 = 0 |
| 102 | const NXR_OOM_BUFFER: i64 = 1 |
| 103 | const NXR_BAD_LOCATION: i64 = 2 // CRLF or other unsafe byte |
| 104 | const NXR_BAD_ARG: i64 = 3 |
| 105 | const NXR_VERDICT_N: i64 = 4 |
functions
| 58 | func nxr_kind_is_valid(k: i64) -> i64 |
| 64 | func nxr_kind_status_code(k: i64) -> i64 |
| 73 | func nxr_kind_reason(k: i64) -> *u8 |
| 82 | func nxr_kind_reason_len(k: i64) -> i64 called by 1: nx_http_emit_redirect |
| 93 | func nxr_kind_is_permanent(k: i64) -> i64 |
| 107 | func nxr_verdict_is_valid(v: i64) -> i64 called by 1: main |
| 113 | func nxr_verdict_name(v: i64) -> *u8 |
| 131 | func nxr_location_is_safe(loc: *u8, loc_n: i64) -> i64 |
| 147 | func nxr_put(out: *u8, off: *i64, cap: i64, b: i64) -> i64 |
| 154 | func nxr_put_cstr(out: *u8, off: *i64, cap: i64, s: *u8) -> i64 |
| 164 | func nxr_put_bytes(out: *u8, off: *i64, cap: i64, src: *u8, n: i64) -> i64 |
| 175 | func nxr_put_int_3(out: *u8, off: *i64, cap: i64, v: i64) -> i64 |
| 198 | func nx_http_emit_redirect( |
| 250 | func nx_http_emit_redirect_to_https( |