skip to content
==> src/http.c <==
1/* ui.rs's "6 http" section, ported. */
2#include "mesh/top_ui_http.h"
3
4#include "tui/utf8.h"
5
6#include <stdlib.h>
7#include <string.h>
8
9const char *mt_http_target(mt_frame *f, const mt_machine *m) {
10    const char *colon = strrchr(m->endpoint, ':');
11    const char *ep_host = colon ? tui_arena_strndup(f->a, m->endpoint, (size_t)(colon - m->endpoint)) : m->endpoint;
12    char bound[193] = "";
13    if (m->has_snap) mt_snapshot_host_str(&m->snap, MESH_S_HTTP_ADDR, 64, bound);
14    const char *c = strrchr(bound, ':');
15    if (!c) return MT_FMT(f, "%s:%u", ep_host, MESH_HTTP_PORT);
16    size_t il = (size_t)(c - bound);
17    if ((il == 7 && memcmp(bound, "0.0.0.0", 7) == 0) || (il == 4 && memcmp(bound, "[::]", 4) == 0)) return MT_FMT(f, "%s:%s", ep_host, c + 1);
18    return tui_arena_strdup(f->a, bound);
19}
20
21static void count_line(void *ctx, const char *line, size_t len) {
22    (void)line;
23    (void)len;
24    ++*(size_t *)ctx;
25}
26
27void mt_draw_http(mt_frame *f, tui_rect area, const mt_app *app) {
28    const mt_machine *m = mt_app_focused(app);
29    tui_color color;
30    tui_line title = mt_machine_title(f, m, true, "http: GET served by the GPU", &color);
31    tui_block block = mt_panel(f, title, color);
32    tui_rect inner = tui_block_inner(&block, area);
33    mt_block(f, &block, area);
34    tui_rect r[3];
35    tui_vsplit(inner, 3, (tui_constraint[]){TUI_LENGTH(4), TUI_LENGTH(3), TUI_FILL(1)}, r);
36    const char *path = *app->http_input ? app->http_input : "/";
37    const char *curl = MT_FMT(f, "curl -s http://%s%s", mt_http_target(f, m), path);
38    const mt_section *h = mt_machine_program(m, "http");
39    mt_lines lines = {0};
40    if (m->has_snap && h) {
41        const mt_snapshot *s = &m->snap;
42        char last[193];
43        mt_snapshot_host_str(s, MESH_S_LAST_HTTP, 64, last);
44        mt_lines_push(f, &lines,
45                      MT_LINE(f, mt_label("served by GPU "), mt_val(MT_FMT(f, "%u", mt_section_view_u32(h, MESH_HTTP_HV_SERVED))),
46                              mt_label("   relayed by meshd "), mt_val(MT_FMT(f, "%u", mt_snapshot_host_u32(s, MESH_S_HTTP_REQUESTS))),
47                              mt_label("   last code "), mt_val(MT_FMT(f, "%u", mt_section_view_u32(h, MESH_HTTP_HV_LAST_CODE))),
48                              mt_label("   http "), mt_styled(mt_section_state_name(h), mt_state_style(h))));
49        mt_lines_push(f, &lines, MT_LINE(f, mt_label("last request  "), mt_fgs(tui_arena_strdup(f->a, last), MT_ACCENT)));
50        mt_lines_push(f, &lines, MT_LINE(f, mt_label("try           "), mt_fgs(curl, MT_WARN)));
51    } else if (m->has_snap) {
52        mt_lines_push(f, &lines, tui_line_span(f->a, mt_styled(MT_FMT(f, " http is not loaded on %s ", mt_name(f, m)), mt_fg_bg_bold(MT_BG, MT_WARN))));
53    } else {
54        mt_lines_push(f, &lines, tui_line_span(f->a, mt_fgs(MT_FMT(f, "no snapshot (%s)", m->status), MT_WARN)));
55    }
56    mt_par(f, mt_text(f, &lines), r[0]);
57
58    tui_block ib = mt_panel(f, tui_line_span(f->a, mt_label(" path (Enter sends `http <path>`) ")), MT_ACCENT);
59    tui_paragraph ip = tui_paragraph_new(
60        tui_text_line(f->a, MT_LINE(f, mt_fgs("GET ", MT_DIM), mt_fgb(tui_arena_strdup(f->a, app->http_input), MT_FG), mt_fgs("█", MT_ACCENT))));
61    ip.block = &ib;
62    tui_paragraph_render(f->a, &ip, r[1], f->buf);
63
64    const char *body;
65    if (m->has_http_resp) {
66        size_t ln;
67        char *lossy = tui_utf8_lossy(m->http_resp, m->http_resp_len, &ln);
68        /* .replace("\r\n", "\n") */
69        char *o = tui_arena_alloc(f->a, ln + 1);
70        size_t k = 0;
71        for (size_t i = 0; i < ln; i++) {
72            if (lossy[i] == '\r' && i + 1 < ln && lossy[i + 1] == '\n') continue;
73            o[k++] = lossy[i];
74        }
75        o[k] = 0;
76        free(lossy);
77        body = o;
78    } else {
79        body = "(no response yet: press Enter)";
80    }
81    size_t total = 0;
82    tui_str_lines(body, count_line, &total);
83    tui_block rb = mt_panel(f, tui_line_span(f->a, mt_label(MT_FMT(f, " response  %zu lines  scroll %u ", total, app->http_scroll))), MT_FAINT);
84    tui_paragraph rp = tui_paragraph_new(tui_text_from_str(f->a, body));
85    rp.wrap = TUI_WRAP_KEEP;
86    rp.scroll_y = app->http_scroll;
87    rp.block = &rb;
88    tui_paragraph_render(f->a, &rp, r[2], f->buf);
89}