Looking through programming articles sometimes I see posts about creating your own HTTP server. I am most interested in C++ so I often read blogs about it. After looking them through you could easily write you own web server “on sockets” using boost.asio or something else. I also examined libevent and libev. Each of them has its advantages. Libevent is of great interest to me for developing a small HTTP server. Considering some innovations in C++11 the code becomes much more space-efficient and allows for the creation of a basic HTTP server in less than 40 lines.
The information of this post will be useful for those not familiar with libevent and those who want to quickly create an HTTP server. There’s nothing innovative in this post, so you can use it as material for working in the right direction.
libevent is better than libev and boost.asio because of its embedded HTTP server and some abstraction for operating with buffers. It also has a large set of helper functions. You can examine HTTP protocol by yourself by writing a simple FSN (finite state machine) or maybe through some other means. When working with libevent – it’s all there already. You can also go to a lower level and write your own parser for HTTP and perform the work with sockets on libevent. I liked the detail level of this library. If you want to do something quickly you’ll find a higher-level interface that is usually less flexible. When there are more serious requirements you can go down gradually, level by level. The library allows doing many things, such as: asynchronous input/output, work with the network, work with timers, rpc, etc. You can also use it to create both server-side and client-side software.
What for?
Creating a private small HTTP server can be dictated by certain needs, wish or unwillingness to use full-blown ready servers by one or other reason.
Suppose, you have some server software that operates according to some protocol and solves some tasks. You need to give some API for the given software according to an HTTP protocol. There are just several small functions possible for the server setup and getting its current state according to the HTTP protocol. For example, you can arrange them for GET requests processing with parameters returning a small xml/json/text response. In this case you’ll be able to easily create your own HTTP server that will provide the interface for your server software. If you also want to create a small private special service for the distribution of some file set or even create your own web application you can also use this small server for that purpose. You can use it for the construction of all-sufficient server software as well as for creation of auxiliary services within the limits of bigger systems.
Lightweight HTTP Server in less than 40 Lines
You should perform the following steps in order to create a simple single-threaded HTTP server using libevent:
- Initialize a global object of the library using event_init function. You can use this function for single-threaded processing only. In order to execute a multi-threaded operation you should create a separate object for every thread.
- Create http server using evhttp_start in case of a single-threaded server with a global object of event processing. You should delete the object created with the help of evhttp_start by using evhttp_free.
- In order to respond to the incoming requests you should setup a callback function with the help of evhttp_set_gencb.
- Then you can start the loop of event processing using event_dispatch function. This function is meant for operating with the global object in one thread.
- When processing the request you can get a response buffer utilizing evhttp_request_get_output_buffer function. You can add some content to the buffer. For example, in order to send the line you can use evbuffer_add_printf function. If you want to send a file use evbuffer_add_file function. Then a response to the request should be sent. You can do this with the help of evhttp_send_reply.
The code of a single-threaded server in less than 40 lines:
#include
#include
#include
#include
int main()
{
if (!event_init())
{
std::cerr Server(evhttp_start(SrvAddress, SrvPort), &evhttp_free);
if (!Server)
{
std::cerr Hello World!