mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
The stack could already reach the real internet once the UDP-checksum and
scheduler fixes landed; this makes it work on real-world URLs and gives the
desktop a first-class "is the internet up?" answer.
HTTP client
- Follows 3xx redirects (Location header, absolute or relative) up to five
hops, so a bare host that 301s to a path or a canonical host resolves to
actual content. Verified: `webget google.com/` follows the 301 to
www.google.com and returns its HTTP 200 homepage.
- Refuses https:// targets -- at the initial URL and on redirect -- with a
clear message instead of speaking plaintext to port 443 and timing out.
- Split the URL parser out so both the initial request and redirect targets
go through the same path; added a case-insensitive header finder.
netcheck (CLI)
One command that walks the whole chain -- link, address, gateway ping, DNS,
and a real HTTP fetch -- and reports each PASS/FAIL, ending in ONLINE or
DEGRADED. The one-shot answer to "is the internet working?".
Network Monitor (GUI)
A live Internet: ONLINE/OFFLINE badge with the resolved IP, HTTP status and
latency. It auto-probes once on open and re-checks on the Check button, all
through the async HTTP worker so the window never blocks.
Verified against the real internet through QEMU's NAT: DNS resolved
example.com to a live Cloudflare address; `netcheck` passed all five layers
(Internet: ONLINE); the GUI badge showed "ONLINE 104.20.23.154 HTTP 200 240
ms"; redirect following and the HTTPS refusal both behaved. Builds clean on
x86_64, aarch64 and armv8i.
Known limit: no TLS, so HTTPS URLs are reported rather than fetched -- plain
HTTP only.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
68 lines
2.9 KiB
C
68 lines
2.9 KiB
C
#ifndef _NET_HTTP_CLIENT_H
|
|
#define _NET_HTTP_CLIENT_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
// Asynchronous HTTP/1.0 client.
|
|
//
|
|
// The TCP client calls (tcp_connect/tcp_send/tcp_recv) all busy-wait against
|
|
// the timer tick, so calling them from an interactive context -- the GUI
|
|
// compositor above all -- would freeze it for the length of the fetch. This
|
|
// module runs every fetch on one long-lived kernel worker thread instead: the
|
|
// requester posts a job and polls its state, and the compositor keeps painting
|
|
// at full rate while the worker blocks.
|
|
//
|
|
// Ownership follows the state. While a job is HTTP_STATE_RUNNING the worker
|
|
// owns it; once it is DONE or ERROR the requester owns it again. The requester
|
|
// hands a job back with http_fetch_release, which frees it now if the fetch has
|
|
// finished, or marks it abandoned so the worker frees it when it does -- so a
|
|
// window can close mid-fetch without leaking or use-after-free.
|
|
|
|
typedef enum {
|
|
HTTP_STATE_RUNNING = 0, // worker owns the job
|
|
HTTP_STATE_DONE, // completed; buf holds the response
|
|
HTTP_STATE_ERROR // failed; err holds a short reason
|
|
} http_fetch_state_t;
|
|
|
|
typedef struct http_fetch {
|
|
// Request, filled in by http_fetch_start from the parsed URL.
|
|
char host[128];
|
|
char path[256];
|
|
uint16_t port;
|
|
bool tls; // the URL asked for https, which we cannot speak
|
|
|
|
// Result. `state` is the only field the requester may read while the fetch
|
|
// is in flight; everything else is valid once state != RUNNING.
|
|
volatile int state; // http_fetch_state_t
|
|
volatile bool abandoned; // requester released it mid-flight; worker frees
|
|
|
|
char* buf; // response bytes (status line, headers, body)
|
|
int len; // bytes stored
|
|
int cap; // buffer capacity
|
|
|
|
uint32_t ip; // resolved peer address (of the final hop)
|
|
int status_code; // parsed HTTP status, 0 if not found
|
|
uint32_t elapsed_ms; // wall time of the whole fetch
|
|
int redirects; // number of 3xx hops followed
|
|
char err[96]; // human-readable failure reason
|
|
} http_fetch_t;
|
|
|
|
// Start the worker thread. Call once at boot, after the TCP stack is up.
|
|
void http_client_init(void);
|
|
|
|
// Begin fetching `url` (forms: "host", "host/path", "host:port/path", with an
|
|
// optional "http://" prefix). `cap` bounds the stored response. Returns a job
|
|
// to poll, or NULL if the URL is unusable or a fetch is already in flight.
|
|
http_fetch_t* http_fetch_start(const char* url, int cap);
|
|
|
|
// Give a job back. Frees it if the fetch has finished; otherwise marks it so
|
|
// the worker frees it on completion. The pointer must not be used afterwards.
|
|
void http_fetch_release(http_fetch_t* f);
|
|
|
|
// True while the worker thread is busy with a fetch.
|
|
bool http_client_busy(void);
|
|
|
|
#endif // _NET_HTTP_CLIENT_H
|