Subsections

8.6 CGI-Erstellung für das httpd-Paket

8.6.1 Allgemeines zum Webserver

Der Webserver, der bei fli4l verwendet wird, ist der mini_httpd von ACME Labs. Die Quellen können unter http://www.acme.com/software/mini_httpd/ heruntergeladen werden. Allerdings wurden für fli4l ein paar Änderungen vorgenommen. Die Anpassungen befinden sich im src-Paket im Verzeichnis src/""fbr/""buildroot/""package/""mini_httpd.

8.6.2 Skriptnamen

Der Skriptname sollte möglichst vielsagend sein, damit er von anderen Skripten leichter zu unterscheiden ist und es keine Namensüberschneidungen bei verschiedenen OPTs gibt.

Damit die Skripte ausführbar gemacht werden und DOS-Zeilenumbrüche in Unix-Zeilenumbrüche umgewandelt werden, muss in der opt/<PAKET>.txt ein entsprechender Eintrag gemacht werden, siehe Tabelle .

8.6.3 Menü-Einträge

Um einen Eintrag im Menü vorzunehmen, muss eine Eintragung in der Datei /etc/httpd/menu vorgenommen werden. Dieser Mechanismus erlaubt es OPTs, auch im laufendem Betrieb Änderungen am Menü vorzunehmen. Dies sollte nur mit dem Skript httpd-menu.sh gemacht werden, da dieses darauf achtet, dass das Dateiformat dieser Datei immer konsistent ist. Um neue Menüpunkte einzufügen, wird es folgendermaßen aufgerufen:

    httpd-menu.sh add [-p <priority>] <link> <name> [section] [realm]

So wird ein Eintrag mit dem Namen <name> in den Abschnitt [section] eingetragen. Wenn [section] weggelassen wird, wird es standardmäßig in den Abschnitt "`OPT-Pakete"' eingetragen. <link> gibt das Ziel des neuen Links an. <priority> spezifiziert die Priorität eines Menüeintrags in seinem Abschnitt. Wird sie nicht angegeben, wird die Standardpriorität 500 benutzt. Die Priorität sollte eine dreistellige Nummer sein. Je kleiner die Priorität, desto weiter oben steht der Link in dem Abschnitt. Soll ein Eintrag möglichst weit nach unten, so ist z.B. die Priorität 900 zu wählen. Bei gleicher Priorität werden die Einträge nach dem Ziel des Links sortiert. Bei [realm] wird der Bereich angegeben, für den ein angemeldeter Benutzer mindestens die Berechtigung view haben muss, damit der Menüpunkt angezeigt wird. Wird [realm] nicht angegeben, wird der Menüpunkt immer angezeigt. Siehe hierzu auch den Abschnitt "`Benutzerrechte"'.

Beispiel:

    httpd-menu.sh add "neuedatei.cgi" "Hier klicken" "Tools" "tools"

Dieses Beispiel erzeugt im Abschnitt "`Tools"' einen Link mit dem Titel "`Hier klicken"' und dem Link-Ziel "`neuedatei.cgi"' und legt den Abschnitt, falls dieser nicht vorhanden ist, an.

Das Skript kann auch Einträge aus dem Menü wieder entfernen:

    httpd-menu.sh rem <link>

Mit diesem Aufruf wird der Eintrag mit dem Link <link> wieder entfernt.


Wichtig: Wenn mehrere Menüeinträge auf die gleiche Datei verweisen, werden alle diese Einträge aus dem Menü entfernt.

Da Abschnitte auch Prioritäten haben können, können diese auch manuell angelegt werden. Wird ein Abschnitt automatisch beim Hinzufügen eines Eintrages angelegt, erhält er automatisch die Priorität 500. Der Syntax zum Anlegen von Abschnitten lautet:

    httpd-menu.sh addsec <priority> <name>

Auch hier sollte <priority> nur dreistellige numerische Werte annehmen.

Um sinnvolle Prioritäten in Erfahrung zu bringen, lohnt es sich, auf einem laufenden fli4l in die Datei /etc/httpd/menu zu schauen, die Prioritäten stehen in der zweiten Spalte.

Der Vollständigkeit halber wird hier kurz auf das Dateiformat der Menüdatei eingegangen. Wem die Funktion von httpd-menu.sh reicht, der kann diesen Abschnitt überspringen. Die Datei /etc/httpd/menu hat den folgenden Aufbau: Sie ist in vier Spalten eingeteilt. In der ersten Spalte steht ein Kennbuchstabe, der Überschriften und Einträge unterscheidet. In der zweiten Spalte steht die Sortierungspriorität. Die dritte Spalte enthält bei Einträgen das Ziel des Links und bei Überschriften einen Bindestrich, da dieses Feld bei Überschriften keine Bedeutung hat. Im Rest der Zeile steht der Text, der nachher im Menü erscheint.

Überschriften benutzen den Kennbuchstaben "`t"', dann wird ein neuer Menüabschnitt begonnen. Normale Menüeinträge benutzen den Kennbuchstaben "`e"'. Ein Beispiel:

    t 300 - Mein tolles OPT
    e 200 meinopt.cgi Mach etwas Tolles
    e 500 meinopt.cgi?mehr=ja Mach mehr Tolles

Beim Bearbeiten dieser Datei muss man darauf achten, dass das httpd-menu.sh-Skript die Datei immer sortiert abspeichert. Die einzelnen Abschnitte sind sortiert und die Einträge pro Abschnitt sind in diesem Abschnitt sortiert. Der genaue Sortieralgorithmus kann aus httpd-menu.sh übernommen werden - besser wäre allerdings, dieses Skript um mögliche neue Funktionen zu erweitern, damit alle Menü-Bearbeitungen an zentraler Stelle passieren.

8.6.4 Aufbau eines CGI-Skriptes

8.6.4.1 Die Kopfzeilen

Alle Skripte des Webservers sind einfache Shell-Skripte (Interpreter wie z.B. Perl, PHP, etc. sind viel zu groß für fli4l). Sie sollten mit dem obligatorischen Skript-Header anfangen (Verweis auf den Interpreter, Name, Sinn des Skriptes, Autor, Lizenz).

8.6.4.2 Das Hilfsskript "'cgi-helper"'

Gleich nach den Kopfzeilen sollte dann schon das Hilfsskript cgi-helper mit folgendem Aufruf eingebunden werden:

    . /srv/www/include/cgi-helper

Wichtig ist ein Leerzeichen zwischen Punkt und Schrägstrich!

Dieses Skript stellt diverse Hilfsfunktionen bereit, die das Erstellen von CGIs für fli4l wesentlich vereinfachen sollen. Außerdem werden mit dem Einbinden des cgi-helper auch noch Standardaufgaben ausgeführt, wie beispielsweise das Parsen von Variablen, die mit Formularen oder über die URL übergebenen wurden, oder das Laden von Sprach- und CSS-Dateien.

Tabelle 8.4 gibt einen Überblick über die Funktionen des cgi-helper-Skriptes.


Table 8.4: Funktionen des cgi-helper-Skriptes
Name Funktion
check_rights Überprüfung der Benutzerrechte
http_header Ausgabe eines Standard-HTTP-Headers oder eines speziellen HTTP-Headers, beispielsweise zum Download von Dateien
show_html_header Ausgabe des kompletten Seitenheaders (inkl. HTTP-Header, Kopfzeile und Menü)
show_html_footer Ausgabe des Abschlusses der HTML-Seite
show_tab_header Ausgabe eines Inhalt-Fensters mit Reitern
show_tab_footer Ausgabe des Abschlusses des Inhaltsfensters
show_error Ausgabe einer Box für Fehlermeldungen (Hintergrundfarbe: rot)
show_warn Ausgabe einer Box für Warnmeldungen (Hintergrundfarbe: gelb)
show_info Ausgabe einer Box für Informationen oder Erfolgsmeldungen (Hintergrundfarbe: grün)

8.6.4.3 Der Inhalt eines CGI-Skriptes

Um ein einheitliches Design und vor allem die Kompatibilität mit zukünftigen fli4l-Versionen zu gewährleisten, ist es sehr zu empfehlen, die Funktionen des Hilfsskriptes cgi-helper zu benutzen, auch wenn man in einem CGI theoretisch alle Ausgaben selbst generieren kann.

Eine einfaches CGI-Skript könnte wie folgt aussehen:

    #!/bin/sh
    # --------------------
    # Header (c) Autor Datum
    # --------------------
    # get main helper functions
    . /srv/www/include/cgi-helper

    show_html_header "Mein erstes CGI"
    echo '   <h2>Willkommen</h2>'
    echo '   <h3>Dies ist ein Beispiel-CGI-Skript</h3>'
    show_html_footer

8.6.4.4 Die Funktion show_html_header

Die Funktion show_html_header erwartet eine Zeichenkette als Parameter. Diese Zeichenkette stellt den Titel der zu generierenden Seite dar. Die Funktion generiert automatisch das Menü und bindet ebenso automatisch zum Skript gehörende CSS- und Sprachdateien ein. Voraussetzung dafür ist, dass diese sich in den Verzeichnissen /srv/www/css bzw. /srv/www/lang befinden und denselben Namen (aber natürlich eine andere Endung) wie das Skript haben. Ein Beispiel:

    /srv/www/admin/OpenVPN.cgi
    /srv/www/css/OpenVPN.css
    /srv/www/lang/OpenVPN.de

Sowohl das Benutzen von Sprachdateien als auch von CSS-Dateien ist optional. Immer eingebunden werden css/main.css und lang/main.<lang>, wobei <lang> der gewählten Sprache entspricht.

Der Funktion show_html_header können aber neben dem Titel noch weitere Parameter übergeben werden. Ein Aufruf mit allen möglichen Parametern könnte so aussehen:

    show_html_header "Titel" "refresh=$time;url=$url;cssfile=$cssfile;showmenu=no"

Alle zusätzlichen Parameter müssen, wie im Beispiel gezeigt, mit Anführungszeichen umschlossen und durch ein Semikolon getrennt werden. Eine Überprüfung der Syntax erfolgt nicht! Es ist also notwendig, sehr genau auf die Parameterübergabe zu achten.

Hier eine kurze Übersicht über die Funktion der Parameter:

Sonstige Richtlinien zum Inhalt:

8.6.4.5 Die Funktion show_html_footer

Die Funktion show_html_footer schließt den Block im CGI-Skript ab, der durch die Funktion show_html_header eingeleitet wurde.

8.6.4.6 Die Funktion show_tab_header"'

Damit der Inhalt eurer mit Hilfe des CGIs erzeugten Webseite auch hübsch geordnet aussieht, könnt ihr die cgi-helper-Funktion show_tab_header nutzen. Sie erzeugt dann anklickbare Reiter ("`Tabs"' genannt), so dass ihr eure Seite in mehrere logisch voneinander getrennte Bereiche unterteilen könnt.

Der show_tab_header-Funktion werden Parameter immer in Paaren übergeben. Der erste Wert entspricht dem Titel eines Reiters, der zweite dem Link. Wird als Link die Zeichenkette "`no"' übergeben, wird lediglich der Titel ausgegeben und der Reiter ist nicht anklickbar (und blau).

Im folgenden Beispiel wird ein "`Fenster"' mit dem Titel "`Ein tolles Fenster"' erzeugt. Im Fenster steht "`foo bar"':

    show_tab_header "Ein tolles Fenster" "no"
    echo "foo"
    echo "bar"
    show_tab_footer

Im nächsten Beispiel werden zwei anklickbare Reiter generiert, die dem Skript die Variable action mit verschiedenen Werten übergibt.

    show_tab_header "1. Auswahltab" "$myname?action=machdies" \
                    "2. Auswahltab" "$myname?action=machjenes"
    echo "foo"
    echo "bar"
    show_tab_footer

Nun kann das Skript den Inhalt der Variablen FORM_action (siehe weiter unten zur Variablenauswertung) auswerten und je nachdem unterschiedliche Inhalte bereitstellen. Damit der angeklickte Reiter auch ausgewählt erscheint und nicht mehr angeklickt werden kann, müsste der Funktion statt dem Link wie schon erwähnt ein "`no"' übergeben werden. Das geht aber auch einfacher, wenn man sich an die Konvention in folgendem Beispiel hält:

    _opt_machdies="1. Auswahltab"
    _opt_machjenes="2. Auswahltab"
    show_tab_header "$_opt_machdies" "$myname?action=opt_machdies" \
                    "$_opt_machjenes" "$myname?action=opt_machjenes"
    case $FORM_action in
        opt_machdies) echo "foo" ;;
        opt_machjenes) echo "bar" ;;
    esac
    show_tab_footer

Wird also für den Titel eine Variable verwendet, deren Namen dem Inhalt der Variablen action mit führendem Unterstrich (_) entspricht, wird der entsprechende Reiter ausgewählt dargestellt.

8.6.4.7 Die Funktion show_tab_footer

Die Funktion show_tab_footer schließt den Block im CGI-Skript ab, der durch die Funktion show_tab_header eingeleitet wurde.

8.6.4.8 Mehrsprachfähigkeit

Das Hilfsskript cgi-helper enthält weiterhin Funktionen, um CGI-Skripte mehrsprachfähig zu machen. Dazu müssen "`nur"' für alle Textausgaben Variablen mit führenden Unterstrichen (_) verwendet und diese Variablen in den entsprechenden Sprachdateien definiert werden.

Beispiel:

lang/opt.de enthalte:

    _opt_machdies="Eine Ausgabe"

lang/opt.en enthalte:

    _opt_machdies="An Output"

admin/opt.cgi enthalte:

    ...
    echo $_opt_machdies
    ...

8.6.4.9 Formular-Auswertung

Um Formulare zu verarbeiten, muss man noch einige Dinge wissen. Egal ob die Formular-Methode GET oder POST verwendet wird, die Parameter finden sich nach dem Einbinden des cgi-helper-Skripts (welches wiederum das Hilfsprogramm proccgi aufruft) in den Variablen FORM_<Parameter> wieder. Wenn das Formularfeld also den Namen "`eingabe"' hatte, kann im CGI-Skript mit $FORM_eingabe darauf zugegriffen werden.

Weitere Informationen zum Programm proccgi finden sich unter http://www.fpx.de/fp/Software/ProcCGI.html.


8.6.4.10 Benutzerrechte: Die Funktion check_rights

Um zu prüfen, ob der Benutzer ausreichende Rechte zur Nutzung eines CGI-Skripts besitzt, muss am Anfang des CGI-Skripts die Funktion check_rights wie folgt aufgerufen werden:

    check_rights <Bereich> <Aktion>

Das CGI-Skript wird dann nur ausgeführt, wenn der aktuell angemeldete Benutzer

8.6.4.11 Die Funktion show_error

Diese Funktion gibt eine Fehlermeldung in einer roten Box aus. Sie erwartet zwei Parameter: einen Titel sowie eine Meldung. Beispiel:

    show_error "Error: No key" "No key was specified!"

8.6.4.12 Die Funktion show_warn

Diese Funktion gibt eine Warnmeldung in einer gelben Box aus. Sie erwartet zwei Parameter: einen Titel sowie eine Meldung. Beispiel:

    show_info "Warnung" "Derzeit besteht keine Verbindung!"

8.6.4.13 Die Funktion show_info

Diese Funktion gibt eine Informations- oder Erfolgsmeldung in einer grünen Box aus. Sie erwartet zwei Parameter: einen Titel sowie eine Meldung. Beispiel:

    show_info "Info" "Aktion wurde erfolgreich ausgeführt!"

8.6.4.14 Das Hilfsskript "'cgi-helper-ip4"'

Gleich nach den Hilfsskript "cgi-helper" kann dann das Hilfsskript cgi-helper-ip4 mit folgendem Aufruf eingebunden werden:

. /srv/www/include/cgi-helper-ip4

Wichtig ist ein Leerzeichen zwischen Punkt und Schrägstrich!

Dieses Skript stellt Hilfsfunktionen bereit, um Prüfungen von IPv4-Adressen vornehmen zu können.

8.6.4.15 Die Funktion ip4_isvalidaddr

Diese Funktion überprüft, ob eine gültige IPv4-Adresse übergeben wurde. Beispiel:

    if ip4_isvalidaddr ${FORM_inputip}
    then
        ...
    fi

8.6.4.16 Die Funktion ipv4_normalize

Diese Funktion entfernt aus der übergebenen IPv4-Adresse führende Nullen. Beispiel:

    ip4_normalize ${FORM_inputip}
    IP=$res
    if [ -n "$IP" ]
    then
        ...
    fi

8.6.4.17 Die Funktion ipv4_isindhcprange

Diese Funktion prüft, ob die übergebene IPv4-Adresse sich im Bereich der übergebenen Start- und Zieladresse befindet. Beispiel:

    if ip4_isindhcprange $FORM_inputip $ip_start $ip_end
    then
        ...
    fi

8.6.5 Sonstiges

Dies und das (ja, das ist auch noch wichtig!):

8.6.6 Fehlersuche

Um die Fehlersuche innerhalb eines CGI-Skripts zu erleichtern, kann man vor der Einbindung des cgi-helper-Skripts den Debugging-Modus aktivieren. Dazu muss die Variable set_debug auf den Wert "`yes"' gesetzt werden. Dies führt zur Erstellung der Datei debug.log, die über die URL http://<fli4l-Host>/admin/debug.log heruntergeladen werden kann. Diese enthält alle Aufrufe des CGIs. Die set_debug-Variable ist nicht global, muss also in jedem Problem-CGI erneut gesetzt werden. Beispiel:

    set_debug="yes"
    . /srv/www/include/cgi-helper

Alternativ kann auch die jeweilige CGI-URL um den Parameter debug=yes ergänzt werden, etwa http://<fli4l-Host>/admin/meinopt.cgi?debug=yes.

Des Weiteren eignet sich cURL8.9 hervorragend zur Fehlersuche, insbesondere wenn die HTTP-Kopfzeilen nicht korrekt zusammengesetzt werden oder der Browser nur weiße Seiten anzeigt. Auch ist das Cachingverhalten moderner Webbrowser bei der Fehlersuche hinderlich.

Beispiel: Mit dem folgenden Aufruf wird der HTTP-Header ("`dump"', -D) sowie die normale Ausgabe des CGIs admin/mein.cgi ausgegeben. Es soll der Benutzername ("`user"', -u) "`admin"' verwendet werden.

    curl -D - http://fli4l/admin/mein.cgi -u admin



Footnotes

... (SelfHTML8.8
siehe http://de.selfhtml.org/
... cURL8.9
siehe http://de.wikipedia.org/wiki/CURL
© 2001-2019 Das fli4l-Team - April 28, 2019