| Title: | Embedded HTTP and WebSocket Server Through 'CivetWeb' |
|---|---|
| Description: | An embedded HTTP and WebSocket server. The bundled 'CivetWeb' <https://github.com/civetweb/civetweb> C library does the socket work on its own threads, and R handles one request or WebSocket event at a time on its main thread, so handlers need no locking. Static files are served from disk, TLS (Transport Layer Security) is terminated by the bundled 'Mbed TLS' <https://github.com/Mbed-TLS/mbedtls>, and the event loop is exposed so an application can drive it from its own. |
| Authors: | Troy Hernandez [aut, cre] (ORCID: <https://orcid.org/0009-0005-4248-604X>), Vedo Alagic [aut, cph] (wrote the package; github.com/vedoa/civetwebR), cornball.ai [cph], The CivetWeb developers [cph] (CivetWeb, bundled in src/civetweb.c and src/civetweb/), Sergey Lyubka [cph] (Mongoose, from which CivetWeb descends), Aladdin Enterprises [cph] (the MD5 implementation in src/civetweb/md5.inl), L. Peter Deutsch [ctb] (author of src/civetweb/md5.inl), No Face Press, LLC [ctb] (amalgamated md5.inl for CivetWeb), Steve Reid [ctb] (author of src/civetweb/sha1.inl (public domain)), James H. Brown [ctb] (src/civetweb/sha1.inl), Saul Kravitz [ctb] (src/civetweb/sha1.inl), Ralph Giles [ctb] (src/civetweb/sha1.inl), The Mbed TLS Contributors [cph] (Mbed TLS, bundled in src/mbedtls/) |
| Maintainer: | Troy Hernandez <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.0.1.7 |
| Built: | 2026-10-13 19:52:07 UTC |
| Source: | https://github.com/cornball-ai/civetwebR |
Clear all registered handlers
clear_handlers()clear_handlers()
Register handlers under a common path prefix
group(prefix, expr)group(prefix, expr)
prefix |
Character(1). Path prefix (e.g. "/api/v1"). |
expr |
Code that registers handlers. |
Invisibly returns TRUE.
Registers a function for a given HTTP method and path. The path is normalized and combined with the current route prefix.
handle(method, path, fun, overwrite = TRUE)handle(method, path, fun, overwrite = TRUE)
method |
Character string. HTTP method (e.g. "GET", "POST"). |
path |
Character string. Route path starting with "/". |
fun |
Function. Handler of form function(req). |
overwrite |
Logical. If TRUE (default), overwrite existing handler. |
TRUE (invisibly) on success.
TRUE when the package was built with TLS support, which the bundled Mbed TLS sources provide on every platform.
has_tls()has_tls()
Logical.
The low-level driver: one call returns one event from a server, or
NULL after timeout_ms with nothing to do.
run_server() and serve() are loops over this; an
application with its own event loop calls it directly.
next_event(timeout_ms = 100L, server = NULL)next_event(timeout_ms = 100L, server = NULL)
timeout_ms |
Milliseconds to wait for an event. Default 100. |
server |
A server handle from |
Events are lists of class cw_request with an event
field:
"request": an HTTP request. method, path,
query, headers (named character), body (raw),
body_too_large, remote_addr, remote_port. Must
be answered with send_response(); the worker thread waits
until then.
"ws_connect": a client asks to upgrade on the WebSocket
path. Same fields as a request. Must be answered with
send_response(): TRUE accepts, FALSE refuses
with 403, a list with a status refuses with that status.
Nothing is sent to the client until R decides, so this is where an
Origin or cookie check belongs.
"ws_open": the handshake completed for the connection
with this id.
"ws_message": a data frame arrived. body (raw),
binary, fin and opcode (1 text, 2 binary, 0
continuation). A message split across frames arrives as several
events: the first with the text or binary opcode, the rest as
continuations, the last with fin = TRUE; the receiver
concatenates the bodies.
"ws_close": the connection with this id is gone.
A WebSocket connection keeps the id of its connect event for
its whole life; ws_send() and ws_close() address it by
that id.
Control frames never reach R: CivetWeb answers a ping with a pong,
and a close frame from the client is echoed back with its status
code before the ws_close event (RFC 6455 section 5.5.1).
On Ctrl-C an interrupt condition is signalled.
A cw_request, or NULL on timeout.
A "connect" handler runs before the handshake and decides
whether the client may upgrade: it returns TRUE to accept,
FALSE to refuse with 403, or a list with a status to
refuse with that status. It sees the upgrade request's
headers (so Origin or a cookie can be checked) and
remote_addr. Without a connect handler every upgrade is
accepted.
on_ws(event, fun)on_ws(event, fun)
event |
Character string: "connect", "open", "message", or "close". |
fun |
Function taking a |
Invisibly returns TRUE.
Helper to extract a header from a request
req_header(req, key)req_header(req, key)
req |
A cw_request object. |
key |
Header name. |
Helper to extract a query parameter from a request
req_query(req, key)req_query(req, key)
req |
A cw_request object. |
key |
Parameter name. |
This loop pulls requests from C, dispatches in R, and sends responses back. It runs until interrupted.
run_server(timeout_ms = 100L)run_server(timeout_ms = 100L)
timeout_ms |
Polling timeout in milliseconds. Default is 100ms. |
Invisibly returns TRUE when the loop exits.
Answer a request or a WebSocket connect
send_response(id, res, server = NULL)send_response(id, res, server = NULL)
id |
The event's |
res |
For a request: a string (200, text/plain) or a list with
|
server |
A server handle from |
NULL, invisibly.
Start and run the HTTP server
serve( port = 8080L, host = "127.0.0.1", quiet = FALSE, log = NULL, static = NULL, timeout_ms = 100L, num_threads = 50L, max_body_size = 8 * 1024 * 1024, request_timeout_ms = 30000L, ws_path = "/ws", keep_alive = FALSE, tls_cert = NULL )serve( port = 8080L, host = "127.0.0.1", quiet = FALSE, log = NULL, static = NULL, timeout_ms = 100L, num_threads = 50L, max_body_size = 8 * 1024 * 1024, request_timeout_ms = 30000L, ws_path = "/ws", keep_alive = FALSE, tls_cert = NULL )
port |
Integer. Port to listen on. |
host |
Character(1). Bind address. |
quiet |
Logical. Suppress startup message. |
log |
Function or NULL. Optional request logger. |
static |
NULL or list. Static serving configuration(s). |
timeout_ms |
Polling timeout in milliseconds. Default is 100ms. |
num_threads |
Integer. Number of worker threads. Default is 50. |
max_body_size |
Number. Maximum request body size in bytes. Default is 8MiB. |
request_timeout_ms |
Integer. Socket receive timeout. Default is 30s. |
ws_path |
String. The path WebSocket upgrades are accepted on.
Default |
keep_alive |
Logical. Keep HTTP connections open between
requests. Default |
tls_cert |
NULL, or the path of a PEM file holding the server's
certificate and private key; see |
Invisibly returns TRUE when the loop exits.
Useful after start_server(port = 0).
server_port(server = NULL)server_port(server = NULL)
server |
A server handle from |
Integer port.
Starts a server and, by default, registers it as the package's default
server, the one run_server(), serve(), ws_send()
and friends use when no server is given. With
register = FALSE the server is only returned, so one R process
can run several.
start_server( port = 8080L, host = "127.0.0.1", num_threads = 50L, max_body_size = 8 * 1024 * 1024, request_timeout_ms = 30000L, ws_path = "/ws", static_dirs = NULL, keep_alive = FALSE, tls_cert = NULL, register = TRUE )start_server( port = 8080L, host = "127.0.0.1", num_threads = 50L, max_body_size = 8 * 1024 * 1024, request_timeout_ms = 30000L, ws_path = "/ws", static_dirs = NULL, keep_alive = FALSE, tls_cert = NULL, register = TRUE )
port |
Integer. Port to listen on; |
host |
String. Host to expose to. |
num_threads |
Integer. Number of worker threads. Default is 50. |
max_body_size |
Number. Maximum request body size in bytes. Default is 8MiB. |
request_timeout_ms |
Integer. Socket receive timeout. Default is 30s. |
ws_path |
String. The path WebSocket upgrades are accepted on.
Default |
static_dirs |
NULL or a named character vector mapping URL
prefixes to directories, e.g. |
keep_alive |
Logical. Keep HTTP connections open between
requests. Default |
tls_cert |
NULL, or the path of a PEM file holding the server's certificate (followed by its chain, if any) and its private key. When given, the port speaks TLS (https and wss) through the bundled Mbed TLS, and a plain-HTTP client on it is refused. |
register |
Logical. Make this the default server. Default
|
A server handle (class cw_server), invisibly.
Static file handler (serves files from a directory)
static_files( dir, prefix = "/", index = c("index.html"), cache_control = NULL, list_dirs = FALSE, template = NULL )static_files( dir, prefix = "/", index = c("index.html"), cache_control = NULL, list_dirs = FALSE, template = NULL )
dir |
Character(1). Root directory to serve from. |
prefix |
Character(1). URL prefix. |
index |
Character vector. Index files. |
cache_control |
NULL or character(1). |
list_dirs |
Logical. Enable directory listing. |
template |
Character(1) or NULL. Optional template path override. |
Answers every request still waiting on R with 503, closes the connections and releases the server. Stopping the default server clears it.
stop_server(server = NULL)stop_server(server = NULL)
server |
A server handle from |
Invisibly returns TRUE.
Removes a function for a given HTTP method and path.
unhandle(method, path)unhandle(method, path)
method |
Character string. HTTP method (e.g. "GET"). |
path |
Character string. Route path. |
TRUE (invisibly) on success.
Sends a close frame with code; the client answers and the
connection ends, which arrives later as a ws_close event.
Further ws_send() calls on the id return FALSE.
ws_close(id, code = 1000L, server = NULL)ws_close(id, code = 1000L, server = NULL)
id |
Connection ID. |
code |
Integer close code. Default 1000 (normal closure). |
server |
A server handle from |
TRUE if the close frame was written.
Send a WebSocket message
ws_send(id, data, server = NULL)ws_send(id, data, server = NULL)
id |
Connection ID. |
data |
Character string or raw vector. |
server |
A server handle from |
TRUE if the frame was written, FALSE if the
connection is not open.