refactor: network - harden TCP/IP and unify HTTP clients
This commit is contained in:
1 parent
75ae7ede56
commit
a288dee7df
28 files changed
+1852
-1361
No files matched your search
+28
-85
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <montauk/syscall.h>
|
||||
#include <montauk/string.h>
|
||||
#include <tls/tls.hpp>
|
||||
#include <http/http.hpp>
|
||||
|
||||
extern "C" {
|
||||
#include <string.h>
|
||||
@@ -82,39 +82,15 @@ static bool check_keyboard_abort() {
|
||||
|
||||
// ---- HTTPS fetch wrapper ----
|
||||
|
||||
static int wiki_fetch(const char* path, char* respBuf, int respMax) {
|
||||
static char request[2560]; // keep off stack
|
||||
int reqLen = snprintf(request, sizeof(request),
|
||||
"GET %s HTTP/1.0\r\n"
|
||||
"Host: %s\r\n"
|
||||
static http::Response wiki_fetch(const char* path, char* respBuf, int respMax) {
|
||||
http::RequestOptions options;
|
||||
options.resolved_ip = g_serverIp;
|
||||
options.extra_headers =
|
||||
"User-Agent: MontaukOS/1.0 wiki\r\n"
|
||||
"Accept: application/json\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n",
|
||||
path, WIKI_HOST);
|
||||
return tls::https_fetch(WIKI_HOST, g_serverIp, 443,
|
||||
request, reqLen, g_tas,
|
||||
respBuf, respMax, check_keyboard_abort);
|
||||
}
|
||||
|
||||
// ---- HTTP response parsing ----
|
||||
|
||||
static int find_header_end(const char* buf, int len) {
|
||||
for (int i = 0; i + 3 < len; i++) {
|
||||
if (buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && buf[i+3] == '\n')
|
||||
return i + 4;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_status_code(const char* buf, int len) {
|
||||
int i = 0;
|
||||
while (i < len && buf[i] != ' ') i++;
|
||||
if (i >= len) return -1;
|
||||
i++;
|
||||
if (i + 2 >= len) return -1;
|
||||
if (buf[i] < '0' || buf[i] > '9') return -1;
|
||||
return (buf[i] - '0') * 100 + (buf[i+1] - '0') * 10 + (buf[i+2] - '0');
|
||||
"Accept: application/json\r\n";
|
||||
options.abort_check = check_keyboard_abort;
|
||||
return http::request_into("GET", WIKI_HOST, path, nullptr, nullptr, 0,
|
||||
&g_tas, respBuf, respMax, options);
|
||||
}
|
||||
|
||||
// ---- URL encoding ----
|
||||
@@ -725,23 +701,13 @@ extern "C" void _start() {
|
||||
"/w/api.php?action=query&format=json&formatversion=2"
|
||||
"&prop=extracts&explaintext=1&titles=%s", encoded);
|
||||
|
||||
int respLen = wiki_fetch(path, respBuf, RESP_MAX);
|
||||
if (respLen <= 0) {
|
||||
http::Response response = wiki_fetch(path, respBuf, RESP_MAX);
|
||||
if (response.error != http::Error::NONE) {
|
||||
montauk::print("\x01"); // error sentinel
|
||||
montauk::sleep_ms(100);
|
||||
montauk::exit(1);
|
||||
}
|
||||
respBuf[respLen] = '\0';
|
||||
|
||||
int headerEnd = find_header_end(respBuf, respLen);
|
||||
if (headerEnd < 0) {
|
||||
montauk::print("\x01");
|
||||
montauk::sleep_ms(100);
|
||||
montauk::exit(1);
|
||||
}
|
||||
|
||||
int statusCode = parse_status_code(respBuf, headerEnd);
|
||||
if (statusCode == 404) {
|
||||
if (response.status == 404) {
|
||||
montauk::print("\x01");
|
||||
montauk::sleep_ms(100);
|
||||
montauk::exit(1);
|
||||
@@ -749,8 +715,8 @@ extern "C" void _start() {
|
||||
|
||||
// Output raw JSON body in chunks to avoid overflowing
|
||||
// the 4KB kernel ring buffer (parent polls at ~60fps)
|
||||
const char* body = respBuf + headerEnd;
|
||||
int bodyLen = respLen - headerEnd;
|
||||
const char* body = response.body;
|
||||
int bodyLen = response.body_len;
|
||||
static char chunk[2049];
|
||||
int sent = 0;
|
||||
while (sent < bodyLen) {
|
||||
@@ -774,21 +740,13 @@ extern "C" void _start() {
|
||||
"/w/api.php?action=opensearch&search=%s&limit=10&format=json",
|
||||
encoded);
|
||||
|
||||
int respLen = wiki_fetch(path, respBuf, RESP_MAX);
|
||||
if (respLen <= 0) {
|
||||
http::Response response = wiki_fetch(path, respBuf, RESP_MAX);
|
||||
if (response.error != http::Error::NONE) {
|
||||
montauk::print("\033[1;31mError:\033[0m no response from Wikipedia\n");
|
||||
montauk::exit(1);
|
||||
}
|
||||
respBuf[respLen] = '\0';
|
||||
|
||||
int headerEnd = find_header_end(respBuf, respLen);
|
||||
if (headerEnd < 0) {
|
||||
montauk::print("\033[1;31mError:\033[0m malformed response\n");
|
||||
montauk::exit(1);
|
||||
}
|
||||
|
||||
const char* body = respBuf + headerEnd;
|
||||
int bodyLen = respLen - headerEnd;
|
||||
const char* body = response.body;
|
||||
int bodyLen = response.body_len;
|
||||
|
||||
static char titles[MAX_SEARCH_RESULTS][256];
|
||||
int titleCount = parse_search_titles(body, bodyLen, titles, MAX_SEARCH_RESULTS);
|
||||
@@ -831,8 +789,8 @@ extern "C" void _start() {
|
||||
snprintf(articlePath, sizeof(articlePath),
|
||||
"/api/rest_v1/page/summary/%s", articleEncoded);
|
||||
|
||||
respLen = wiki_fetch(articlePath, respBuf, RESP_MAX);
|
||||
if (respLen <= 0) {
|
||||
response = wiki_fetch(articlePath, respBuf, RESP_MAX);
|
||||
if (response.error != http::Error::NONE) {
|
||||
sb_reset();
|
||||
sb_cursor_to(infoRow, 3);
|
||||
sb_puts("\033[2K\033[1;31mFetch failed. Press any key.\033[0m");
|
||||
@@ -841,16 +799,10 @@ extern "C" void _start() {
|
||||
montauk::abi::KeyEvent ev; montauk::getkey(&ev);
|
||||
continue;
|
||||
}
|
||||
respBuf[respLen] = '\0';
|
||||
body = response.body;
|
||||
bodyLen = response.body_len;
|
||||
|
||||
headerEnd = find_header_end(respBuf, respLen);
|
||||
if (headerEnd < 0) continue;
|
||||
|
||||
int statusCode = parse_status_code(respBuf, headerEnd);
|
||||
body = respBuf + headerEnd;
|
||||
bodyLen = respLen - headerEnd;
|
||||
|
||||
if (statusCode == 404) {
|
||||
if (response.status == 404) {
|
||||
sb_reset();
|
||||
sb_cursor_to(infoRow, 3);
|
||||
sb_puts("\033[2K\033[1;31mArticle not found. Press any key.\033[0m");
|
||||
@@ -893,24 +845,15 @@ extern "C" void _start() {
|
||||
"&prop=extracts&explaintext=1&titles=%s", encoded);
|
||||
}
|
||||
|
||||
int respLen = wiki_fetch(path, respBuf, RESP_MAX);
|
||||
if (respLen <= 0) {
|
||||
http::Response response = wiki_fetch(path, respBuf, RESP_MAX);
|
||||
if (response.error != http::Error::NONE) {
|
||||
montauk::print("\033[1;31mError:\033[0m no response from Wikipedia\n");
|
||||
montauk::exit(1);
|
||||
}
|
||||
respBuf[respLen] = '\0';
|
||||
const char* body = response.body;
|
||||
int bodyLen = response.body_len;
|
||||
|
||||
int headerEnd = find_header_end(respBuf, respLen);
|
||||
if (headerEnd < 0) {
|
||||
montauk::print("\033[1;31mError:\033[0m malformed response\n");
|
||||
montauk::exit(1);
|
||||
}
|
||||
|
||||
int statusCode = parse_status_code(respBuf, headerEnd);
|
||||
const char* body = respBuf + headerEnd;
|
||||
int bodyLen = respLen - headerEnd;
|
||||
|
||||
if (statusCode == 404) {
|
||||
if (response.status == 404) {
|
||||
montauk::print("\033[1;31mArticle not found:\033[0m ");
|
||||
montauk::print(query);
|
||||
montauk::putchar('\n');
|
||||
|
||||
Reference in new issue
Block a user