Note:
This project is currently a proof of concept and represents the bare minimum viable product (MVP).
It is not designed for production use, and there may be bugs, limitations, or incomplete features.
Use at your own discretion.
Welcome to c-web-modules, a modular and efficient approach to web development in C. Inspired by kernel modules and AWS Lambda, this project allows you to upload C code directly to the server, which compiles and deploys it at runtime. No precompilation is necessary, and the server can easily be upgraded to include more features or external libraries.
For more detailed information, please refer to the official documentation.
C isn’t typically the go-to for web development, and there are valid reasons why. Here’s how c-web-modules tackles some of the common concerns:
-
Slow Build Cycles:
Instead of recompiling the entire application, c-web-modules allows you to upload raw C code. The server compiles it on-the-fly, enabling rapid iteration and eliminating the need for restarts. This is as close to "hot reloading" as you can get with C. -
Speed vs. Practicality:
While raw computation speed might not always be critical for web apps, c-web-modules shines in scenarios where performance matters, like handling heavy data processing or real-time applications. Modules let you inject optimized performance-critical code where it’s needed. -
Manpower and Time-to-Market:
By automating common server tasks (e.g., routing, module integration, and shared resources like SQLite3), c-web-modules reduces boilerplate and accelerates development compared to starting from scratch. It's not as fast as scripting languages, but it's far from the manual grind of traditional C projects. -
Memory Management and Crashes:
Modules are isolated and dynamically managed, reducing the risk of crashing the entire server. While C still requires careful memory management, the modular approach lets you focus on smaller, manageable pieces of functionality rather than tackling a monolithic application. -
Pre-Made Solutions:
By supporting external libraries like SQLite3, OpenSSL, and Jansson out of the box, c-web-modules leverages existing solutions, allowing developers to skip reinventing the wheel and focus on their application's unique needs.
This isn’t a silver bullet—it’s a proof of concept. But c-web-modules aims to bring C’s raw power into the web world in a more developer-friendly way.
Here’s a simple example of a module that keeps track of a counter and returns its value every time you visit /counter
.
See more examples in the example/
folder.
SQLite3 App (TODO)
#include <stdio.h>
#include <cweb.h>
static int counter = 0;
static const char* template =
"<html>\n"
" <body>\n"
" <h1>Counter: %d</h1>\n"
" </body>\n"
"</html>\n";
/* Route: /counter - Method GET */
static int index_route(struct http_request *req, struct http_response *res) {
snprintf(res->body, HTTP_RESPONSE_SIZE, template, counter++);
res->status = HTTP_200_OK;
return 0;
}
/* Define the routes for the module */
export module_t config = {
.name = "counter",
.author = "cweb",
.routes = {
{"/counter", "GET", index_route, NONE},
},
.size = 1,
};
- Code Deployment: Upload raw C code to the server for on-the-fly compilation and deployment.
- No Precompilation: Simplify your workflow—focus on writing code, and let the server handle compilation.
- Dynamic Updates: Add or replace functionality without downtime or recompiling the entire server.
- Performance: Written in C, the server offers unmatched speed and efficiency.
- WebSocket Support: Even when modules are updated, existing WebSocket connections remain alive.
- Built-In Features: Includes a cross-module cache and scheduler for deferred tasks.
- Regex in Paths: Define routes using regular expressions for more flexible and powerful URL matching.
Currently supported external libraries:
- OpenSSL: Currently only for hashing, but later for secure communication.
- SQLite3: Shared by all modules for lightweight database needs.
- Jansson: For easy JSON parsing and manipulation.
Deploying code to the server is simple and can be done in multiple ways, depending on your workflow.
At its core, deploying code to the server involves sending a POST request with the C file attached. Here’s an example using curl
:
curl -X POST -F "code=@path/to/yourcode.c" http://localhost:8080/mgnt
The script handles:
- Sending the file to the server using
curl
. - Parsing responses for success or failure.
- Providing helpful logs and error messages.
./cweb deploy path/to/yourcode.c
You can deploy multiple modules in one go using a configuration file. By default, the script looks for a file named routes.ini
.
Example routes.ini
file:
server_url=http://localhost:8080/mgnt
[modules]
example1.c
example2.c
When using the .ini files you run: ./cweb deploy
For Windows there currently only is a very primitve deploy.bat script:
.\deploy.bat file.c
The server needs to be specified inside the .bat file, default is: http://localhost:8080/mgnt
Error messages are forwarded back to you over http.
Note:
MacOS support is not guaranteed!
The project depends on:
# Debian
sudo apt-get install libssl-dev
sudo apt-get install libsqlite3-dev
sudo apt-get install libjansson-dev
# Arch
sudo pacman -S openssl
sudo pacman -S sqlite
sudo pacman -S jansson
# Bug with archlinux and fanitizser, ref: https://github.com/joexbayer/c-web-modules/issues/12
sudo sysctl vm.mmap_rnd_bits=30
# MacOS
brew install openssl@3
brew install sqlite
brew install jansson
Run make to compile and make run to start the server.
make
make run
docker-compose up --build
Unlike Apache modules and ISAPI extensions, which are tightly integrated into the server and require configuration changes followed by a server restart or reload, c-web-modules offers runtime flexibility.
Key Differences:
-
Dynamic Deployment:
c-web-modules allows you to upload raw C code directly to the server, which compiles and integrates it into the running application without restarts. Neither Apache modules nor ISAPI extensions support this level of runtime modification. -
Module Isolation:
Each module in c-web-modules is independently managed, minimizing the risk of crashing the entire server. -
WebSocket Updates:
WebSocket handlers can be updated at runtime without breaking existing connections, a feature not typically available in Apache modules or ISAPI.
This makes c-web-modules suitable for rapid experimentation and modular design, especially in scenarios requiring frequent updates without disrupting service.