refactor: network - harden TCP/IP and unify HTTP clients

This commit is contained in:
2026-07-29 15:35:17 +01:00
parent 75ae7ede56
commit a288dee7df
28 changed files with 1852 additions and 1361 deletions
+34 -4
View File
@@ -643,11 +643,16 @@ The allocator uses size-class buckets (32 to 4096 bytes) with an overflow list f
## Networking and HTTPS
MontaukOS provides a shared TLS library (`tls/tls.hpp`) backed by BearSSL, and the MontaukAI dev environment adds a higher-level HTTP wrapper (`http/http.hpp`) on top. Build with `USE_TLS=1` to link TLS support.
MontaukOS provides a shared TLS library (`tls/tls.hpp`) backed by BearSSL and
a higher-level HTTP client (`http/http.hpp`) used by system and third-party
applications. Build with `USE_TLS=1` to link TLS support.
### HTTP Wrapper (`http/http.hpp`)
Header-only library that handles DNS resolution, request building, TLS, response parsing, and cleanup. All functions return an `http::Response` struct.
Header-only library that handles DNS resolution, request building, TLS,
response parsing, and cleanup. It decodes chunked responses, validates
`Content-Length`, handles informational responses and partial I/O, and reports
a specific `http::Error`. All functions return an `http::Response`.
#### Setup
@@ -656,13 +661,14 @@ Header-only library that handles DNS resolution, request building, TLS, response
// Load CA certificates once at startup (required for HTTPS)
tls::TrustAnchors tas = tls::load_trust_anchors();
// Call tls::free_trust_anchors(&tas) during application shutdown.
```
#### GET
```cpp
auto resp = http::get("api.example.com", "/v1/data", tas);
if (resp.status == 200) {
if (resp.error == http::Error::NONE && resp.status == 200) {
// resp.body is a pointer to the response body
// resp.body_len is its length
}
@@ -743,6 +749,28 @@ http::free_response(&resp);
Set `g_quit = true` from your keyboard handler (e.g., on Escape) to cancel mid-request.
#### Generic HTTP/HTTPS Requests
Use `RequestOptions` for custom ports, cached DNS results, plain HTTP, or a
caller-owned response buffer:
```cpp
char response_buffer[65536];
http::RequestOptions options;
options.secure = true;
options.port = 8443;
options.resolved_ip = cached_ip; // zero asks the library to resolve the host
options.extra_headers = "Accept: application/json\r\n";
auto resp = http::request_into(
"GET", "api.example.com", "/large", nullptr, nullptr, 0, &tas,
response_buffer, sizeof(response_buffer), options);
if (resp.error != http::Error::NONE) {
// http::error_string(resp.error) is suitable for diagnostics
}
// response_buffer is caller-owned, so do not free_response(&resp).
```
#### Response Struct Reference
```cpp
@@ -754,6 +782,8 @@ struct http::Response {
int body_len;
char* raw; // Owned buffer — freed by free_response()
int raw_len;
http::Error error;
bool owns_raw;
};
```
@@ -798,7 +828,7 @@ int http::parse_response(char* buf, int len, http::Response* out);
bool http::get_header(const http::Response* resp, const char* name,
char* out_val, int max_len);
// Free the response's raw buffer
// Free the response's raw buffer when owns_raw is true
void http::free_response(http::Response* resp);
```