Unser Server verwaltet Verbindungen mithilfe eines synchronen I/O-Multiplexing-Systems. Sockets bleiben für jede eingehende Verbindung aktiv, und ein Timeout-System stellt sicher, dass sie geschlossen werden, wenn innerhalb der in der Konfiguration definierten Zeit keine Aktivität erfolgt. Die Konfiguration ist flexibel und erlaubt präzise Standortberechtigungen und Einstellungen. CGI kann ausgeführt und über ein CGI-Skriptverzeichnis konfiguriert werden. Timeout-Zeit und maximale Body-Größe können ebenfalls pro Server gesetzt werden. Zusätzlich können beliebig viele Server in einer einzigen Konfiguration definiert werden.
Socket-Management:
Wir verwenden poll(), um eingehende Verbindungen effizient zu verwalten. Server können eine beliebige Anzahl gleichzeitiger Anfragen verarbeiten, ohne abzustürzen.
HTTP-Methoden:
Aktuell implementiert sind GET, POST und DELETE. Diese müssen pro Location im Server-Root über die Konfigurationsdatei explizit aktiviert werden. GET sendet angeforderte Daten an den Client zurück. POST lädt Daten vom Client in den Upload-Speicher des Servers hoch (ebenfalls in der Konfiguration definiert). DELETE entfernt angeforderte Daten vollständig vom Server. Diese Methoden sind selbstverständlich durch Sicherheitsmechanismen abgesichert.
Konfigurationsdirektiven: Es gibt viele Konfigurationsdirektiven, mit denen verschiedene Serverfunktionen gesteuert werden können. Für alle fehlenden Direktiven existieren Standardwerte. Eine detaillierte Tabelle wird im nächsten Abschnitt gezeigt.
CGI-Skriptausführung:
Der Server unterstützt die Ausführung von CGI-Skripten, die über die Direktive cgi-path konfiguriert werden können. Diese definiert den Pfad, anhand dessen CGI-Anfragen erkannt werden.
Beispielseiten und Konfiguration: Das Projekt enthält eine Standardkonfiguration sowie eine Beispiel-Website mit mehreren HTML-Seiten und CSS-Styling. Es gibt eine Upload-Seite zum Testen von POST-Anfragen sowie eine CGI-Testseite, die Eingaben an ein Beispielprogramm weiterleitet, welches die Daten verarbeitet und als HTML zurückgibt.
Ausführliches Logging: Zusätzlich wurde ein robustes Logging- und Debugging-System implementiert, das zur Laufzeit hilfreiche Informationen ausgibt, etwa Request-Daten und Fehler.
Das Programm kann einfach mit ./webserv gestartet werden. Dabei wird automatisch die Datei default.conf verwendet, sofern vorhanden. Für eine eigene Konfiguration kann es mit ./webserv [Pfad zur Konfigurationsdatei] gestartet werden.
Der Prozess läuft anschließend unbegrenzt und gibt Logs aus, bis er durch ein Interrupt-Signal mit CTRL+C beendet wird.
Es können beliebig viele Server-Scopes und Location-Scopes innerhalb eines Servers definiert werden. Keine Direktive ist zwingend erforderlich, da für alle Werte Standardwerte existieren. Wird z. B. kein Index definiert, wird automatisch index.html verwendet. Falls diese Datei nicht existiert, wird eine 404-Antwort zurückgegeben.
Jeder Scope wird mit { } geöffnet und geschlossen, jede Direktive endet mit ;.
Hier sind alle verfügbaren Direktiven und Scopes im Konfigurationssystem:
| Schlüsselwort | Typ | Felder | Beschreibung |
|---|---|---|---|
| server | Scope | Servername | Definiert einen Server, der beim Start ausgeführt wird. |
| error_page | Direktive | Statuscode, Seitenpfad | Setzt die Antwortseite für einen bestimmten HTTP-Statuscode. |
| location | Scope | Pfad (relativ zum Server-Root) | Definiert eine Location innerhalb des Servers. Muss innerhalb eines Server-Scopes liegen. |
| listen | Direktive | Portnummer | Legt den Port fest, auf dem der Server lauscht. |
| host | Direktive | IP-Adresse | Legt die IP-Adresse fest, auf der der Server läuft. |
| root | Direktive | Pfad | Definiert das Root-Verzeichnis des Servers. |
| index | Direktive | Dateipfad/Dateiname | Definiert die Standarddatei für einfache Serveranfragen. |
| timeout | Direktive | Zeit (Sekunden) | Maximale Zeit, die eine Socket-Verbindung ohne Aktivität offen bleibt. |
| cgi | Direktive | Dateiendungen | Definiert Dateitypen, die als CGI-Skripte behandelt werden. |
| max_body | Direktive | Größe (Bytes) | Setzt die maximale Body-Größe für POST-Anfragen pro Location. |
| methods | Direktive | Methodennamen (durch Leerzeichen getrennt) | Definiert erlaubte HTTP-Methoden für eine Location. |
| return | Direktive | Pfad-Aliase | Definiert Weiterleitungen (Aliases) zu der Location, in der die Direktive gesetzt ist. |
Beispielkonfiguration:
server {
listen 8080;
host 127.0.0.1;
root www/;
index index.html;
timeout 10;
location / {
methods GET;
}
location scripts/ {
index ../pages/scripts.html;
methods GET POST;
cgi .sh .py .php;
return cgi-bin/;
}
location uploads/ {
index ../pages/upload.html;
methods GET POST DELETE;
max_body 8000000;
}
}