### Build libuv Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/introduction.md Instructions to build libuv from source. No installation is required for building the examples. ```default cd libuv ./autogen.sh ./configure make ``` -------------------------------- ### TCP Echo Server Setup Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/networking.md Initializes a TCP server, binds it to a port, and starts listening for incoming connections. Uses uv_ip4_addr for address conversion. The backlog argument to uv_listen specifies the maximum length of the queue for pending connections. ```c uv_close((uv_handle_t*) client, on_close); } } int main() { loop = uv_default_loop(); uv_tcp_t server; uv_tcp_init(loop, &server); uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr); uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0); int r = uv_listen((uv_stream_t*) &server, DEFAULT_BACKLOG, on_new_connection); if (r) { fprintf(stderr, "Listen error %s\n", uv_strerror(r)); return 1; } return uv_run(loop, UV_RUN_DEFAULT); } ``` -------------------------------- ### Install libuv Components Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/CMakeLists.txt Installs libuv headers, license, pkg-config files, and libraries using CMake's install command. ```cmake install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) install(FILES ${PROJECT_BINARY_DIR}/libuv.pc ${PROJECT_BINARY_DIR}/libuv-static.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(TARGETS uv EXPORT libuvConfig RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(EXPORT libuvConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv) ``` -------------------------------- ### Install libuv with Homebrew Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Install the libuv library from HEAD using the Homebrew package manager on macOS. ```bash $ brew install --HEAD libuv ``` -------------------------------- ### Start a Unix Domain Socket Server with httpuv Source: https://context7.com/rstudio/httpuv/llms.txt Demonstrates how to start a server listening on a Unix domain socket. The `mask` argument controls file permissions, and the `app` argument defines the request handler. ```R pipe_path <- tempfile("httpuv_pipe_") s <- startPipeServer( name = pipe_path, mask = strtoi("177", 8L), # rwx for owner only app = list( call = function(req) { list( status = 200L, headers = list("Content-Type" = "text/plain"), body = paste("Hello from pipe server:", req$PATH_INFO) ) } ) ) cat("Pipe server listening at:", s$getName(), "\n") # Test with: curl --unix-socket http://localhost/hello # s$stop() ``` -------------------------------- ### Start WebSocket Echo Server in R Source: https://github.com/rstudio/httpuv/blob/main/README.md This snippet demonstrates how to start a WebSocket server that echoes received messages back to the client. It requires the httpuv package. ```R s <- startServer("127.0.0.1", 8080, list( onWSOpen = function(ws) { # The ws object is a WebSocket object cat("Server connection opened.\n") ws$onMessage(function(binary, message) { cat("Server received message:", message, "\n") ws$send(message) }) ws$onClose(function() { cat("Server connection closed.\n") }) } ) ) ``` -------------------------------- ### Get Executable Path - uv_exepath Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets the executable path. You must call uv_setup_args before using this function. ```c char buffer[1024]; size_t size = sizeof(buffer); uv_exepath(buffer, &size); ``` -------------------------------- ### Start HTTP server with dynamic and static paths Source: https://context7.com/rstudio/httpuv/llms.txt Starts an HTTP server that can serve static files from a directory and handle dynamic API requests. Use `excludeStaticPath()` to prevent certain paths from being served statically. ```R s <- startServer("0.0.0.0", 3000, app = list( call = function(req) { # Only reached for paths not matched by staticPaths list( status = 404L, headers = list("Content-Type" = "text/plain"), body = paste("Not found:", req$PATH_INFO) ) }, staticPaths = list( # Serve everything under /public from disk "/" = staticPath( "public", indexhtml = TRUE, fallthrough = TRUE, # fall through to call() for missing files html_charset = "utf-8", headers = list("Cache-Control" = "max-age=3600"), validation = '"X-Secret-Token" == "abc123"' # require header ), # Exclude /api/* from static serving so it goes to call() "/api" = excludeStaticPath() ), staticPathOptions = staticPathOptions( indexhtml = TRUE, fallthrough = FALSE, html_charset = "utf-8" ) ) ) ``` -------------------------------- ### Setup uvwget with libuv and libcurl Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md Initializes the libuv loop, libcurl, and sets up multi-socket options for asynchronous operations. This is the main entry point for the uvwget utility. ```c #include #include #include #include #include uv_loop_t *loop; CURLM *curl_handle; uv_timer_t timeout; } int main(int argc, char **argv) { loop = uv_default_loop(); if (argc <= 1) return 0; if (curl_global_init(CURL_GLOBAL_ALL)) { fprintf(stderr, "Could not init cURL\n"); return 1; } uv_timer_init(loop, &timeout); curl_handle = curl_multi_init(); curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket); curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout); while (argc-- > 1) { add_download(argv[argc], argc); } uv_run(loop, UV_RUN_DEFAULT); curl_multi_cleanup(curl_handle); return 0; } ``` -------------------------------- ### Install httpuv from CRAN Source: https://github.com/rstudio/httpuv/blob/main/README.md Installs the stable version of the httpuv package from CRAN. ```r install.packages("httpuv") ``` -------------------------------- ### Start Basic HTTP Server in R Source: https://github.com/rstudio/httpuv/blob/main/README.md Starts a basic HTTP server on port 8080 that responds to requests with the current system time and the requested path. Ensure the host is set to '0.0.0.0' to listen on all network interfaces, or '127.0.0.1' for local host only. ```r library(httpuv) s <- startServer(host = "0.0.0.0", port = 8080, app = list( call = function(req) { body <- paste0("Time: ", Sys.time(), "
Path requested: ", req$PATH_INFO) list( status = 200L, headers = list('Content-Type' = 'text/html'), body = body ) } ) ) ``` -------------------------------- ### uv_prepare_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/prepare.md Starts the uv_prepare_t handle, scheduling the provided callback to be executed once per loop iteration before I/O polling. The callback must not be NULL. ```APIDOC ## uv_prepare_start ### Description Starts the handle with the given callback. This function always succeeds, except when cb is NULL. ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters * **prepare** ([uv_prepare_t](#c.uv_prepare_t) *prepare) - The prepare handle. * **cb** ([uv_prepare_cb](#c.uv_prepare_cb) cb) - The callback function to execute. ### Returns * **int**: 0 on success, or UV_EINVAL when cb == NULL. ``` -------------------------------- ### Install httpuv Development Version Source: https://github.com/rstudio/httpuv/blob/main/README.md Installs the development version of the httpuv package using the 'pak' package manager. ```r pak::pak("rstudio/httpuv") ``` -------------------------------- ### startPipeServer Source: https://context7.com/rstudio/httpuv/llms.txt Starts a server that listens on a Unix domain socket. Only the owner can connect to this socket. ```APIDOC ## startPipeServer ### Description Starts a server that listens on a Unix domain socket. Only the owner can connect to this socket. ### Arguments * `name`: The path to the Unix domain socket. * `mask`: The file permission mask for the socket. * `app`: An R list representing the application to handle requests. ### Example ```r pipe_path <- tempfile("httpuv_pipe_") s <- startPipeServer( name = pipe_path, mask = strtoi("177", 8L), # rwx for owner only app = list( call = function(req) { list( status = 200L, headers = list("Content-Type" = "text/plain"), body = paste("Hello from pipe server:", req$PATH_INFO) ) } ) ) cat("Pipe server listening at:", s$getName(), "\n") # Test with: curl --unix-socket http://localhost/hello # s$stop() ``` ``` -------------------------------- ### uv_alloc_cb Callback Example Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/handle.md Example of a memory allocation callback used for read operations. The user must allocate memory and set the buffer's base and length. ```c static void my_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { buf->base = malloc(suggested_size); buf->len = suggested_size; } ``` -------------------------------- ### Start FS Event Monitoring Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/fs_event.md Starts monitoring a specified path for file system changes. The callback will be invoked upon detected events. Only UV_FS_EVENT_RECURSIVE is currently supported on OSX and Windows. ```c int uv_fs_event_start(uv_fs_event_t *handle, uv_fs_event_cb cb, const char *path, unsigned int flags); ``` -------------------------------- ### Initialize and Start a Repeating Timer in C Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md Initializes a timer and starts it with a specified timeout and repeat interval. The timer will first trigger after the timeout, then repeat at the specified interval. ```c uv_timer_t timer_req; uv_timer_init(loop, &timer_req); uv_timer_start(&timer_req, callback, 5000, 2000); ``` -------------------------------- ### Install httpuv from GitHub with Debugging Options Source: https://github.com/rstudio/httpuv/blob/main/README.md This R code snippet uses `withr::with_makevars` to temporarily set C++ preprocessor flags for debugging before installing httpuv from GitHub. This is useful for development or troubleshooting. ```R withr::with_makevars( c(PKG_CPPFLAGS="-DDEBUG_TRACE -DDEBUG_THREAD -UNDEBUG"), { devtools::install_github("rstudio/httpuv") }, assignment = "+=") ``` -------------------------------- ### uv_fs_event_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/fs_event.md Starts monitoring a specified path for file system events. The provided callback will be invoked when events occur. ```APIDOC ## uv_fs_event_start ### Description Starts the handle, causing it to watch the specified path for changes. The callback `cb` will be invoked repeatedly when events occur. The `flags` parameter can be an ORed mask of `uv_fs_event_flags`. ### Method `uv_fs_event_start(uv_fs_event_t *handle, uv_fs_event_cb cb, const char *path, unsigned int flags)` ### Parameters - **handle** ([`uv_fs_event_t`](#c.uv_fs_event_t) *) - The FS Event handle. - **cb** ([`uv_fs_event_cb`](#c.uv_fs_event_cb)) - The callback function to be invoked upon event detection. - **path** (const char *) - The path to monitor for changes. - **flags** (unsigned int) - Flags to control the behavior of the watcher. Currently, only `UV_FS_EVENT_RECURSIVE` is supported on OSX and Windows. ### Note Currently, the only supported flag is `UV_FS_EVENT_RECURSIVE` and only on OSX and Windows. ``` -------------------------------- ### uv_signal_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/signal.md Starts monitoring a specific signal and associates a callback function with it. ```APIDOC ## uv_signal_start ### Description Starts the signal handle, associating a callback with a specific signal number. ### Parameters - **signal** ([uv_signal_t](#c.uv_signal_t) *) - The initialized signal handle. - **cb** ([uv_signal_cb](#c.uv_signal_cb)) - The callback function to be executed when the signal is received. - **signum** (int) - The signal number to monitor (e.g., SIGINT, SIGTERM). ### Return Value Returns 0 on success, or a negative error code on failure. ``` -------------------------------- ### uv_async_init Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/async.md Initializes an async handle. It starts the handle immediately upon initialization. A NULL callback is permissible. ```APIDOC ## uv_async_init ### Description Initializes the async handle. A NULL callback is allowed. ### Method int uv_async_init([uv_loop_t](loop.md#c.uv_loop_t) *loop, [uv_async_t](#c.uv_async_t) *async, [uv_async_cb](#c.uv_async_cb) async_cb) ### Parameters * **loop**: The event loop to associate the async handle with. * **async**: The async handle to initialize. * **async_cb**: The callback function to be executed when the handle is activated. ### Returns 0 on success, or a negative error code on failure. ``` -------------------------------- ### uv_idle_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/idle.md Starts an idle handle, causing its callback to be executed on each loop iteration. The callback must not be NULL. ```APIDOC ## uv_idle_start Start the handle with the given callback. This function always succeeds, except when cb is NULL. ### Parameters * **idle** ([`uv_idle_t`](#c.uv_idle_t) *) - The idle handle to start. * **cb** ([`uv_idle_cb`](#c.uv_idle_cb)) - The callback function to execute on each loop iteration. ### Returns 0 on success, or UV_EINVAL when cb == NULL. ``` -------------------------------- ### startPipeServer() Source: https://context7.com/rstudio/httpuv/llms.txt Starts a server that listens on a Unix domain socket or a Windows named pipe instead of a TCP port, useful for inter-process communication. ```APIDOC ## startPipeServer() ### Description Variant of `startServer()` that binds to a Unix domain socket (Linux/macOS) or a Windows named pipe instead of a TCP port. Useful for inter-process communication where network socket overhead is undesirable. The `mask` parameter controls the file-system permissions of the socket file via `umask`. ### Parameters - **pipePath** (string) - The path to the Unix domain socket or named pipe. - **app** (list or environment or R5 object) - A list containing handler functions for the server. - **mask** (numeric, optional) - File system permissions for the socket file (umask). ### Request Example ```r library(httpuv) # Example for Unix domain socket # s <- startPipeServer("/tmp/httpuv.sock", app = list(call = function(req) list(body = "Hello via pipe!"))) # Example for Windows named pipe # s <- startPipeServer("\\.\pipe\httpuv_pipe", app = list(call = function(req) list(body = "Hello via pipe!"))) ``` ``` -------------------------------- ### Run Static Server in Background Source: https://github.com/rstudio/httpuv/blob/main/tests/testthat/_snaps/static-server.md Starts a static server in the background. Use the stop() method to shut it down. ```R s <- runStaticServer(path_example_site(), background = TRUE, browse = FALSE) ``` ```R s$stop() ``` -------------------------------- ### uv_check_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/check.md Starts a check handle, scheduling its callback to be executed once per event loop iteration after I/O polling. ```APIDOC ## uv_check_start ### Description Starts the check handle with the given callback. The callback will be invoked once per event loop iteration, after I/O polling. ### Parameters - **check** ([uv_check_t](#c.uv_check_t)) - The check handle to start. - **cb** ([uv_check_cb](#c.uv_check_cb)) - The callback function to execute. Must not be NULL. ### Returns 0 on success, or UV_EINVAL if the callback is NULL. ``` -------------------------------- ### uv_spawn Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/process.md Initializes a process handle and starts a child process. Returns 0 on success, or a negative error code if spawning fails. ```APIDOC ## uv_spawn ### Description Initializes the process handle and starts the process. If the process is successfully spawned, this function will return 0. Otherwise, the negative error code corresponding to the reason it couldn’t spawn is returned. Possible reasons for failing to spawn would include (but not be limited to) the file to execute not existing, not having permissions to use the setuid or setgid specified, or not having enough memory to allocate for the new process. #### Versionchanged Changed in version 1.24.0: Added UV_PROCESS_WINDOWS_HIDE_CONSOLE and UV_PROCESS_WINDOWS_HIDE_GUI flags. ### Signature int uv_spawn([uv_loop_t](loop.md#c.uv_loop_t) *loop, [uv_process_t](process.md#c.uv_process_t) *handle, const [uv_process_options_t](process.md#c.uv_process_options_t) *options) ``` -------------------------------- ### Run a Blocking Server Loop Source: https://context7.com/rstudio/httpuv/llms.txt runServer is a convenience wrapper that starts a server, enters a blocking service loop, and stops the server on exit. It's suitable for standalone scripts. This example creates a minimal JSON API. ```R library(httpuv) # A minimal JSON API that returns request details runServer("127.0.0.1", 5000, app = list( call = function(req) { # Read POST body if present body_raw <- req$rook.input$read(-1L) body_text <- if (length(body_raw) > 0) rawToChar(body_raw) else "" response_json <- paste0( '{"method":"', req$REQUEST_METHOD, '",', '"path":"', req$PATH_INFO, '",', '"body":', if (nzchar(body_text)) body_text else 'null', '}' ) list( status = 200L, headers = list("Content-Type" = "application/json"), body = response_json ) } ) ) # Blocks here; press Ctrl+C to stop ``` -------------------------------- ### Build Documentation Options Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Shows available targets for building documentation using make. Use 'make help' to see all options. ```bash make help ``` -------------------------------- ### Sample Plugin Implementation Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md A simple plugin that registers itself with the name "Hello World!" using the `mfp_register` function provided by the plugin interface. ```c #include "plugin.h" void initialize() { mfp_register("Hello World!"); } ``` -------------------------------- ### Inter-thread Communication Setup Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/threads.md Initializes a libuv loop and an `uv_async_t` watcher for inter-thread communication. A work request is queued to simulate a long-running task. ```c uv_loop_t *loop; uv_async_t async; int main() { loop = uv_default_loop(); uv_work_t req; int size = 10240; req.data = (void*) &size; uv_async_init(loop, &async, print_progress); uv_queue_work(loop, &req, fake_download, after); return uv_run(loop, UV_RUN_DEFAULT); } ``` -------------------------------- ### Timer Start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/timer.md Starts the timer, scheduling a callback to be executed after a specified timeout and optionally at a repeat interval. ```APIDOC ## uv_timer_start ### Description Starts the timer. timeout and repeat are in milliseconds. If timeout is zero, the callback fires on the next event loop iteration. If repeat is non-zero, the callback fires first after timeout milliseconds and then repeatedly after repeat milliseconds. Does not update the event loop’s concept of “now”. See [uv_update_time()](#c.uv_update_time) for more information. If the timer is already active, it is simply updated. ### Parameters - **handle** ([uv_timer_t](#c.uv_timer_t) *) - **cb** ([uv_timer_cb](#c.uv_timer_cb) cb) - **timeout** (uint64_t) - The initial delay in milliseconds. - **repeat** (uint64_t) - The repeat interval in milliseconds. ### Returns 0 on success, or an error code. ``` -------------------------------- ### startServer() Source: https://context7.com/rstudio/httpuv/llms.txt Creates an HTTP/WebSocket server by binding a TCP port and listening for connections in a background thread. The 'app' argument defines handler functions for HTTP requests, header inspection, WebSocket upgrades, and static file serving. ```APIDOC ## startServer() ### Description Binds a TCP port on the given host and starts listening for HTTP and WebSocket connections in a background thread. The `app` argument is a named list (or environment/R5 object) that provides handler functions: `call` for HTTP requests, `onHeaders` for early header inspection, `onWSOpen` for WebSocket upgrades, and `staticPaths` for zero-R-overhead static file serving. Returns a `WebServer` object that can be used to inspect or stop the server. ### Parameters - **host** (string) - The host address to bind to. - **port** (numeric) - The TCP port to listen on. - **app** (list or environment or R5 object) - A list containing handler functions: - **call**: Function to handle HTTP requests (Rook-compatible). - **onHeaders**: Function for early header inspection. - **onWSOpen**: Function to handle WebSocket upgrades. - **staticPaths**: List defining paths for static file serving. - **staticPathOptions**: Options for static file serving. ### Request Example ```r library(httpuv) s <- startServer( host = "0.0.0.0", port = 8080, app = list( call = function(req) { list( status = 200L, headers = list("Content-Type" = "text/html; charset=utf-8"), body = "

httpuv demo

" ) }, onWSOpen = function(ws) { cat("WebSocket opened\n") }, staticPaths = list( "/static" = staticPath("www/static") ) ) ) ``` ### Response - **WebServer object**: An object that can be used to inspect or stop the server. ``` -------------------------------- ### Build ePub Documentation Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Command to build the documentation in ePub format. ```bash make epub ``` -------------------------------- ### Get System Load Average - uv_loadavg Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets the system load average. Returns [0,0,0] on Windows as it's not implemented. ```c double avg[3]; uv_loadavg(avg); // avg[0] is the 1-minute average, avg[1] is the 5-minute average, avg[2] is the 15-minute average. ``` -------------------------------- ### Main Application for Loading Plugins Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md This application loads shared libraries specified as command-line arguments, finds the `initialize` function within them using `uv_dlsym`, and executes it. It handles errors during library loading and symbol resolution. ```c #include "plugin.h" typedef void (*init_plugin_function)(); void mfp_register(const char *name) { fprintf(stderr, "Registered plugin \"%s\"\n", name); } int main(int argc, char **argv) { if (argc == 1) { fprintf(stderr, "Usage: %s [plugin1] [plugin2] ...\n", argv[0]); return 0; } uv_lib_t *lib = (uv_lib_t*) malloc(sizeof(uv_lib_t)); while (--argc) { fprintf(stderr, "Loading %s\n", argv[argc]); if (uv_dlopen(argv[argc], lib)) { fprintf(stderr, "Error: %s\n", uv_dlerror(lib)); continue; } init_plugin_function init_plugin; if (uv_dlsym(lib, "initialize", (void **) &init_plugin)) { fprintf(stderr, "dlsym error: %s\n", uv_dlerror(lib)); continue; } init_plugin(); } return 0; } ``` -------------------------------- ### Start a Full-Featured HTTP/WebSocket Server Source: https://context7.com/rstudio/httpuv/llms.txt Use startServer to bind a TCP port and listen for connections. The app argument is a list containing handlers for HTTP requests (call), headers (onHeaders), WebSocket upgrades (onWSOpen), and static file serving (staticPaths). ```R library(httpuv) # Full-featured app: dynamic HTTP + static assets + WebSocket support s <- startServer( host = "0.0.0.0", port = 8080, app = list( # HTTP handler (Rook-compatible) call = function(req) { path <- req$PATH_INFO method <- req$REQUEST_METHOD body <- paste0( "

httpuv demo

", "

Method: ", method, "

", "

Path: ", path, "

", "

Time: ", Sys.time(), "

" ) list( status = 200L, headers = list("Content-Type" = "text/html; charset=utf-8"), body = body ) }, # Intercept headers before the body is read (e.g. enforce upload limits) onHeaders = function(req) { content_length <- as.numeric(req$HTTP_CONTENT_LENGTH %||% 0) if (content_length > 1e6) { list( status = 413L, headers = list("Content-Type" = "text/plain"), body = "Payload too large" ) } else { NULL # continue normal processing } }, # WebSocket handler onWSOpen = function(ws) { cat("WebSocket opened from:", ws$request$REMOTE_ADDR, "\n") ws$onMessage(function(binary, message) { ws$send(paste("Echo:", message)) }) ws$onClose(function() { cat("WebSocket closed\n") }) }, # Serve /static/* directly from disk, bypassing R staticPaths = list( "/static" = staticPath("www/static", indexhtml = FALSE), "/favicon.ico" = staticPath("www/favicon.ico") ), staticPathOptions = staticPathOptions( indexhtml = TRUE, fallthrough = FALSE, html_charset = "utf-8" ) ) ) cat("Server running on port", s$getPort(), "\n") # s$stop() # stop when done ``` -------------------------------- ### Restart Repeating Timer in C Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md Restarts a repeating timer, equivalent to stopping and then starting it again with the same timeout and repeat values. Fails if the timer has not been started. ```default int uv_timer_again(uv_timer_t *) ``` -------------------------------- ### uv_setup_args Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Stores program arguments, which is required for getting/setting the process title or executable path. Libuv may take ownership of the memory pointed to by argv. ```APIDOC ## uv_setup_args ### Description Store the program arguments. Required for getting / setting the process title or the executable path. Libuv may take ownership of the memory that argv points to. This function should be called exactly once, at program start-up. Example: ```default argv = uv_setup_args(argc, argv); /* May return a copy of argv. */ ``` ### Signature char **uv_setup_args(int argc, char **argv) ``` -------------------------------- ### Get CPU Information - uv_cpu_info Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets information about the CPUs on the system. The cpu_infos array must be freed with uv_free_cpu_info(). Added in version 1.16.0. ```c uv_cpu_info_t *cpu_infos; int count; uv_cpu_info(&cpu_infos, &count); // Use cpu_infos and count here uv_free_cpu_info(cpu_infos, count); ``` -------------------------------- ### uv_is_active Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/handle.md Checks if a libuv handle is currently active. A handle is considered active if it is involved in I/O operations, has been started with a start function, or is in the process of being closed. ```APIDOC ## uv_is_active ### Description Returns non-zero if the handle is active, zero if it’s inactive. What “active” means depends on the type of handle: - A uv_async_t handle is always active and cannot be deactivated, except by closing it with uv_close(). - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that deals with i/o - is active when it is doing something that involves i/o, like reading, writing, connecting, accepting new connections, etc. - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has been started with a call to uv_check_start(), uv_idle_start(), etc. Rule of thumb: if a handle of type uv_foo_t has a uv_foo_start() function, then it’s active from the moment that function is called. Likewise, uv_foo_stop() deactivates the handle again. ### Function Signature ```c int uv_is_active(const uv_handle_t *handle) ``` ``` -------------------------------- ### Hello World libuv Program Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/basics.md A minimal libuv program that initializes an event loop and exits immediately. It demonstrates the basic structure for starting and stopping a libuv loop. ```c #include #include #include int main() { uv_loop_t *loop = malloc(sizeof(uv_loop_t)); uv_loop_init(loop); printf("Now quitting.\n"); uv_run(loop, UV_RUN_DEFAULT); uv_loop_close(loop); free(loop); return 0; } ``` -------------------------------- ### uv_is_active Function Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/handle.md Checks if a libuv handle is currently active. A handle is considered active if it's involved in I/O operations or has been started with a corresponding start function. ```c int uv_is_active(const uv_handle_t *handle); ``` -------------------------------- ### Build HTML Documentation Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Command to build the documentation in HTML format. ```bash make html ``` -------------------------------- ### Get Network Interface Addresses - uv_interface_addresses Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets address information about network interfaces. The returned array must be freed with uv_free_interface_addresses(). Added in version 1.16.0. ```c uv_interface_address_t *addresses; int count; uv_interface_addresses(&addresses, &count); // Use addresses and count here uv_free_interface_addresses(addresses, count); ``` -------------------------------- ### Display Build Summary Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/CMakeLists.txt Prints a summary of the build configuration options to the console. ```cmake message(STATUS "summary of build options: Install prefix: ${CMAKE_INSTALL_PREFIX} Target system: ${CMAKE_SYSTEM_NAME} Compiler: C compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID}) CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} ") ``` -------------------------------- ### Get Timer Due Time Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/timer.md Gets the remaining time in milliseconds until the timer is due to fire. Returns 0 if the timer has expired. This time is relative to uv_now(). ```APIDOC ## uv_timer_get_due_in ### Description Get the timer due value or 0 if it has expired. The time is relative to [uv_now()](#c.uv_now). Added in version 1.40.0. ### Parameters - **handle** (const [uv_timer_t](#c.uv_timer_t) *) ### Returns The time in milliseconds until the timer is due, or 0 if expired. ``` -------------------------------- ### uv_prepare_init Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/prepare.md Initializes a uv_prepare_t handle. This function always succeeds. ```APIDOC ## uv_prepare_init ### Description Initializes the handle. This function always succeeds. ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters * **loop** ([uv_loop_t](loop.md#c.uv_loop_t) *loop) - The event loop. * **prepare** ([uv_prepare_t](#c.uv_prepare_t) *prepare) - The prepare handle to initialize. ### Returns * **int**: 0 on success. ``` -------------------------------- ### Clone and Set Up Remote Repository Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/CONTRIBUTING.md Clone the libuv repository and set up the upstream remote for tracking changes. ```bash git clone https://github.com/username/libuv.git $ cd libuv $ git remote add upstream https://github.com/libuv/libuv.git ``` -------------------------------- ### TTY Animation Example Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md An example demonstrating TTY animation using ANSI escape codes for screen clearing, cursor positioning, and color. It animates a message moving down the screen. ```c #include #include #include #include uv_loop_t *loop; uv_tty_t tty; uv_timer_t tick; uv_write_t write_req; int width, height; int pos = 0; char *message = " Hello TTY "; void update(uv_timer_t *req) { char data[500]; uv_buf_t buf; buf.base = data; buf.len = sprintf(data, "\033[2J\033[H\033[%dB\033[%luC\033[42;37m%s", pos, (unsigned long) (width-strlen(message))/2, message); uv_write(&write_req, (uv_stream_t*) &tty, &buf, 1, NULL); pos++; if (pos > height) { uv_tty_reset_mode(); uv_timer_stop(&tick); } } int main() { loop = uv_default_loop(); uv_tty_init(loop, &tty, STDOUT_FILENO, 0); uv_tty_set_mode(&tty, 0); if (uv_tty_get_winsize(&tty, &width, &height)) { fprintf(stderr, "Could not get TTY information\n"); uv_tty_reset_mode(); return 1; } fprintf(stderr, "Width %d, height %d\n", width, height); uv_timer_init(loop, &tick); uv_timer_start(&tick, update, 200, 200); return uv_run(loop, UV_RUN_DEFAULT); } ``` -------------------------------- ### uv_udp_recv_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/udp.md Prepares a UDP socket for receiving data. If not bound, it binds to 0.0.0.0 and a random port. ```APIDOC ## uv_udp_recv_start ### Description Prepare for receiving data. If the socket has not previously been bound with `uv_udp_bind()`, it is bound to 0.0.0.0 (the “all interfaces” IPv4 address) and a random port number. ### Parameters * **handle** – UDP handle. Should have been initialized with `uv_udp_init()`. * **alloc_cb** – Callback to invoke when temporary storage is needed. * **recv_cb** – Callback to invoke with received data. ### Returns 0 on success, or an error code < 0 on failure. ### NOTE When using `recvmmsg(2)`, the number of messages received at a time is limited by the number of max size dgrams that will fit into the buffer allocated in `alloc_cb`, and `suggested_size` in `alloc_cb` for `udp_recv` is always set to the size of 1 max size dgram. ### Versionchanged Changed in version 1.35.0: added support for `recvmmsg(2)` on supported platforms. The use of this feature requires a buffer larger than 2 * 64KB to be passed to `alloc_cb`. ### Versionchanged Changed in version 1.37.0: `recvmmsg(2)` support is no longer enabled implicitly, it must be explicitly requested by passing the `UV_UDP_RECVMMSG` flag to `uv_udp_init_ex()`. ### Versionchanged Changed in version 1.39.0: `uv_udp_using_recvmmsg()` can be used in `alloc_cb` to determine if a buffer sized for use with `recvmmsg(2)` should be allocated for the current handle/platform. ``` -------------------------------- ### Start Timeout Callback for libcurl Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/utilities.md Callback function invoked by libcurl to set the next timeout interval. It starts a libuv timer that will later drive libcurl's multi-socket action. ```c void start_timeout(CURLM *multi, long timeout_ms, void *userp) { if (timeout_ms <= 0) timeout_ms = 1; /* 0 means directly call socket_action, but we'll do it in a bit */ uv_timer_start(&timeout, on_timeout, timeout_ms, 0); } ``` -------------------------------- ### Start Polling a File Descriptor Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/poll.md Starts polling the file descriptor for specified events. The callback is invoked when an event is detected or an error occurs. Calling this on an active handle updates the watched events. ```c int uv_poll_start(uv_poll_t *handle, int events, uv_poll_cb cb); ``` -------------------------------- ### Execute File Operations and Run Event Loop Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/filesystem.md Sets up the initial file open operation and runs the libuv event loop. It's crucial to call `uv_fs_req_cleanup` for each request after the loop finishes to free internal memory. ```c int main(int argc, char **argv) { uv_fs_open(uv_default_loop(), &open_req, argv[1], O_RDONLY, 0, on_open); uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_fs_req_cleanup(&open_req); uv_fs_req_cleanup(&read_req); uv_fs_req_cleanup(&write_req); return 0; } ``` -------------------------------- ### Setup and Send UDP Packets Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/guide/networking.md Initializes UDP sockets for receiving and sending, binds them to specific ports and addresses, and sends a broadcast discovery message. Use 0.0.0.0 to bind to all interfaces and 255.255.255.255 for subnet broadcast. Port 0 assigns a random port. Ensure the broadcast flag is set to avoid EACCES errors. ```c uv_loop_t *loop; uv_udp_t send_socket; uv_udp_t recv_socket; int main() { loop = uv_default_loop(); uv_udp_init(loop, &recv_socket); struct sockaddr_in recv_addr; uv_ip4_addr("0.0.0.0", 68, &recv_addr); uv_udp_bind(&recv_socket, (const struct sockaddr *)&recv_addr, UV_UDP_REUSEADDR); uv_udp_recv_start(&recv_socket, alloc_buffer, on_read); uv_udp_init(loop, &send_socket); struct sockaddr_in broadcast_addr; uv_ip4_addr("0.0.0.0", 0, &broadcast_addr); uv_udp_bind(&send_socket, (const struct sockaddr *)&broadcast_addr, 0); uv_udp_set_broadcast(&send_socket, 1); uv_udp_send_t send_req; uv_buf_t discover_msg = make_discover_msg(); struct sockaddr_in send_addr; uv_ip4_addr("255.255.255.255", 67, &send_addr); uv_udp_send(&send_req, &send_socket, &discover_msg, 1, (const struct sockaddr *)&send_addr, on_send); return uv_run(loop, UV_RUN_DEFAULT); } ``` -------------------------------- ### uv_exepath Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets the executable path. ```APIDOC ## uv_exepath ### Description Gets the executable path. You *must* call uv_setup_args before calling this function. ### Parameters - **buffer** (char *): Buffer to store the executable path. - **size** (size_t *): Pointer to the size of the buffer. On success, it will be updated with the length of the executable path. On failure due to insufficient buffer size, it will be updated with the required buffer size. ### Returns - int: 0 on success, negative on error. ``` -------------------------------- ### uv_loadavg Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets the load average. ```APIDOC ## uv_loadavg ### Description Gets the load average. See: https://en.wikipedia.org/wiki/Load_(computing) ### NOTE Returns [0,0,0] on Windows (i.e., it’s not implemented). ### Parameters - **avg** (double[3]): An array of three doubles to store the load average values (1-minute, 5-minute, 15-minute). ``` -------------------------------- ### uv_udp_init_ex Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/udp.md Initializes a UDP handle with specified flags, allowing for domain specification and enabling features like recvmmsg. ```APIDOC ## uv_udp_init_ex ### Description Initialize the handle with the specified flags. The lower 8 bits of the flags parameter are used as the socket domain. A socket will be created for the given domain. If the specified domain is `AF_UNSPEC` no socket is created, just like `uv_udp_init()`. The remaining bits can be used to set one of these flags: * UV_UDP_RECVMMSG: if set, and the platform supports it, `recvmmsg(2)` will be used. #### Versionadded Added in version 1.7.0. #### Versionchanged Changed in version 1.37.0: added the UV_UDP_RECVMMSG flag. ### Signature ```c int uv_udp_init_ex(uv_loop_t *loop, uv_udp_t *handle, unsigned int flags) ``` ``` -------------------------------- ### uv_cpu_info Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets information about the CPUs on the system. ```APIDOC ## uv_cpu_info ### Description Gets information about the CPUs on the system. The cpu_infos array will have count elements and needs to be freed with `uv_free_cpu_info()`. ### Parameters - **cpu_infos** (uv_cpu_info_t **): Output parameter to store an array of CPU information structures. - **count** (int *): Output parameter to store the number of CPU information structures. ### Returns - int: 0 on success, negative on error. ``` -------------------------------- ### uv_signal_start_oneshot Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/signal.md Starts monitoring a signal for a single occurrence. ```APIDOC ## uv_signal_start_oneshot ### Description Starts the signal handle for a single signal reception. The handler is reset after the signal is caught. ### Parameters - **signal** ([uv_signal_t](#c.uv_signal_t) *) - The initialized signal handle. - **cb** ([uv_signal_cb](#c.uv_signal_cb)) - The callback function to be executed when the signal is received. - **signum** (int) - The signal number to monitor. ### Return Value Returns 0 on success, or a negative error code on failure. ### Versionadded Added in version 1.12.0. ``` -------------------------------- ### Import GPG Key (Standard) Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Imports a GPG public key from a keyserver using the standard method. ```bash gpg --keyserver pool.sks-keyservers.net --recv-keys AE9BC059 ``` -------------------------------- ### QNX Platform Configuration Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/CMakeLists.txt Appends source files and links the 'socket' library for the QNX platform. ```cmake list(APPEND uv_sources src/unix/posix-hrtime.c src/unix/posix-poll.c src/unix/qnx.c src/unix/bsd-ifaddrs.c src/unix/no-proctitle.c src/unix/no-fsevents.c) list(APPEND uv_libraries socket) ``` -------------------------------- ### uv_interface_addresses Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets address information about the network interfaces on the system. ```APIDOC ## uv_interface_addresses ### Description Gets address information about the network interfaces on the system. An array of count elements is allocated and returned in addresses. It must be freed by the user, calling `uv_free_interface_addresses()`. ### Parameters - **addresses** (uv_interface_address_t **): Output parameter to store an array of network interface address structures. - **count** (int *): Output parameter to store the number of network interface address structures. ### Returns - int: 0 on success, negative on error. ``` -------------------------------- ### Build Live HTML Documentation (Unix) Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Builds HTML documentation with live reload. Requires sphinx-autobuild and is Unix-specific. ```bash make livehtml ``` -------------------------------- ### Run a static file server with one function call Source: https://context7.com/rstudio/httpuv/llms.txt Starts a static file server for a specified local directory. This function can run in the background and automatically opens the browser in interactive sessions. Use `browse = FALSE` to prevent automatic browser opening. ```R library(httpuv) # Serve a directory in the background server <- runStaticServer( dir = "~/my-website", host = "127.0.0.1", port = 4321, background = TRUE, browse = FALSE ) # Serving: '~/my-website' # View at: http://127.0.0.1:4321 catalogue("Static server on port:", server$getPort(), "\n") # Use the bundled example site website_dir <- system.file("example-static-site", package = "httpuv") runStaticServer(dir = website_dir) # blocks; Ctrl+C to stop ``` -------------------------------- ### Build Man Pages Documentation Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/README.md Command to build the documentation in man page format. ```bash make man ``` -------------------------------- ### uv_fs_poll_start Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/fs_poll.md Starts monitoring a given path for changes at a specified interval. ```APIDOC ## uv_fs_poll_start ### Description Check the file at path for changes every interval milliseconds. ### Parameters #### Path Parameters - **handle** ([uv_fs_poll_t](#c.uv_fs_poll_t) *) - The FS Poll handle. - **poll_cb** ([uv_fs_poll_cb](#c.uv_fs_poll_cb)) - The callback function to be invoked when changes are detected. - **path** (const char *) - The path to monitor. - **interval** (unsigned int) - The interval in milliseconds to check for changes. ### NOTE For maximum portability, use multi-second intervals. Sub-second intervals will not detect all changes on many file systems. ### Returns Returns 0 on success or an error code less than 0 in case of failure. ``` -------------------------------- ### uv_get_total_memory Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/misc.md Gets the total amount of physical memory in the system, in bytes. ```APIDOC ## uv_get_total_memory ### Description Gets the total amount of physical memory in the system (in bytes). ### Return Value - **uint64_t** - The total amount of physical memory in bytes. ``` -------------------------------- ### uv_open_osfhandle Source: https://github.com/rstudio/httpuv/blob/main/src/libuv/docs/src/fs.md Gets the C runtime file descriptor for an OS-dependent handle. ```APIDOC ## uv_open_osfhandle ### Description For a OS-dependent handle, get the file descriptor in the C runtime. On UNIX, returns the `os_fd` intact. On Windows, this calls [\_open_osfhandle](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-osfhandle?view=vs-2019). Note that this consumes the argument, any attempts to close it or to use it after closing the return value may lead to malfunction. #### Versionadded Added in version 1.23.0. ```