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
@@ -14,7 +14,7 @@
|
||||
#include <gui/svg.hpp>
|
||||
#include <gui/truetype.hpp>
|
||||
#include <gui/mtk.hpp>
|
||||
#include <tls/tls.hpp>
|
||||
#include <http/http.hpp>
|
||||
|
||||
extern "C" {
|
||||
#include <string.h>
|
||||
@@ -77,26 +77,6 @@ static bool g_tls_ready = false;
|
||||
static uint32_t g_server_ip = 0;
|
||||
static tls::TrustAnchors g_tas = {nullptr, 0, 0};
|
||||
|
||||
// ============================================================================
|
||||
// HTTP 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 || i + 3 >= len) return -1;
|
||||
i++;
|
||||
if (buf[i] < '0' || buf[i] > '9') return -1;
|
||||
return (buf[i]-'0')*100 + (buf[i+1]-'0')*10 + (buf[i+2]-'0');
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// JSON parsing
|
||||
// ============================================================================
|
||||
@@ -237,39 +217,27 @@ static void do_fetch() {
|
||||
g_tls_ready = true;
|
||||
}
|
||||
|
||||
static char request[512];
|
||||
int reqLen = snprintf(request, sizeof(request),
|
||||
"GET /?format=j1 HTTP/1.0\r\n"
|
||||
"Host: %s\r\n"
|
||||
http::RequestOptions options;
|
||||
options.resolved_ip = g_server_ip;
|
||||
options.extra_headers =
|
||||
"User-Agent: MontaukOS/1.0 weather\r\n"
|
||||
"Accept: application/json\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n",
|
||||
WTTR_HOST);
|
||||
|
||||
int respLen = tls::https_fetch(WTTR_HOST, g_server_ip, 443,
|
||||
request, reqLen, g_tas,
|
||||
g_resp_buf, RESP_MAX);
|
||||
if (respLen <= 0) {
|
||||
snprintf(g_status, sizeof(g_status), "Error: no response from server");
|
||||
"Accept: application/json\r\n";
|
||||
http::Response response = http::request_into(
|
||||
"GET", WTTR_HOST, "/?format=j1", nullptr, nullptr, 0, &g_tas,
|
||||
g_resp_buf, RESP_MAX, options);
|
||||
if (response.error != http::Error::NONE) {
|
||||
snprintf(g_status, sizeof(g_status), "Error: %s",
|
||||
http::error_string(response.error));
|
||||
g_phase = AppPhase::ERR; return;
|
||||
}
|
||||
g_resp_buf[respLen] = '\0';
|
||||
|
||||
int headerEnd = find_header_end(g_resp_buf, respLen);
|
||||
if (headerEnd < 0) {
|
||||
snprintf(g_status, sizeof(g_status), "Error: malformed HTTP response");
|
||||
if (response.status != 200) {
|
||||
snprintf(g_status, sizeof(g_status), "Error: HTTP %d from server",
|
||||
response.status);
|
||||
g_phase = AppPhase::ERR; return;
|
||||
}
|
||||
|
||||
int status = parse_status_code(g_resp_buf, headerEnd);
|
||||
if (status != 200) {
|
||||
snprintf(g_status, sizeof(g_status), "Error: HTTP %d from server", status);
|
||||
g_phase = AppPhase::ERR; return;
|
||||
}
|
||||
|
||||
const char* body = g_resp_buf + headerEnd;
|
||||
int bodyLen = respLen - headerEnd;
|
||||
const char* body = response.body;
|
||||
int bodyLen = response.body_len;
|
||||
|
||||
// Extract core weather fields
|
||||
static char temp_raw[16], feels_raw[16], code_raw[8];
|
||||
|
||||
Reference in new issue
Block a user