Testing a small http-client on Linux using no_std & embedded reqwless.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add portability design for posix-libc and rustix backends

rektide 992c8f63 df9d8d3f

+148
+148
doc/portable.md
··· 1 + # Portability Plan: Linux and BSD 2 + 3 + This document proposes how to evolve this downloader from Linux-first to a portable Unix implementation that supports Linux and BSDs without changing the core HTTP flow. 4 + 5 + Current implementation references: 6 + 7 + - [`/src/main.rs`](/src/main.rs) 8 + - [`/Cargo.toml`](/Cargo.toml) 9 + - [`/README.md`](/README.md) 10 + 11 + ## Goals 12 + 13 + - Keep downloader logic backend-agnostic (`reqwless` + `embedded-nal-async` traits). 14 + - Support multiple platform backends: `posix-libc` and `rustix`. 15 + - Keep feature gating explicit and mutually exclusive where needed. 16 + - Preserve low-allocation behavior and fixed-buffer streaming. 17 + 18 + ## Backend Strategy 19 + 20 + We should support two backends with a single shared app layer. 21 + 22 + ### Backend 1: `posix-libc` 23 + 24 + - Best compatibility baseline for Linux + BSDs. 25 + - Straightforward access to `socket`, `connect`, `read/write`, `close`, `getaddrinfo`. 26 + - Good default while portability is the top priority. 27 + 28 + ### Backend 2: `rustix` 29 + 30 + - Safer syscall wrappers and stronger typing. 31 + - Better long-term ergonomics around low-level I/O. 32 + - DNS coverage is not identical to libc flows, so resolver strategy must be deliberate. 33 + 34 + ## DNS and Address Conversion Are Separate Problems 35 + 36 + We should treat these as separate design axes. 37 + 38 + ### Problem A: DNS Resolution 39 + 40 + Options: 41 + 42 + 1. `dns-getaddrinfo` (portable baseline) 43 + - Use libc `getaddrinfo` style resolution. 44 + - Works well for Linux + BSD. 45 + 2. `dns-ip-only` (minimal fallback) 46 + - Accept only literal IP hosts; reject names. 47 + - Useful for strict/minimal builds. 48 + 3. `dns-custom` (future) 49 + - Dedicated resolver implementation. 50 + - More control, higher complexity. 51 + 52 + Recommendation: start with `dns-getaddrinfo` for the portable baseline and keep `dns-ip-only` as a tiny fallback mode. 53 + 54 + ### Problem B: Address Conversion 55 + 56 + This means converting `core::net::SocketAddr` into backend-specific connect input. 57 + 58 + Options: 59 + 60 + 1. Backend-owned conversion (recommended) 61 + - `platform/posix_libc/addr.rs` owns libc sockaddr packing. 62 + - `platform/rustix/addr.rs` owns rustix address adaptation. 63 + - Keeps unsafe and ABI assumptions local to each backend. 64 + 2. Shared conversion module 65 + - One common converter to a raw sockaddr representation. 66 + - Less duplication, but can over-couple backends to one memory layout contract. 67 + 68 + Recommendation: start backend-owned. If patterns converge, extract shared pieces later. 69 + 70 + ## Proposed Structure 71 + 72 + Use domain-grouped layout (not flat): 73 + 74 + ```text 75 + src/ 76 + app/ 77 + main.rs 78 + download.rs 79 + net/ 80 + mod.rs 81 + traits.rs 82 + errors.rs 83 + platform/ 84 + mod.rs 85 + posix_libc/ 86 + mod.rs 87 + tcp.rs 88 + dns.rs 89 + addr.rs 90 + errno.rs 91 + rustix/ 92 + mod.rs 93 + tcp.rs 94 + dns.rs 95 + addr.rs 96 + runtime/ 97 + executor.rs 98 + fd_io.rs 99 + ``` 100 + 101 + - `app/`: URL handling, request flow, stdout streaming. 102 + - `net/`: shared adapter interfaces and error mapping. 103 + - `platform/`: backend-specific networking + DNS + address conversion. 104 + - `runtime/`: executor and FD utilities. 105 + 106 + ## Feature Model 107 + 108 + Suggested Cargo features: 109 + 110 + - `backend-posix-libc` (default) 111 + - `backend-rustix` 112 + - `dns-getaddrinfo` (default with `backend-posix-libc`) 113 + - `dns-ip-only` 114 + 115 + Build rules: 116 + 117 + - Exactly one backend must be enabled. 118 + - Exactly one DNS mode must be enabled. 119 + - Enforce at compile time with `compile_error!` guards. 120 + 121 + ## Integration Shape 122 + 123 + ```mermaid 124 + flowchart LR 125 + CLI[app/main] --> DL[app/download] 126 + DL --> NAL[embedded-nal-async traits] 127 + NAL --> SEL{backend feature} 128 + SEL --> LIBC[platform/posix_libc] 129 + SEL --> RUSTIX[platform/rustix] 130 + LIBC --> DNS{dns mode} 131 + RUSTIX --> DNS 132 + DNS --> OUT[stdout stream] 133 + ``` 134 + 135 + ## Practical Notes 136 + 137 + - Keep all `unsafe` inside backend modules only. 138 + - Keep error translation close to syscall sites. 139 + - Avoid backend-specific types leaking into `app/`. 140 + - Preserve fixed-size buffers and streaming body reads. 141 + 142 + ## Proposed Initial Default 143 + 144 + - Backend: `backend-posix-libc` 145 + - DNS: `dns-getaddrinfo` 146 + - HTTPS: optional feature (already added) 147 + 148 + This gives the best near-term Linux/BSD portability while leaving room to add `rustix` as a first-class backend without redesigning the app layer.