Blue Ribbon Campaign for Free SpeechAnmerkungen zu "CGI leicht gemacht!"


  1. CGI-Beispiel-Programme
  2. CGI Mailer Skript
  3. Sicherheit und CGI-Skripts
  4. Das Skript auf den Server bekommen
  5. Ein vorhandenes File als Antwort senden
  6. Weitere nützliche Environment-Variablen
  7. Ein Bild (oder andere Binärdaten) als Antwort ausgeben
  8. Der Unterschied zwischen GET und POST


CGI-Beispiel-Programme

Wie gewünscht findest Du hier ein paar "Hello World" CGI-Programme um den Anfang leichter zu machen. Die erste Version zeigt nur CGI-Ausgaben, die längere Version gibt den an sie übermittelten Text als HTML einfach wieder aus. Es gibt jeweils eine C und eine Perl-Version.

Zum Seitenanfang


CGI Mailer Skript

Eines der häufigsten Anwendungsfelder für CGI-Skripts ist es, Formulardaten an eine eMail-Adresse zu versenden. Hier findest Du ein einfaches Skript, daß genau das tut - natürlich in Perl: mailer.pl

Zwei Dinge mußt Du vor der Benutzung aber noch tun, sonst wärs zu einfach:

Die Übermittlung von Form-Daten ohne CGI

Es gibt noch einen Billig-Weg, Form-Daten per eMail zu verschicken, der nur auf HTML basiert. Im <FORM> Tag mußt Du ACTION auf "mailto:" setzen, und das ENCTYPE -Attribut muß "text/plain" sein. Die meisten Browser können damit umgehen und senden die Form-Daten an die angegebene Adresse. Zum Beispiel:

<FORM ACTION="mailto:me@myhost.de" ENCTYPE="text/plain">
 

Da gibts aber auch Nachteile: Man hat keine Kontrolle über das Format des versendeten Textes und außerdem bekommt der User kein Feedback. Außerdem unterstützen halt nicht alle Browser diese Variante des <FORM>-Tags.

Zum Seitenanfang


Sicherheit und CGI-Skripts

Man muß sich einfach mal klar machen, daß ein CGI-Skript ein Programm ist, daß jeder Mensch dieser Welt auf Deinem Rechner laufen lassen kann. Gerade bei Kommandozeilenorientierten Betriebssystemen (Unix) sollte man ziemlich aufpassen, in seinem Skript keine großen Lücken zu lassen.

Wichtig: Traue keiner User-Eingabe. Zum Beispiel sollte man nie vom User übermittelte Daten direkt als Shell-Command ausführen, ohne die Daten zu prüfen. Hacker riechen solche Löcher! Stell Dir mal vor Du hättest ein CGI-Skript mit dem der User auf Deinem Rechner "fingern" kann. Ein Perl-Skript könnte so aussehen:

system "finger $username" ;
 

Wenn der geneigte User nun "james; rm -rf /" als Usernamen eingibt, wird daraus

system "finger james; rm -rf /" ;
 

was so viele Dateien wie Möglich löscht. Das ist doch wohl nicht, was Du erwartet hast!? Den Usernamen sollte man in diesem Fall zumindest mit folgendem überprüfen:

$username!~ /[^\w.-]/   || die "Boa! Netter Versuch..." ;
 

Es ist für einen Hacker ja ganz einfach, irgendwelche FORM-Variablen an Dein Skript zu schicken - mit irgendwelchen Werten (auch Steuerzeichen). Dein Skript sollte auf solche Daten nicht reagieren.

Zum Seitenanfang


Das Skript auf den Server bekommen

Jeder Webserver ist anders konfiguriert. Einige erlauben es, CGI-Skripts ins gleiche Verzeichnis wie die Websites zu packen, die Dateinamen müssen dann mit ".cgi" aufhören. Andere wollen die CGI-Skripts in einem speziellen Verzeichnis haben, meist "cgi-bin". Dein Webmaster sollte Dir da weiterhelfen können.

Du mußt Deinem CGI-Skript noch die richtigen Unix-Permissions geben, um es als ausführbar zu kennzeichnen. Unter Unix läuft der Webserver (wie jeder Prozess) unter einem Usernamen. Dein CGI-Skript muß erstens von diesem User ausfürbar und zweitens auch noch lesbar sein. Unter Unix setzt man diese Permissions mit "chmod 750 *.cgi" (oder "chmod 755 *.cgi" - frag den Webmaster)

Wenn das Skript nicht läuft:

Zum Seitenanfang


Ein vorhandenes HTML-File als Antwort senden

Wenn die HTML-Antwort Deines Skripts immer die gleiche ist oder Du mit einem von mehreren vorhandenen Files antworten möchtest, könntest Du das "Location"-Antwortprinzip hilfreich finden. Damit kann man den Browser "auf eine andere URL umleiten".

Um ein Beispiel zu nennen, stell Dir vor, Dein Skript gibt

Location: response.html

aus - gefolgt von einer Leerzeile. Der Browser des Users wird daraufhin response.html laden, als sei es die Antwort Deines CGI-Skripts. Hier kann man natürlich relative und absolut Adressen angeben.

In diesem Fall erzeugt man keinen "Content-type:" -Header!

Zum Seitenanfang


Weitere nützliche Environment-Variablen

CGI-Skripts können auf etwa 20 Environment-Variablen zugreifen - solche wie QUERY_STRING und CONTENT-LENGTH. Hier ist die komplette Liste von NCSA.

Ein paar ausgesuchte sind besonders interessant:

 
REQUEST_METHOD
Beinhaltet die Methode, mit der das Skript aufgerufen wurde. Normalerweise "GET" oder "POST".
 

HTTP_REFERER

Die URL der HTML-Form, die übertragen wurde. Sie ist nicht immer gesetzt, also verlass Dich nicht drauf. Die Privatsphäre des Users sollte man damit (und generell) auch nicht erobern.
 

PATH_INFO

Genauere Pfad-Information. So ist es möglich, dem Skript einen Pfad zu übergeben. Der muß dann hinter der URL des CGI-Skripts stehen:
http://www.myhost.com/mypath/myscript.cgi/path/info/here

würde PATH_INFO auf "/path/info/here" setzen.

 

SERVER_NAME

Hostname und IP Deines Webservers.
 

SERVER_PORT

Der benutzte Port des Webservers (zumindest für diesen Request)
 

SCRIPT_NAME

Die lokale URL des ausgeführten Skriptes. Im CGI-Standard ist unklar, ob ein führender Slash mit übergeben werden soll. Mit der folgenden Perl-Zeile hat man nie einen führenden Slash:
$ENV{'SCRIPT_NAME'}=~ s#^/## ;

Die komplette URL des ausgeführten Skriptes wäre in Perl also

"http://$ENV{'SERVER_NAME'}:$ENV{'SERVER_PORT'}/$ENV{'SCRIPT_NAME'}"
 

Die komplette URL mit der das Skript aufgerufen worden ist trüge hinten noch PATH-INFO und QUERY_STRING angehängt.

Nochmal: Bei NCSA's complete list findest Du sie alle.

Zum Seitenanfang


Ein Bild (oder andere Binärdaten) als Antwort ausgeben

Die meisten CGI-Skripts geben HTML-Daten zurück, man kann aber eigentlich zurückgeben, was man möchte. Man sollte nur den richtigen MIME-Type in der "Content-type:"-Zeile stehen haben - natürlich wieder von einer Leerzeile gefolgt. Anschließend können dir rohen Binärdaten folgen. Bei einer HTML-Antwort ist das HTML-Text. Bei Bildern, Audio oder Video sind es Binärdaten. Ein GIF zum Beispiel gibt man so zurück:

Content-type: image/gif

GIF89a&%--- binary contents of GIF file here ---$(*&%(*@#......

Dein HTML-File kann ein solches Skript-generiertes Bild zum Beispiel wie folgt aufrufen:

<IMG SRC="gifmaker.cgi?param1=wert1&param2=wert2">

Eins meiner Lieblingsbeispiele hierfür ist der interaktive Grafikrenderer, der 3D-Icons mit den Farben, Formen, Texturen, Lichtern usw. erzeugt, die ich definiere. Die entstandenen Icons kann man dann auf seiner Seite als Aufzählungspunkt oder HR benutzen. Anm.: Die Seite ist z.Zt. Homeless - es gibt aber diesen Mirror in Finnland.

MIME-Types

MIME-Types sind standardisierte, Casesensitive Strings die einen Dateityp identifizieren. Sie beginnen mit dem generellen Typ der Datei (text, image, audio), gefolgt von einem Slash, um mit dem spezifischen Dateityp (html, gif, jpeg) aufzuhören. HTML-Files sind zum Beispiel als text/html identifiziert, GIFs oder JPEGs heißen jeweils image/gif bzw. image/jpeg.

Zum Seitenanfang


Der Unterschied zwischen GET und POST

GET und POST sind zwei zwei unterschiedliche Methoden, die im HTTP festgelegt sind. Sie tun recht verschiedene Dinge, sind aber beide geeignet, um Form-Daten zurück an den Server zu senden.

Normalerweise benutzt man GET um eine Datei oder so anzufordern, vielleicht mit ein paar Parametern versehen, die diese genauer beschreiben. Die Daten werden dabei komplett in der URL übertragen:

Dabei dürfen nicht zu viele Daten übertragen werden müssen - die Maximallänge der URL variiert von Browser zu Browser.

GET ist idempotent.. Das bedeutet, daß die Rahmenbedingungen bei mehreren GET-Anforderungen für das Skript genau gleich sind. Kurz gesagt: Browser und Proxies können Antwortfiles cachen. So schaffen es bei zwei identischen Form-Übermittlungen evtl. nicht beide bis zu Deinem Server. Wenn Du also jeden Zugriff protokollieren willst, solltest Du POST verwenden.

Normalerweise wird POST dafür verwendet, dem Server einen großen Haufen Daten zum verarbeiten zu übermitteln. (Der Name POST kommt ursprünglich von der Idee, einen Beitrag in eine Newsgroup zu senden) Wenn eine HTML-Form per POST übermittelt wird, werden die Daten direkt an die POST-Anforderung angehängt - im eigenen Objekt. Das ist nicht so schnell und einfach zu bedienen wie GET, aber es ist vielseitiger. Mit POST kann der User zum Beispiel ganze Dateien an den Server uploaden: Die Menge der übertragenen Daten ist im Gegensatz zu GET nicht begrenzt.

All das geschieht hinter den Kulissen. Für den CGI-Programmierer funktionieren GET und POST fast gleich und sind gleich einfach zu benutzen. Der Vorteil von POST ist, daß man beliebig viele Daten übertragen kann. Der Vorteil von GET ist, daß alle Daten in eine URL gebastelt sind - man kann auf sie also verweisen oder sie Bookmarken. (Mit dem AutoPOST-Utility geht das auch per POST)

 

Zum Seitenanfang

 


© 1997 James Marshall, German translation by Friedemann Wachsmuth (comments encouraged)