← Retour aux projets

École 42 · 100/100

Webserv

Un serveur HTTP écrit intégralement en C++, dans l'esprit de nginx : analyse de configuration, boucle d'événements non bloquante et exécution CGI.

Webserv est l'un des projets les plus exigeants du cursus 42 : reconstruire, en C++98 et sans bibliothèque HTTP externe, un serveur capable de servir des fichiers statiques, d'exécuter du CGI et de gérer plusieurs clients simultanément, à partir des seuls appels système (socket, poll, fork, execve). Pour être validé, il doit aussi encaisser un vrai test de charge (siege) sans jamais planter, fuir de la mémoire, ni rester bloqué.

Architecture

Le serveur repose sur une boucle d'événements unique construite autour de poll(), qui multiplexe en même temps les sockets d'écoute, les connexions clientes et les pipes CGI.

Chaque socket est passé en non bloquant, ce qui permet à un seul thread de traiter un grand nombre de connexions sans jamais rester bloqué sur l'une d'elles.

L'exécution CGI

L'exécution de scripts CGI est entièrement non bloquante : pipe(), fork(), dup2() puis execve() lancent le script, dont l'avancement est suivi par une machine à états dédiée.

Un script qui dépasse son délai est interrompu proprement, et les en-têtes qu'il renvoie sont réinjectés dans la réponse HTTP finale.

Parsing incrémental

Les requêtes HTTP sont analysées au fur et à mesure des données reçues, sans supposer qu'une requête arrive en une seule lecture : ligne de requête, en-têtes puis corps (avec gestion du Content-Length).

Configuration

Le format de configuration reprend la syntaxe de nginx (blocs server et location), analysé par un pipeline lexer puis parseur produisant un arbre syntaxique. Plusieurs blocs server, ports et noms d'hôtes peuvent cohabiter dans un seul fichier.

Ce que ça m'apporte aujourd'hui

Avoir écrit un serveur HTTP à partir des seuls appels système change la façon dont je lis un problème aujourd'hui. Que ce soit un comportement étrange derrière NGINX en production, ou un endpoint NestJS que je conçois chez Fair3, je ne raisonne plus sur une boîte noire : je sais concrètement ce qui se passe entre la requête et la réponse, du parsing des en-têtes à la gestion du keep-alive.

Ça a aussi construit un vrai instinct sécurité. Avoir géré moi-même le parsing HTTP et l'exécution CGI, avec leurs cas limites, me donne une intuition concrète de la façon dont naissent des vulnérabilités comme l'injection dans l'environnement CGI ou le request smuggling, pas seulement un terme retenu d'un cours.