Wer ein wenig mehr über die Kommunikation zwischen Webbrowser und HTTP-Server erfahren möchte, der baut sich mit einfachen Mitteln einen eigenen Webserver und schaut diesem genau über die Schulter.
Einen Webserver selbst zu programmieren, mag erst einmal als ein ebenso schweres wie überflüssiges Unterfangen erscheinen. Tatsächlich gibt es unter Linux zahlreiche frei verfügbare Webserver, von bekannten Allroundern wie Apache oder Nginx bis hin zu leichtgewichtigen Alternativen wie Cherokee oder Lighttpd (“Lighty”).
Allerdings erfordert nicht jede Situation einen ausgefeilten Webserver. Will man einfach nur lokal im eigenen Netzwerk ein paar HTML-Seiten teilen oder die Möglichkeit schaffen, Dateien hochzuladen, dann genügen dazu Linux-Bordmittel. Als passendes Rahmenkonstrukt eignet sich ein schlichtes Shell-Skript, das auf jedem System vorhandene Tools aus dem GNU-Fundus steuert. Die Netzwerkkommunikation übernimmt dabei das oft als Schweizer Taschenmesser für TCP/IP apostrophierte Netcat [1].
Bei so einem Projekt ist es am besten, an der Wurzel zu beginnen. Da ein Webserver eben ein Server ist, muss er ständig an einem bestimmten Port mithören und bei Anfragen passende Antworten geben. In der Regel lauschen Webserver bei normalen Anfragen am Port 80, wobei dieser Port im Allgemeinen nur HTTP-Anfragen ohne Verschlüsselung entgegennimmt. Der Webserver, den wir im Folgenden erstellen, wird auf den Ports 8080 und 8081 mithören und nur unverschlüsselt kommunizieren. Falls Sie eine Firewall nutzen und den Server im lokalen Netzwerk testen wollen, sollten Sie daran denken, diese beiden Ports für den Webserver freizuschalten.
Eigenbau
Ein Webserver braucht einen Root-Ordner, aus dem er die auszugebenden HTML-Dateien lädt. Zudem benötigt er noch ein Verzeichnis, in dem er hochgeladene Dateien ablegen kann. Die entsprechende Konfiguration definieren Sie zunächst über eine Reihe einfacher Variablen zu Beginn des Server-Skripts (Listing 1). Darüber hinaus müssen Sie die Verzeichnisse und auch die FIFO-Datei entweder manuell oder mithilfe des Test-Builtins der Bash erstellen. Wie das gelingt, demonstriert die fertige Lösung server6.sh, die Sie im Download-Bereich zu diesem Artikel finden.
Listing 1
Konfiguration
HTTP_HOME=http_home
HTTP_UPLOAD=${HTTP_HOME}/upload
CACHE_DATEI=${HTTP_UPLOAD}/dateizumbearbeiten
FIFO_GET=fifo_get
HTTP_GET_PORT=8080
HTTP_POST_PORT=8081
MEINE_IP=$(ip addr show wlan0 | grep -Eo "([0-9]{1,3}\.){3}[0-9]+" | sed 1q)
In der letzten Zeile von Listing 1 sehen Sie dann noch, dass auch die eigene IP-Adresse wichtig ist. Als Netzwerkgerät verwendet der RasPi die WLAN-Schnittstelle wlan0 oder das kabelgebundene Interface eth0. Wenn ein Webbrowser eine Datei über ein Webformular abschicken will, braucht er eine Zieladresse. GET-Anfragen sind die einfachere Variante. Wenn ein Browser eine solche Anfrage stellt, dann erwartet er als Antwort einfach nur den Inhalt einer Webseite, die er dann im Browser-Fenster darstellt.
Passende Dateien für das Testen des Webservers lassen sich skriptgesteuert erstellen. Die Funktion aus Listing 2 durchläuft dazu sieben Mal eine For-Schleife. Darin verwendet die Routine ein Here-Dokument (dritte Zeile), um HTML-Code fast 1:1 eingeben zu können. In solchen Heredocs kann man Bezug auf die in der For-Anweisung gesetzte Variable nehmen, die dann einfach nur die laufende Nummer enthält.
Listing 2
Beispieldateien
function create_files () {
for x in {1..7}; do
cat <<-FILE > ${HTTP_HOME}/datei${x}.html
<html><head><meta charset="utf-8">
<title>Seite ${x}</title>
</head><body>
<p> $( date ) </p>
<p> Seite ${x} </p>
</body></html>
FILE
done
}
Auf diesem Weg erzeugen Sie mit wenigen Zeilen Code so viele HTML-Dateien, wie Sie brauchen. Optional integrieren Sie weitere dynamische Inhalte, die Sie per Skript innerhalb des Here-Dokuments erzeugen. Auch die HTML-Datei, die das Upload-Formular enthält, wird auf diesem Weg in einer anderen Funktion erzeugt.
Am besten testen Sie das Erstellen der HTML-Dateien gleich einmal. Nach einem erfolgreichen Test haben Sie den ersten Meilenstein zur Entwicklung eines Webservers geschafft und können an die Entwicklung weiterer Komponenten gehen. Das Skript im Download-Bereich enthält auch noch eine Funktion, die alle im Root-Ordner enthaltenen HTML-Dateien mit CSS-Code [2] im Header ausschmückt.
GET-Anfragen
Stellt ein Webbrowser eine GET-Anfrage, will er einfach nur Daten zurückbekommen. Wie das aussieht, lässt sich stark vereinfacht austesten: Um etwa zu sehen, was ein Browser macht, wenn man sich nicht an das HTTP-Protokoll hält, führen Sie auf der Kommandozeile echo "hallo Firefox" | netcat -l 8080 aus. Dann geben Sie in der Adresszeile des Webbrowsers die URL localhost:8080 ein. Daraufhin sehen Sie, dass Firefox wartet, wartet und weiter wartet – es fehlt offenbar etwas.
Nichtsdestotrotz können Sie aber im Terminalfenster prüfen, wie die Anfrage von Firefox im Klartext aussieht, da der Browser sie bereits an Netcat geschickt hat. Er wartet nun darauf, einen Header und auch HTML als Antwort zu erhalten. Netcat liefert jedoch nichts dergleichen. Mit [Strg]+[C] kappen Sie die Verbindung zu Firefox. Im Browser-Fenster sollte dann der Text aus dem Echo-Kommando erscheinen (Abbildung 1).







