Zenbu

seobeo
Login

seobeo

HTTP client and networking library for C.

Features

Files

File Description
seobeo.h Public API header
seobeo_internal.h Internal declarations
s_http_client.c HTTP client implementation
s_network.c Network utilities
s_sse.c Server-Sent Events framing and stream lifecycle
s_ssl.c SSL/TLS handling
s_logging.c Logging utilities
s_worker.c Thread and worker-pool implementation
seobeo_worker.h Public worker API
snapshot_creator.c/h Snapshot testing
docs/ Documentation
examples/ Usage examples
tests/ Unit tests
os/ OS-specific code

Usage

#include "seobeo/seobeo.h"

// Make HTTP request
HttpResponse* resp = http_get("https://example.com");
// handle response...
http_response_free(resp);

Building

bazel build //seobeo:seobeo
bazel test //seobeo:seobeo_test

Background workers

Use a detached task for simple fire-and-forget work:

void Convert_Image(void *p_context)
{
  Conversion *p_conversion = p_context;
  Run_FFmpeg(p_conversion);
}

Seobeo_Worker_Result result =
    Seobeo_Thread_Start_Detached(
        Convert_Image,
        p_conversion,
        free);
if (result != SEOBEO_WORKER_OK)
  free(p_conversion);

Use a bounded pool when requests can enqueue expensive work:

Seobeo_Worker_Pool *p_pool =
    Seobeo_Worker_Pool_Create(2, 16);

Seobeo_Worker_Result result =
    Seobeo_Worker_Pool_Submit(
        p_pool,
        Convert_Image,
        p_conversion,
        free);

Seobeo_Worker_Pool_Shutdown(p_pool, TRUE);
Seobeo_Worker_Pool_Destroy(p_pool);

Submitting transfers context ownership only when it returns SEOBEO_WORKER_OK. Cleanup runs after successful work and for queued tasks discarded by a non-draining shutdown. User callbacks never run while the pool mutex is held.

Server-Sent Events

Register an SSE route separately from ordinary response and stream handlers:

static void Build_Events(
    Seobeo_SSE_Stream *p_stream,
    Seobeo_Request_Entry *p_request,
    Dowa_Arena *p_arena)
{
  (void)p_request;
  (void)p_arena;
  Seobeo_SSE_Event event = {
    .event = "build",
    .id = "42",
    .data = "started\ncompiling",
    .retry_ms = 2000,
  };
  Seobeo_SSE_Send(p_stream, &event);
  Seobeo_SSE_Send_Comment(p_stream, "heartbeat");
}

Seobeo_Router_Register_SSE("/events/builds", Build_Events);

SSE handlers run once when a client connects and must return promptly so edge workers remain available. Call Seobeo_SSE_Retain before storing a stream for later work and pair it with Seobeo_SSE_Release; use Seobeo_SSE_Is_Open before sending. Do not retain the request map or arena after the handler returns. A return value of 1 means the record was retained behind socket backpressure and Seobeo_SSE_Flush should be retried later. SEOBEO_SSE_BACKPRESSURE means the bounded pending queue is full and the new record was not accepted. Events are bounded by the handle write-buffer capacity so one record is queued atomically; larger records return SEOBEO_SSE_EVENT_TOO_LARGE.

Dependencies