(Yet another) C web framework
Switch branches/tags
Nothing to show
Pull request Compare This branch is 8 commits ahead of MechanisM:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.




Tofu is a framework for building web applications in C with as minimal effort as possible, allowing simple web applications to be created rapidly and with few lines of C code.

Tofu is web server agnostic, which means that applications written using the Tofu API can be run on a wide variety of backend web servers with very little work on the app developer side.

Attention: Tofu is highly experimental software, take it as a proof-of-concept.


Put the following code into hi.c:

#include <tofu.h>

tofu_rep_t *hello(tofu_req_t *req) {
  tofu_rep_t *rep = tofu_rep_init();

  tofu_head(rep, "Content-Type", "text/html");
  tofu_write(rep, "Hello World!");

  return rep;

int main() {
  char *opts[] = { "", "8080" };
  tofu_ctx_t *ctx = tofu_ctx_init(TOFU_EVHTTP, opts);

  tofu_handle_with(ctx, GET, "/hi", hello);

  return 0;

compile and run with:

$ cc -o hi hi.c -ltofu
$ ./hi

then visit with your browser.


A Tofu web application consists in a Tofu context and one or more route handlers. On startup the application has to initialize a Tofu context (tofu_ctx_t) which holds all the information needed to run the application. The backend to be used by the application can be chosen in this phase.

The handlers are functions that take as only argument a Tofu request (tofu_req_t) and return a Tofu response (tofu_rep_t). Every handler has to be registered and associated with an HTTP method (GET POST ...) and a route pattern using the tofu_handle_with() function:

tofu_handle_with(ctx, GET, "/route/:param", handler_function);

A route pattern can contain one or more tokens (words prefixed by :). Each token found in a route pattern is then included in the Tofu request so that it can be accessed by the route handler. For example the route /page/:name is matched against the /page/index request, and the correspondent handler can fetch the name paramenter using the tofu_param() function:

char *param = tofu_param(req, "name");

The param variable will contain the string "index".

An handler can be also defined to only handle execution errors, for example 404 or 500 errors. To register an error handler the function tofu_rescue_with() has to be used:

tofu_rescue_with(ctx, 404, err404_handler_func);

The error handlers get invoked in various situations:

  • when there is an error in the backend (error 500)
  • when no handler is defined to handle a specific request (error 404)
  • when an handler returns a Tofu response with status in the range 400 <= x < 600 (whatever error is set).

By default Tofu can handle some errors (i.e. 404s or 500s) if no other handler has been defined in the application.


Tofu does not provide any advanced functionalities that may be useful when developing web applications. Here's a list of useful external libraries to extend your Tofu applications (or any other software written in C/C++):

  • houdini is a simple API for escaping and unescaping text for the web.
  • amaca is a tiny template engine which natively supports Lua scripting.
  • ctpl is another template library written in C.
  • jansson is a C library for encoding, decoding and manipulating JSON data.
  • discount is an implementation of John Gruber's Markdown markup language.
  • hiredis is a minimalistic C client library for the Redis database.
  • libmongo-client is an alternative C driver for MongoDB.

If you know any other library, please let me know.


  • pcre
  • libfcgi (only for the fcgi backend)
  • libevent (>= 2.0) (only for the evhttp backend)
  • jansson (only for the zmq backend)
  • zeromq (only for the zmq backend)


Tofu is distributed as source code. Build with:

$ git clone git://github.com/AlexBio/Tofu.git && cd Tofu
$ ./autogen.sh
$ ./configure
$ make

By default all the backends are built.


Copyright (C) 2011 Alessandro Ghedini al3xbio@gmail.com

See COPYING for the license.