The server and support headers are included:
#include <vws/server.h> #include "vwsx.h"
The handler answers every request with the same body. It receives the
server, the connection id, the parsed
vws_http_msg (unused here),
and the worker context, and returns a bool:
static bool process(vws_svr* s, vws_cid_t cid, vws_http_msg* msg, void* ctx)
{
(void)msg;
(void)ctx;
const char* body = "Hello world";
size_t body_len = strlen(body);
char response[256];
int n = snprintf(response, sizeof(response),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %zu\r\n"
"\r\n"
"%s",
body_len, body);The full HTTP response — status line, headers, and body — is formatted into
a local buffer. The Content-Length is computed from
body_len rather than hardcoded, so the header always matches
the payload. The formatted bytes are then copied onto the heap and handed to a
response object, which is sent:
char* data = (char*)vws.malloc((size_t)n);
memcpy(data, response, (size_t)n);
vws_svr_data* reply = vws_svr_data_own((vws_tcp_svr*)s, cid,
(ucstr)data, (size_t)n);
vws_tcp_svr_send(reply);
return true;vws_svr_data_own() takes
ownership of the heap copy and binds the reply to the request's connection id;
vws_tcp_svr_send() queues it for the
networking thread. The handler casts the server to (vws_tcp_svr*) to
use these base-layer calls, and returns true to tell the
framework the request was handled.
Setup mirrors the WebSocket server but installs the HTTP handler:
vws_svr* server = vws_svr_new(10, 0, 0);
if (server == NULL)
{
vwsx_die("vws_svr_new() failed");
}
server->process_http = process;Because the HTTP and WebSocket handlers live on the same
vws_svr, one server can serve both:
setting process_http as well as a
process_ws lets the framework route each request to the right
handler. The run and stop go through the base type, exactly as in the WebSocket
server:
vwsx_serve_stop_on_signal((vws_tcp_svr*)server); vws_tcp_svr_run((vws_tcp_svr*)server, HOST, PORT); vws_svr_free(server);