| 1818 | } |
| 1819 | |
| 1820 | void cbm_http_server_run(cbm_http_server_t *srv) { |
| 1821 | if (!srv || !srv->listener_ok) |
| 1822 | return; |
| 1823 | |
| 1824 | while (!atomic_load(&srv->stop_flag)) { |
| 1825 | cbm_http_conn_t *conn = cbm_httpd_accept(srv->listener, 200); |
| 1826 | if (!conn) |
| 1827 | continue; /* timeout — re-check stop flag */ |
| 1828 | |
| 1829 | uint64_t request_start_ms = cbm_now_ms(); |
| 1830 | cbm_http_req_t req; |
| 1831 | int rc = cbm_httpd_read_request(conn, &req); |
| 1832 | if (rc == 0) { |
| 1833 | dispatch_request(srv, conn, &req); |
| 1834 | cbm_log_http_request("graph_ui", req.method, req.path, cbm_http_conn_status(conn), |
| 1835 | (int64_t)(cbm_now_ms() - request_start_ms), req.body_len, |
| 1836 | cbm_http_conn_response_bytes(conn)); |
| 1837 | cbm_http_req_free(&req); |
| 1838 | } else if (rc > 0) { |
| 1839 | /* Parse/transport error with a known HTTP status (400/408/411/413/431). |
| 1840 | * No CORS reflection here — the request was never parsed. */ |
| 1841 | cbm_http_replyf(conn, rc, "", "bad request"); |
| 1842 | cbm_log_http_request("graph_ui", "", "", cbm_http_conn_status(conn), |
| 1843 | (int64_t)(cbm_now_ms() - request_start_ms), 0, |
| 1844 | cbm_http_conn_response_bytes(conn)); |
| 1845 | } |
| 1846 | cbm_httpd_conn_close(conn); |
| 1847 | } |
| 1848 | } |
| 1849 | |
| 1850 | bool cbm_http_server_is_running(const cbm_http_server_t *srv) { |
| 1851 | return srv && srv->listener_ok; |