AnwendungenPerl

Anwendungen gibt es fast unendlich viele ...

Server, CGI und Perl

Perl hat mit dem Internet einen mächtigen Aufschwung erlebt ... es ist doch erstaunlich wie anpassungsfähig Perl ist ...

SeitenanfangSeitenendeWo findet man Perl im Internet

Viele werden sich jetzt fragen, wo finde ich Perl im Internet. Naja für den Anwender ist das nicht dirket der Fall. Aber wenn man etwas genauer hinschaut kann man oft statt den Links Adressen wie http://btu0xc.ub.uni-bayreuth.de/cgi-webOPAC/bridgeMain.pl?maskID=001&tagNO=&... entdecken. Diese stammen z. B. von einem Formular, das ein Perlprogramm auf dem Server aufruft. Das heißt, dass man von einem Browser aus ein existierendes Perlskript auf einem Server ausführen kann.

SeitenanfangSeitenendeCGI auf einem Server

Ich möchte jetzt nicht auf Internetarchitektur etc. eingehen, doch etwas Grundwissen brauchen wir jetzt schon. Also ein WWW-Server ist ein Computer mit folgenden Eigenschaften:

Damit hat man schon alles, um lokal einen WWW-Server zu betreiben. Genaueres findet man unter http://selfhtml.teamone.de/cgiperl/intro/webserverpc.htm.

Ein WWW-Server ist ein Progamm (Achtung: Die Bezeichnung WWW-Server wird für den Computer und für das Programm gebraucht!), das im Hintergrund arbeitet. Man sieht also recht wenig davon, wenn das WWW-Server-Programm gestartet wurde - eventuell ein kleines Icon.

Für uns ist nun folgendes wichtig. Es gibt ein Verzeichnis (z. B. C:\Programs\Sambar\docs) auf dem Computer, das die Internetseiten für das WWW enthält. Man findet dort HTML-Seiten, Bilder, etc., eben alles was für das WWW sichtbar sein soll. Außerdem gibt es noch eine CGI-Schnittstelle; das ist ein Verzeichnis (z. B. C:\Programs\Sambar\cgi-bin), in dem ausführbare Programme enthalten sind - wie z. B. ein Perlprogramm (vgl. Suchen).

Eine HTML-Seite fordert man von einem Server z. B. dadurch an, dass man eine Web-Adresse im Browser eingibt. Diese Anforderung wird an den zuständigen Server geschickt; dieser gibt dann die angeforderte Seite zurück. Ist die Anforderung ohne irgendwelchen speziellen Pfadangaben, so sucht der Server in dem Dokumentenverzeichnis (hier C:\Programs\Sambar\docs). Aufgrund der Endung der angeforderten Datei, weiß der Server, was er mit der Datei anfangen muss. Wird eine HTML-Seite angegeben - mit der Endung htm bzw. html, dann sendet der Server die HTML-Seite zurück an den Browser. Genauer gesagt: Es wird der ASCII-Code der HTML-Seite mit einer Vorabinformation über die Rückgabe an die IP-Adresse des Anforderers geschickt.

Besteht nun die Anforderung aus einem CGI-Aufruf (diesen erkennt man daran, dass der Link der Anforderung mit /cgi-bin/ beginnt), so sucht der Server im CGI-Verzeichnis (hier: C:\Programs\Sambar\cgi-bin). Der Server gibt jetzt nicht den ASCII-Code des Programms zurück, sondern er macht einen Programmaufruf und wartet, dass das Programm ASCII-Code zurückliefert, den der Server weiter an den Anforderer schicken kann.

Damit ist auf Server-Seite alles getan, um Programme auf dem Server ablaufen zu lassen.

SeitenanfangSeitenendeHTML-Formulare und Perl auf dem Server

HTML bietet die Möglichkeit, Formulare zu erstellen. In einem Formular kann der Browserbediener Eingabefelder ausfüllen, mehrzeilgen Text in ein Textfeld eingeben, Radiobuttons ein- und ausschalten, Buttons drücken, aus Listen auswählen, etc. (vgl. http://www.teamone.de/selfhtml/tch.htm). Wenn man mit den Eintragungen fertig ist, kann man das Formular absenden. Als Ersteller der HTML-Seite muss man noch angeben, was mit den Daten gemacht wird. Dazu gibt es zwei Möglichkeiten: Entweder die Daten als Email zu verschicken - an dem sind wir aber jetzt nicht interessiert, oder diese an ein Programm am Server weiterzuleiten - und das hört sich doch schon ganz gut an. Ein Beispiel aus dem Suchen-Formular (vgl. Suchen). Wichtig für uns sind die dunkelblauen Zeilen; der Rest ist nur Formatierungssache.:

<p>
 <form action="/cgi-bin/perl/search.pl" method="get">
  <table table align="center" cellspacing=5 cellpadding=5 border=0>
  <tr>
   <td valign="bottom">
    <table align="center" cellspacing=0 cellpadding=0 border=0>
     <tr>
      <td align="center">regulärer Ausdruck </td>
      <td align="center">Optionen </td>
      <td></td>
     </tr>
     <tr>
      <td align="center"><b><font size="6">/</font></b><input type="Text" name="regExp" value="" size="30" maxlength="50"></td>
      <td align="center"><b><font size="6">/</font></b>
       <select name="optionen" size="1">
        <option value="">keine Option
        <option value="i">Option i
        <option value="m">Option m
        <option value="s">Option s
        <option value="im">Optionen im
        <option value="is">Optionen is
        <option value="ms">Optionen ms
        <option value="ims">Optionen ims
       </select>

      </td>
     </tr>
     </table>
   </td>
   <td valign="bottom"><input type="Submit" value="suchen"></td>
  </tr>
  </table>
 </form>
</p>

Ein Textfeld wird mit <input type="Text" name="NAME" size="BREITE des Kaestchens" maxlength="maximale ZEICHENANZAHL"> angeben. Darin kann man Text eintragen, der dann losgeschickt wird.

Will man nur eine Auswahl von Einträgen zulassen, so kann man dies mit den Tags <select> und </select> tun. Auch hier wird dem <select> der Name übergeben. Die möglichen Optionen gibt man mit <option value="ms"> an. Danach steht der zu erscheinende Text im Auswahlfenster (z. B. keine Option). Die ausgewählte Option wird dann ebenfalls mitgesandt.

Los- bzw. abgeschickt wird das Formular mit einen Button. Dieser wird ebenfalls mit dem <input>-Tag angegebenen; jedoch ist der Typ auf submit gesetzt. value-gibt an, was auf dem Button stehen soll. Betätigt man nun den Button, dann wird das Formular abgeschickt. Der Browser gibt dann eine Anforderung an den Server ab, die lautet (im Textfeld regExp ist haus eingetragen worden und in der Auswahlliste optionen ist die Option is ausgewählt worden.):

/cgi-bin/perl/search.pl?regExp=haus&optionen=is

Was passiert nun auf dem Server? Ganz einfach - hatten wir ja schon! Also es kommt eine Anforderung. Diese ist ein CGI-Programm; hier ein Perlprogramm. Also obige Anforderung könnte man auch so ausdrücken:

"Hallo Server - starte mal in deinem CGI-Unterverzeichnis /cgi-bin/perl/ das Perlprogramm search.pl. Außerdem habe ich da noch ein paar Übergabeparameter: regExp=haus und optionen=is. Ich warte auf deine Antwort!"

Der Server führt dann das Perlprogramm mit den angegebenen Optionen aus und wartet, bis das Perlprogramm eine Ausgabe schickt. Diese wird weiter an die IP-Adresse des Anforderung geschickt.

SeitenanfangSeitenendeAbfragen der übergebenen Optionen mit QUERY_STRING

Jetzt begeben wir uns ins Perlprogramm. Auf Serverseite ist jetzt wirklich alles erledigt - der wartet ja nur noch auf eine Ausgabe.

Als erstes müssen wir die Übergabeparameter abfragen. Dazu gibt es unter Perl eine spezielle Liste, nämlich %ENV. In dieser stehen Umgebungsvariablen. Eine davon ist die Variable QUERY_STRING, in der die Übergabeparameter getrennt durch ein &-Zeichen gespeichert sind. (Werden die Formulardaten mit der Methode post verschickt, so werden diese nicht über QUERY_STRING abgefragt, sondern über CONTENT_LENGTH.) Das Auslesen der Übergabeparamter könnte dann so laufen:

# $ENV{QUERY_STRING} enthaelt 'regExp=haus&optionen=is'

my @uebergabeparameter=split(/&/,$ENV{QUERY_STRING});
# @uebergabeparameter enthaelt jetzt:
# [0] 'regExp=haus'
# [1] 'optionen=is'


my %environment=();
# jetzt werden die Eintraege getrennt
# und in der Liste %environment gespeichert
foreach (@uebergabeparameter) {
  $_=~/(.*)=(.*)/s;
  $environment{$1}=$2;
}

# Die Liste %environment enthaelt jetzt:
# regExp => haus
# optionen => is

Und das geht auch in einer Zeile:

my %environment=split(/[&=]/,$ENV{QUERY_STRING});

SeitenanfangSeitenendeAbfragen der übergebenen Optionen mit CONTENT_LENGTH

Werden Formulardaten mit der Methode post verschickt, dann werden diese Daten mit Hilfe einer anderen Umgebungsvariable eingelesen: CONTENT_LENGTH. Der Unterschied zwischen post und get liegt in der Weiterbehandlung der übergebenen Daten: Mit der Methode get werden die Daten an die Server-Software weitergegeben und in die Umgebungsvaraible QUERY_STRING geschrieben. Benutzt man die Methode post werden die Daten (in der gleichen Formatierung wie oben: & und = ) nicht an die Server-Software gesendet, sondern an die Standardeingabe, die man in diesem Fall mit Hilfe der Umgebungsvariable CONTENT_LENGTH (enthält die Länge der Daten in der Standardeingabe) abfrägt: Die übergebenen Daten liegen zwar vor, besitzen aber kein "Datenendekennzeichen". Deshalb muss man zuerst die Länge der Daten (CONTENT_LENGTH) abfragen und dann genauso viel einlesen. Um eine betimmte Anzahl von Zeichen von der Standardeingabe zu lesen, gibt es die Funktion read(FILEHANDLE,$variable,Laenge). Als erster Parameter für die Funktion read wird ein Filehandle benötigt - STDIN - geht auch. Der zweite Parameter ist eine Variable, in die die Daten geschrieben werden. Der letzte Paramter gibt an, wieviele Zeichen vom Filehandle gelesen werden sollen.

my $post_daten="";
read(STDIN,$post_daten,$ENV{CONTENT_LENGTH});
# Achtung $post_daten wird ueberschreiben

my %environment=split(/[&=]/,$post_daten);

SeitenanfangSeitenendeRückgabe an den Server

Gut nachdem wir jetzt wissen, wie man Optionen einliest, müssen wir nur noch herausfinden, wie man eine Rückgabe an den Server macht. (Was dazwischen abgeht, ist dem Programmierer überlassen).

Die Rückgabe an den Server geht ganz einfach. Man lässt das Perlprogramm einfach mit print auf die Standardausgabe schreiben. Dazu ist aber noch zu beachten, dass man hier schon die Vorabinformation (s. o.) mit ausgibt! Will man also eine HTML-Seite zurückgeben, sieht die Vorabinformation so aus Content-Type: text/html; gefolgt von einer Leerzeile. Die erste Ausgabe im Perlprogramm, die man also an den Server geben muss - vorausgesetzt, man gibt eine HTML-Seite zurück - lautet:

print "Content-Type: text/html;\n\n";
# Achtung jetzt kommt eine HTML-Seite

Anschließend kann ganz normal eine HTML-Seite an den Server übergeben werden.

Tipp: Ich gehe hier meistens folgendermaßen vor:

SeitenanfangSeitenendeAlle CGI-Umgebungsvariablen anzeigen lassen

Der Hash %ENV enthält alle CGI-Umgebungsvariablen (s. o.). Um diese anzeigen zu lassen, reichen folgende Befehle:

# Rueckgabe ist HTML-Code:

my $html="<table width=\"90%" align=\"center\"><tr>\n".
  "  <td><b>Umgebungsvariable</b><\/td>\n".
  "  <td><b>Wert</b><\/td>\n".
  "</tr>\n";
foreach(sort(keys(%ENV))) {
  $html.="<tr>\n".
  "  <td>".$_."<\/td>\n".
  "  <td>".$ENV{$_}."<\/td>\n".
  "</tr>\n";
}
$html.="</tr></table>";

Dies ergibt dann folgende HTML-Tabelle (XXX bedeutet aus Sicherheitsgründen von mir herausgenommen; einige Einträge habe ich sogar gelöscht):

Umgebungsvariable Wert
COMPUTERNAME BTXXX2
COMSPEC XXX
CONTENT_LENGTH 0
DOCUMENT_NAME XXX
DOCUMENT_ROOT XXX
DOCUMENT_URI XXX
GATEWAY_INTERFACE CGI/3.2
HTTP_ACCEPT_CHARSET iso-8859-1,*,utf-8
HTTP_ACCEPT_ENCODING gzip
HTTP_ACCEPT_LANGUAGE de,en
HTTP_HOST btXXX2.XXX.uni-bayreuth.de
HTTP_USER_AGENT Mozilla/XXX [en] (XXX 5.0; U)
PATH XXX
PATHEXT XXX
QUERY_STRING
RCEUSERNAME
REMOTE_ADDR 132.180.XXX.XXX
REMOTE_HOST btXXX2
REMOTE_USER
REQUEST_METHOD GET
SCRIPT_FILENAME XXX
SCRIPT_NAME XXX
SCRIPT_URI
SERVER_NAME btXXX2
SERVER_PORT 80
SERVER_PROTOCOL HTTP/2.0
SERVER_SOFTWARE XXX
TEMP XXX
TMP XXX

Seitenanfang FehlermeldungHilfe zur Fehlermeldung © 2001-2003 Email an den AutorPerl, Lehrstuhl Mathe II, Uni Bayreuth