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.
libebb is released under the X11 license.
libebb is a simple API, mostly it is providing callbacks. There are two types of callbacks that one will work with:
new_*
like new_connection
and
new_request
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,
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.
A simple example is provided in examples/hello_world.c
.