libebb

libebb is a lightweight HTTP server library for C. It lays the
foundation for writing a web server by providing the socket juggling
and request parsing. By implementing the HTTP/1.1 grammar provided in
RFC2612, libebb understands most most valid HTTP/1.1 connections
(persistent, pipelined, and chunked requests included) and rejects
invalid or malicious requests. libebb supports SSL over HTTP.

The library embraces a minimalistic single-threaded evented design.
No control is removed from the user. For example, all allocations are
done through callbacks so that the user might implement in optimal
ways for their specific application. By design libebb is not
thread-safe and all provided callbacks must not block. libebb uses
the high-performance
libev event loop, but does not control it. The user of the library may
start and stop the loop at will, they may attach thier own watchers.

libebb depends on POSIX sockets, libev, and optionally GnuTLS.

libebb is in the early stages of development and probably contains
many bugs. The API is subject to radical changes. If you're
interested checkout
the source code and join the mailing
list. A release will be made when it proves stable.

Usage

libebb is a simple API, mostly it is providing callbacks. There are
two types of callbacks that one will work with:

callbacks to allocate and initialize data for libebb. These are
named new_* like new_connection and
new_request

callbacks which happen on an event and might provide a pointer to
a chunk of data. These are named on_* like
on_body and on_close.

In libebb there are three important classes: ebb_server,
ebb_connection, and ebb_request.
Each server has many peer connections. Each peer connection may have many
requests.
There are two additional classes ebb_buf and ebb_request_parser
which may or may not be useful.

ebb_server

ebb_server represents a single web server listening on a
single port. The user must allocate the structure themselves, then
call ebb_server_init() and provide a libev event loop.
ebb_server_set_secure() will make the server understand
HTTPS connections.

After initialized the ebb_server_listen_on_port() can be
called to open the server up to new connections. libebb does not
control the event loop, it is the user's responsibility to start the
event loop (using ev_loop()) after
ebb_server_listen_on_port() is called.

To accept connections you must provide the new server with a callback
called new_connection. This callback must return an allocated
and initialized ebb_connection structure.
To set this callback do

my_server->new_connection = my_new_connection_callback;

Additional documentation can be found in ebb.h

ebb_connection

This structure contains information and callbacks for a single client
connection. It is allocated and initialized through the
new_connection callback in ebb_server.
To initialize a newly allocated ebb_connection use
ebb_connection_init().

After ebb_connection_init() is called a number of
callbacks can be set: new_request, new_buf,
on_timeout, and on_close.

When an ebb_connection is returned to an
ebb_server, data is immediately data is read from the
socket. This data must be stored somewhere. Because libebb is
agnostic about allocation decisions, it passes this off to the user in
the form of a callback: connection->new_buf. This
callback returns a newly allocated and initialized
ebb_buf structure. How much libebb attempts to read from
the socket is determined by how large the returned
ebb_buf structure is. Using new_buf is
optional. By default libebb reads data into a static buffer
(allocated at compile time), writing over it on each read. In many
web server using the static buffer will be sufficent because callbacks
made during the parsing will buffer the data elsewhere. Providing a
new_buf callback is necessary only if you want to save
the raw data coming from the socket.

The new_request callback is called at the beginning of a
request. It must return a newly allocated and initialized
ebb_request structure. Because HTTP/1.1 supports peristant
connections, there may be many requests per connection.

You may access the file descriptor for the client socket inside the
ebb_connection structure. Writing the response, in valid
HTTP, is the user's responsibility. Remember, requests must be
returned to client in the same order that they were received.

A convience function, ebb_connection_write, is provided
which will write a single string to the peer. You may use
this function or you may write to the file descriptor directly.

To close a peer connection use
ebb_connnection_schedule_close(). Because SSL may require
some additional communication to close the connection properly, the
file descriptor cannot be closed immediately. The
on_close callback will be made when the peer socket is
finally closed.
Only once on_close is called may the
user free the ebb_connection structure.

ebb_request

This structure provides information about a request. For example,
request->method == EBB_POST would mean the method of
the request is POST. There are also many callbacks
which can be set to handle data from a request as it is parsed.

The on_uri callback and all other
ebb_element_cb callbacks provide pointers to request
data. The annoying thing is they do not necessarily provide a
complete string. This is because the reads from the socket may not
contain an entire request and for efficency libebb does not attempt to
buffer the data. Theoretically, one might receive an
on_uri callback 10 times, each providing just a single
character of the request's URI. See ebb_request_parser.h for
a full list of callbacks that you may provide. (If you don't set them,
they are ignored.)

The on_complete callback is called at the end of
each request.
Only once on_complete is called may the
user free the ebb_request structure.