Schnellstart
Quelldateien
Diese Seite wurde aus den folgenden Quelldateien erstellt:
Kompilierung und Vorbereitung
Tinyhttpd ist ein minimalistischer HTTP-Server, der ursprünglich für Sparc Solaris 2.6 entwickelt wurde. Für die Kompilierung unter Linux sind spezifische Anpassungen im Quellcode erforderlich.
Build-Konfiguration
Das Projekt verwendet ein einfaches Makefile, das zwei Hauptziele definiert: den Server (httpd) und einen Testclient (client). Die Kompilierung erfolgt mit GCC und bindet die pthread-Bibliothek ein (Makefile:1-9).
bash1# Kompilierung starten 2make all
Das Makefile definiert folgende Build-Regeln:
- httpd: Kompiliert
httpd.cmit Debug-Symbolen (-g) und aktivierten Warnungen (-W -Wall) - client: Kompiliert
simpleclient.czu einer ausführbaren Testanwendung - clean: Entfernt die generierte
httpd-Binary
Linux-spezifische Anpassungen
Der Quellcode enthält Kommentare zur Linux-Portierung. Für die Kompilierung unter Linux müssen folgende Änderungen vorgenommen werden (httpd.c:7-14):
- Die Zeile
#include <pthread.h>auskommentieren - Die Variable
newthreadauskommentieren - Die beiden
pthread_create()-Aufrufe auskommentieren - Den Aufruf von
accept_request()einkommentieren -lsocketaus dem Makefile entfernen
Die README-Datei bestätigt diese Anpassungen und bietet eine detaillierte Anleitung für die Linux-Kompilierung (README.md:5-14).
Abhängigkeiten
Für CGI-Tests muss das System über Perl verfügen. Die README spezifiziert, dass sowohl Perl als auch das Modul perl-cgi installiert sein müssen (README.md:1-3).
bash1# Debian/Ubuntu 2sudo apt-get install perl libcgi-pm-perl 3 4# CentOS/RHEL 5sudo yum install perl perl-CGI
Server-Initialisierung
Die Server-Initialisierung erfolgt über die Funktion startup(), die einen TCP-Socket erstellt, diesen an einen Port bindet und auf eingehende Verbindungen wartet.
Socket-Erstellung und Konfiguration
Die startup()-Funktion implementiert die vollständige Server-Initialisierung (httpd.c:429-458):
c1int startup(u_short *port) 2{ 3 int httpd = 0; 4 int on = 1; 5 struct sockaddr_in name; 6 7 httpd = socket(PF_INET, SOCK_STREAM, 0); 8 // ... Fehlerbehandlung ... 9 memset(&name, 0, sizeof(name)); 10 name.sin_family = AF_INET; 11 name.sin_port = htons(*port); 12 name.sin_addr.s_addr = htonl(INADDR_ANY); 13 // ... bind() und listen() ... 14}
Die Funktion führt folgende Schritte aus:
- Erstellung eines TCP-Sockets mit
socket(PF_INET, SOCK_STREAM, 0) - Setzen der
SO_REUSEADDR-Socket-Option zur Wiederverwendung lokaler Adressen - Binden des Sockets an alle verfügbaren Netzwerkschnittstellen (
INADDR_ANY) - Starten des Listening mit einer Backlog-Queue von 5 Verbindungen
Dynamische Portzuweisung
Wenn der Port-Parameter mit dem Wert 0 übergeben wird, weist das System dynamisch einen freien Port zu. Die Funktion ermittelt den tatsächlich zugewiesenen Port über getsockname() und aktualisiert die Port-Variable (httpd.c:448-453).
Die README beschreibt den Server-Start wie folgt: Der Server startet und bindet den HTTP-Dienst an einen angegebenen Port oder wählt zufällig einen Port aus (README.md:35-36).
Anfrageverarbeitung und Workflow
Die Anfrageverarbeitung folgt einem klaren Workflow, der in der README dokumentiert ist und durch die Funktionen in httpd.c implementiert wird.
HTTP-Request-Parsing
Beim Empfang einer HTTP-Anfrage extrahiert der Server zunächst die HTTP-Methode (GET oder POST) und die URL. Bei GET-Anfragen mit Parametern zeigt der query_string-Zeiger auf den Teil nach dem Fragezeichen (README.md:37-40).
Die URL wird in das path-Array formatiert, wobei der Pfad relativ zum htdocs-Verzeichnis interpretiert wird. Endet die URL mit einem Schrägstrich oder verweist auf ein Verzeichnis, wird automatisch index.html angehängt.
CGI-Entscheidung und Datei-Serving
Der Server entscheidet basierend auf folgenden Kriterien, ob eine Anfrage als CGI behandelt wird:
- Die Anfrage verwendet die POST-Methode
- Die GET-Anfrage enthält Query-Parameter (Fragezeichen in der URL)
- Die Zieldatei ist als ausführbar markiert (
S_IXUSR,S_IXGRPoderS_IXOTH)
Für statische Dateien ruft der Server die Funktion serve_file() auf (httpd.c:400-419). Diese Funktion:
- Liest und verwirft die HTTP-Header der Anfrage
- Öffnet die angeforderte Datei
- Sendet HTTP-Header an den Client
- Überträgt den Dateiinhalt über den Socket
正在加载图表渲染器...
Verzeichnisbehandlung
Wenn der angeforderte Pfad ein Verzeichnis ist, wird automatisch index.html an den Pfad angehängt. Dies geschieht in der accept_request()-Funktion, nachdem stat() bestätigt hat, dass der Pfad existiert (httpd.c:121-122).
Testen und Abhängigkeiten
CGI-Testanforderungen
Für die Ausführung der mitgelieferten CGI-Skripte sind zusätzliche Abhängigkeiten erforderlich. Die README spezifiziert, dass Perl und das Modul perl-cgi installiert sein müssen (README.md:1-3).
Die CGI-Skripte befinden sich im Verzeichnis htdocs/ und umfassen:
check.cgi- Ein Testskript für CGI-Funktionalitätcolor.cgi- Ein interaktives Farbskript (der ursprüngliche Autor empfiehlt, "chartreuse" als Eingabe zu testen)
Client-Kommunikationstest
Das Projekt enthält einen einfachen Testclient (simpleclient.c), der eine Verbindung zum Server auf Port 9734 herstellt (simpleclient.c:8-33).
c1// simpleclient.c - Verbindung zum lokalen Server 2address.sin_addr.s_addr = inet_addr("127.0.0.1"); 3address.sin_port = htons(9734);
Der Client sendet ein einzelnes Zeichen an den Server und liest die Antwort. Dies dient zur grundlegenden Überprüfung der Socket-Kommunikation.
Manueller Test mit curl
Nach erfolgreicher Kompilierung und Start des Servers kann die Funktionalität mit curl getestet werden:
bash1# Statische Datei abrufen 2curl http://localhost:<PORT>/index.html 3 4# CGI-Skript testen 5curl "http://localhost:<PORT>/color.cgi?color=chartreuse"
Hinweis: Der tatsächliche Port muss der Serverausgabe entnommen werden oder vor der Kompilierung festgelegt werden (需要确认: Der Standardport ist nicht explizit im Quellcode definiert; die Portnummer wird beim Serverstart angezeigt).
Installation und Start
Empfohlene Installationssequenz
bash1# 1. Repository klonen 2git clone https://github.com/EZLippi/Tinyhttpd.git 3cd Tinyhttpd 4 5# 2. Abhängigkeiten installieren (für CGI-Tests) 6sudo apt-get install perl libcgi-pm-perl 7 8# 3. Linux-Anpassungen vornehmen (manuell in httpd.c) 9# - Zeile 25: #include <pthread.h> auskommentieren 10# - pthread_create-Aufrufe auskommentieren 11# - accept_request() Aufruf einkommentieren 12 13# 4. Kompilieren 14make all 15 16# 5. Server starten 17./httpd
Kompilierungsoptionen
| Methode | Befehl | Beschreibung |
|---|---|---|
| Vollständig | make all | Kompiliert Server und Client |
| Nur Server | make httpd | Kompiliert nur den HTTP-Server |
| Nur Client | make client | Kompiliert nur den Testclient |
| Bereinigung | make clean | Entfernt generierte Binärdateien |
Laufzeitverifikation
Erfolgreicher Server-Start
Nach dem Start gibt der Server den verwendeten Port auf der Standardausgabe aus. Die README beschreibt, dass der Server bei der Initialisierung einen Port bindet - entweder den angegebenen oder einen dynamisch zugewiesenen (README.md:35-36).
Erwartete Ausgabe (需要确认: Das genaue Ausgabeformat ist im Quellcode nicht explizit dokumentiert):
httpd running on port <PORT>
Funktionsprüfung
- Statische Dateien: Aufruf von
http://localhost:<PORT>/sollte dieindex.htmlausliefern - CGI-Funktionalität: Aufruf von
http://localhost:<PORT>/color.cgisollte das CGI-Skript ausführen - Fehlerbehandlung: Aufruf einer nicht existierenden Datei sollte einen 404-Fehler zurückgeben
Test mit dem mitgelieferten Client
bash1# Client kompilieren und ausführen 2make client 3./client
Der Client verbindet sich mit 127.0.0.1:9734 und erwartet eine Antwort vom Server (simpleclient.c:18-19).
Hinweis: Der Client verwendet einen fest codierten Port 9734. Wenn der Server auf einem anderen Port läuft, schlägt die Verbindung fehl (需要确认: Eine Konfigurationsmöglichkeit für den Client-Port ist nicht im Quellcode vorhanden).
Häufige Probleme und Lösungen
Problem 1: Kompilierungsfehler unter Linux
Symptom: Fehlermeldungen bezüglich pthread.h oder -lsocket während der Kompilierung.
Ursache: Der Code wurde ursprünglich für Solaris entwickelt und verwendet pthreads sowie die Socket-Bibliothek.
Lösung: Die in der README dokumentierten Anpassungen müssen vollständig umgesetzt werden (README.md:5-14):
- Alle pthread-relevanten Zeilen auskommentieren
-lsocketaus dem Makefile entfernen- Den sequentiellen
accept_request()-Aufruf aktivieren
Problem 2: CGI-Skripte werden nicht ausgeführt
Symptom: CGI-Skripte werden als Text angezeigt statt ausgeführt zu werden.
Ursache: Fehlende Perl-Installation oder das Modul perl-cgi ist nicht installiert.
Lösung: Installation der erforderlichen Abhängigkeiten (README.md:1-3):
bash1sudo apt-get install perl libcgi-pm-perl
Zusätzlich muss sichergestellt werden, dass die CGI-Dateien ausführbare Berechtigungen haben:
bash1chmod +x htdocs/*.cgi
Problem 3: Port bereits belegt
Symptom: Server startet nicht mit der Meldung "bind: Address already in use".
Ursache: Der angeforderte Port wird bereits von einem anderen Prozess verwendet.
Lösung:
- Verwendung von Port 0 für dynamische Zuweisung (empfohlen)
- Oder: Identifizieren und Beenden des Prozesses, der den Port belegt
Die SO_REUSEADDR-Option ist bereits im Code implementiert (httpd.c:442-445), was schnelle Neustarts ermöglicht.
Problem 4: Client-Verbindungsfehler
Symptom: Der Testclient meldet "oops: client1" und bricht ab.
Ursache: Der Server läuft nicht auf Port 9734 oder ist nicht gestartet.
Lösung:
- Sicherstellen, dass der Server läuft
- Den vom Server verwendeten Port prüfen
- Bei Bedarf den Client-Quellcode anpassen (
simpleclient.c:19) oder den Server mit festem Port starten
Nächste Schritte
Nach erfolgreicher Installation und Verifikation können folgende Aspekte vertieft werden:
Quellcode-Analyse
Die README empfiehlt eine bestimmte Lesereihenfolge für das Verständnis des Codes: main → startup → accept_request → execute_cgi (README.md:31). Diese Reihenfolge folgt dem natürlichen Programmfluss und ermöglicht ein schrittuelles Verständnis der Server-Architektur.
Funktionsübersicht
Die README enthält eine detaillierte Beschreibung aller Hauptfunktionen (README.md:16-28):
accept_request: Verarbeitung eingehender HTTP-Anfragenexecute_cgi: Ausführung von CGI-Programmenserve_file: Auslieferung statischer Dateienstartup: Server-Initialisierung
Erweiterte Konfiguration
Für Produktionszwecke sind folgende Anpassungen empfehlenswert (需要确认: Diese Vorschläge basieren auf allgemeinen Best Practices und sind nicht explizit im Repository dokumentiert):
- Implementierung von Logging-Mechanismen
- Hinzufügen von Konfigurationsdatei-Unterstützung
- Integration von HTTPS-Unterstützung
- Implementierung von Request-Throttling
