elouann.dev
FR — version française

ProjectsSystems, network & algorithms

Webserv

An Nginx-like HTTP server

Period
Nov 2025 – Jan 2026
Context
42 curriculum
Team
group
Grade
125/100
  • C++
  • Low-level
  • Network
  • Object-oriented programming

View source

An HTTP server in C++, modelled on Nginx down to its configuration file. One process, one event loop, and no operation that blocks.

descriptorslisten :8080LISTENclientCLIENTclientCLIENTCGI pipesCGI_IN / CGI_OUTepoll_waitone single loopaccept()new clientread, parseHttpRequestlocationNginx configfilecacheCGIfork + pipessendEPOLLOUTCGI pipes join epoll: a slow script blocks nothing
DiagramEvery descriptor (listening sockets, clients, CGI pipes) goes through epoll. Each event is routed according to the context attached to its descriptor.

The event loop

No thread per connection: the server registers all its descriptors with epoll, in non-blocking mode, then waits in epoll_wait. Each descriptor has a small context attached (its role: listening, client, CGI input or output) that immediately says what to do when it is ready.

A request may arrive in several pieces, and a response may leave in several writes: everything is buffered, and the server switches between EPOLLIN and EPOLLOUT depending on whether it is waiting for a request or has something to send. Keep-alive connections are reused.

Configuration and CGI

The Nginx-style configuration file goes through its own lexer and parser, which build a tree of server and location blocks: ports, roots, index files, allowed methods, error pages.

For scripts (PHP, Python), the server starts a CGI: a child process connected by two pipes, also watched by epoll, so a slow script never makes the server wait. A file cache and custom error pages round it off.

What I took away

  • A read or a write never necessarily transfers everything at once.
  • The event-driven model: one thread can serve many clients.
  • HTTP looks like a simple text protocol, but it is full of edge cases.