![]() |
Grundlagen CGI-Programmierung mit Perlvon Prof. Jürgen Plate |
CGI ist, wie gesagt, keine Sprache. Es ist vielmehr ein einfaches Protokoll, das der Kommunikation zwischen HTML-Formularen und einem Programm dient. Ein CGI-Script kann in jeder Sprache geschrieben sein. Diese Kurzanleitung konzentriert sich daher auch auf die Verarbeitung von HTML-Forms. Einige Details werden nicht behandelt, dafür kommt man um so schneller zum Ziel und deckt 90% der üblichen Anwendungen ab.
Ein CGI-Script führt die folgenden typischen Schritte aus:
<A HREF="http://shop.server.de/cgi-bin/shopper.pl?prodid=23481227">Bestellen</A>Genauso häufig sind Daten, die durch die Eingabe in ein Formular erzeugt werden. Wenn der Client seine Daten übermittelt (Submit-Knopf im Formular), erhält das Script alle erzeugten Daten als einen Satz von Name-Wert-Paaren. Der Name ist jeweils der, den man beim INPUT-Tag (bzw. beim SELECT- oder TEXTAREA-Tag) festgelegt hat, die Werte sind das, was der Anwender ins Formular eingetragen oder gewählt hat. Dieser Satz von Name-Wert-Paaren wird in einem einzigen langen String übermittelt, den das CGI-Programm auflösen muß. Das ist nicht sehr kompliziert, und es gibt viele fertige Routinen dazu. Der Aufbau des Strings ist recht einfach:
name1=wert1&name2=wert2&name3=wert3Man muß den String also einfach beim &-Zeichen zerlegen. Dann erhält man die Paare
name1=wert1 name2=wert2 name3=wert3In den entstandenen Häppchen muß man nun noch
Das kommt daher, das der übermittelte String in der URL des CGI-Programms codiert ist. Bei einer Form der Übermittlung zum Server wird er durch "?" getrennt an die URL angehängt, was Sie beispielsweise beim Bedienen einer Suchmaschine in der URL-Zeile des Browsers sehen kann. Der Anwender muß aber nach wie vor die Möglichkeit haben, &-Zeichen und Gleichheitszeichen zu übergeben - deshalb die Codierung durch "%xx". Die folgende Tabelle zeigt die Zeichencodierung:
Zeichen | Code | Zeichen | Code | Zeichen | Code | Zeichen | Code |
---|---|---|---|---|---|---|---|
Leerz. | + | ! | %21 | " | %22 | # | %23 |
$ | %24 | % | %25 | & | %26 | ' | %27 |
( | %28 | ) | %29 | + | %2B | , | %2C |
/ | %2F | : | %3A | ; | %3B | < | %3C |
= | %3D | > | %3E | ? | %3F | [ | %5B |
\ | %5C | ] | %5D | ^ | %5E | " | %60 |
{ | %7B | | | %7C | } | %7D | ~ | %7E |
° | %A7 | Ä | %C4 | Ö | %D6 | Ü | %DC |
ß | %DF | ä | %E4 | ö | %F6 | ü | %FC |
Das Anhängen der Daten an die URL ist aber nicht die einzige Möglichkeit - die Methode hätte auch ihre Grenzen bei grossen Datenmengen, etwa einer hochzuladenden Bilddatei. Deshalb kennt das ZTTP-Protokoll mehrere Möglichkeiten. Von wo das CGI-Programm den Formularinhalt erhält, hängt von der Methode ab, mit der die HTTP-Form übermittelt wurde:
http://.../cgi-bin/testcgi.pl?Text=Hallo+dies+ist+ein+Test&Zeichen=%25Diese URL wird beim Absenden der Anfrage auch durch den Browser angezeigt. Die Nachteile der GET-Methode sind leicht ersichtlich: Es eignet sich nur bei relativ geringen Datenmengen und die URLs werden unleserlich. Der Vorteil liegt darin, daß diese Darstellung für den CGI-Programmierer sehr hilfreich sein kann beim Debugging seinen Scriptes. Außerdem ist GET schneller als POST.
Bei GET-Übermittlungen liegt das Ergebnis in der Environment-Variable QUERY_STRING.
Bei POST-Übermittlungen muß man die Formulardaten
von STDIN lesen. Die genaue Anzahl der übermittelten
Bytes steht dabei in der Variablen CONTENT_LENGTH.
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 in die Bookmarks aufnehmen.
Hier sind noch einmal die Schritte aufgeführt, die ein CGI-Script normalerweise durchlebt, wenn es vom Benutzer aufgerufen wird:
Content-Type: text/htmlgefolgt von einer Leerzeile auf die Standardausgabe aus. Nun läßt es eine normale HTML-Antwort folgen, die es ebenfalls auf die Standardausgabe ausgibt. Wenn das Script beendet ist, sieht der Anwender die so erzeugte Seite. Das Script liegt in einem speziellen Verzeichnis auf dem Server (meist "cgi-bin"). Der Content-Type kann natürlich variieren, es sind alle gebräuchlichen und vom Browser akzepierten MIME-Typen erlaubt. Versuchen wir es mal mit einem einfachen Beispiel.
Die beiden folgenden Programme liefern jeweils nur ein "Hello World" als HTML-Seite. Es gibt jeweils eine C- und eine Perl-Version. Zuerst die C-Version:
/************************************************/ /** hello.c -- simple "hello, world" fuer cgi **/ /************************************************/ #include <stdio.h> int main(void) { /** CGI response header **/ printf("Content-type: text/html\n\n") ; /** HTML response page **/ printf("<html>\n") ; printf("<head><title>CGI Output</title></head>\n") ; printf("<body>\n") ; printf("<h1>Hello, world.</h1>\n") ; printf("</body>\n") ; printf("</html>\n") ; return(0) ; }
Und nun die Perl-Version:
#!/usr/bin/perl # # CGI response header print "Content-type: text/html\n\n" ; # HTML response page print <<EOF ; <html> <head><title>CGI Results</title></head> <body> <h1>Hello, world.</h1> </body> </html> EOF exit;
Wer wissen möchte, wie mühsam die CGI-Programmierung in C ist, kann einen Blick in das C-Skript werfen.
Content-type: image/gif GIF89a&%--- binärer Inhalt des GIF hier ---......
Die HTML-Datei beim Client kann ein solches Script-generiertes Bild zum Beispiel wie folgt aufrufen:
<IMG SRC="gifmaker.cgi?param1=wert1">
Für eine solche Aktion gibt das CGI-Programm in der Regel die "Content-type"-Zeile und die darauf folgende Leerzeile aus und kopiert dann die Binärdatei auf die Standardausgabe, z. B.:
#!/usr/bin/perl my $file = "....."; # Name und Pfad der GIF-Datei my $buffer; print "Content-type: image/gif\n\n"; open GIF, $file) || die "Cannot open $file\n"; print $buffer while (read(GIF,$buffer,16384)); close(GIF);
Wenn die HTML-Antwort des Scripts immer die gleiche ist oder wenn man mit einer von mehreren vorhandenen Dateien antworten möchte, könnte man das 'Location'-Antwortprinzip hilfreich finden. Damit kann man den Browser auf eine andere URL umleiten, was eigentlich für umgezogene Seiten gedacht ist. Hier ein Beispiel. Das Script sollte generell die folgenden drei Zeilen ausgeben:
Status: 302 Found Location: response.html URI: <response.html>
gefolgt von einer Leerzeile. Der Browser des Clients wird daraufhin die Datei "response.html" laden, als sei es die Antwort des CGI-Scripts. Hier kann man natürlich relative und absolut Adressen angeben. In diesem Fall erzeugt man keinen Content-type:-Header!
Normalerweise bindet man CGI-Skripts als "action" in ein Formular ein. Diese Vorgehensweise erfordert jedoch, daß der Benutzer explizit den Submit-Button aktiviert. Sie ist somit denkbar ungeeignet, automatisch Benutzer-Daten abzuspeichern (z. B. für User-Tracking oder Erfassung von Klick-Raten). Mit einem kleinen Trick aktiviert der Server das Skript jedoch automatisch. Dazu bindet man es als Bild in den HTML-Text aller überwachten Seiten ein:
<img src="/cgi-bin/klick.cgi">Damit der Browser keinen Fehler meldet, weil er kein Bild geliefert bekommt, lenkt das CGI-Skript den Request mit
print "location: //icons/tolles.gif\n\n";auf ein existierendes GIF-Bild um.
Dabei gilt die Regel: Traue keiner Benutzer-Eingabe! Wie Sie oben gesehen haben, muß der Anwender kein Formular ausfüllen, sondern er kann alle Eingaben für Ihr Script auf der URL-Zeile zusammenbasteln. Zum Beispiel sollte man nie vom Anwender übermittelte Daten direkt als Kommando ausführen, ohne die Daten zu prüfen. Hacker riechen solche Löcher! Betrachten Sie dazu folgendes CGI-Script mit dem man Benutzerdaten per "finger"-Kommande einholen kann. Ein Perl-Script könnte folgendermaßen aussehen:
system ("finger $username");Wenn der User nun "james; rm -rf /'" als Usernamen eingibt, wird daraus
system ("finger james; rm -rf /");was so viele Dateien wie möglich löscht. Auch wenn der WWW-Server mit relativ beschränkten Zugriffsrechten läuft, kann doch die eine oder andere Datei "erwischt" werden. Die Eingabe sollte also daraufhin geprüft werden, ob "gefährliche" Zeichen enthalten sind und dann zurückgewiesen werden.
Es ist für einen Hacker ja ganz einfach, irgendwelche FORM-Variablen an ein Script zu schicken - mit irgendwelchen Werten (auch Steuerzeichen). Ein Script sollte auf solche Daten nicht reagieren. Er braucht dzu nicht einmal ein Formular, bei Verwendung der Methode GET genügt es, alles in der URL-Zeile einzutippen. Ein Hacker kann auch einfach lokal den HTML-Quelltext verändern, zusätzliche Dateien oder auch Kommandos in sein Menü einfügen und dann das geänderte Formular abschicken.
Oft leitet ein Skript die Eingabe auch an Programme weiter, ohne daß der Programmierer wichtige Details über diese kennt. So hat das Programm mail wie viele andere Unix-Programme eine rudimentäre Benutzerschnittstelle, um Benutzern von Terminals das Leben zu erleichtern: Gibt man in der ersten Spalte einer Zeile eine Tilde (~) ein, so wird der Rest der Zeile vom Betriebssystem interpretiert. Jedes Skript, das Benutzereingaben ungeprüft an dieses Utility weiterreicht, bietet e inem Hacker damit sehr komfortable Möglichkeiten, weil er gleich mehrere Zeilen in einem Rutsch auf dem Rechner ausführen lassen kann.
Alle Daten, Parameter oder Anfragen, die den Server von außen erreichen, sind also als potentiell gefährlich anzusehen. Überprüfungen im Browser reichen aus o. g. Gründen nicht. Auch Cookies bieten keinen Schutz vor Manipulation. Es ist nämlich möglich, mit Hilfe von verbreiteten Modulen einen Web-Client in Perl zu schreiben, der dann problemlos Cookies setzen kann.
Bei der Eingabeprüfung gibt es zwei Strategien: Entweder man testet, ob die Eingabe explizit erlaubt ist, also zum Beispiel nur aus Buchstaben und Zahlen besteht. Der andere Weg ist die Kontrolle, ob die Eingabe explizit verbotene Dinge bewirkt. Falls man zur zweiten Strategie greift, muß man genau wissen, welche Eingaben zum Beispiel in der aufzurufenden Shell unerwünschte Effekte haben. Gefährlich sind folgende Zeichen:
; < > * | " & $ ! # ( ) [ ] { } : ; ' ` ? ^ \Diese Zeichen dienen in der einen oder anderen Sprache dazu, mehrere Befehle voneinander zu trennen oder die Ein- und Ausgabe eines externen Programms umzuleiten. Dabei ist die obige Liste noch unvollständig; so kann beispielsweise auch ein Zeilenwechsel (new line) oder ein Zeichen mit ASCII-Darstellung > 128 bestimmte Programme durcheinanderbringen. Die sicherere Strategie ist deshalb der Test auf explizit erlaubte Zeichen.
Externe Programme sollten mit Vorsicht eingesetzt werden. Bei vielen gibt es die Möglichkeit des Zugriff auf die Shell. So bildet z. B. beim mail-Programm die Angabe des Adressaten auf der Kommandozeile eine Sicherheitslücke, den dort kann zum einen eine ganze Liste plaziert werden oder wieder Kommandos verkettet (wie oben bei "finger"):
open( MAIL, "| mail $addressat"); print MAIL "Subject: Fehlerreport\n\n"; print MAIL $emailtext; close MAIL;In jedem Falle ist hier das Programm sendmail vorzuziehen. Dieses Tool bietet mit der Kommandozeilen-Option -t die Möglichkeit, des Aufrufs ohne Parameter. Das sieht dann etwa so aus:
open (MAIL, "| /usr/lib/sendmail -it"); print MAIL "To: $addressat\n"; print MAIL "From: webmaster\@netzmafia.de\n", print MAIL "Subject: Fehlerreport\n\n"; print MAIL $emailtext; close MAIL;Trotzdem sollte man auf die zusätzliche Überprüfung der E-Mail-Adresse nicht verzichten.
Dann sollte man im Quelltext suchen, wo Interpreter aufgerufen werden. In Perl kommen alle Aufrufe der Funktionen eval, open, system, exec und glob in Frage, aber auch die sogenannten Backticks wie zum Beispiel in $line = "grep $word $file"; In C heißen die kritischen Funktionen system, popen und exec. Normalerweise sind dies nur wenige Stellen im Programm. An diese Funktionen darf ein CGI-Skript auf keinen Fall ungeprüfte Benutzereingaben als Argumente übergeben. In C sollte man zusätzlich die Speicherverwaltung unter die Lupe nehmen und prüfen, ob statische Puffer verwendet werden.
Die meisten Web-Server starten zwar typischerweise als "root". Diese Rechte benötigen sie, um die Netzwerkverbindung herzustellen. Wenn sie dann tatsächlich Benutzeranfragen bearbeiten, benutzen sie eine andere Benutzeridentität mit weniger Rechten, unter Unix typischerweise als Benutzer "nobody" oder "wwwrun". CGI-Skripte laufen dann auch unter dieser Benutzerkennung. Ein Hacker, der ein Sicherheitsloch in einem CGI-Skript ausnutzt, führt seine Kommandos mit niedrigen Privilegien aus. Aber das schließt nicht allen Mißbrauch aus. Selbst dieser Benutzer ist trotzdem zu vielen Dingen berechtigt.
Irgendwie muß das Skript aus einer verdorbenen Benutzereingabe eine gute machen. Wie bei Lebensmitteln muß man sich die verdorbenen Daten gut ansehen und verdächtige Stellen großflächig entfernen. Hierfür bietet Perl reguläre Ausdrücke. Der im folgenden vorgestellte reguläre Ausdruck dient z. B. zur Überprüfung, ob ein eingegebener Text eine halbwegs gültige EMail-Adresse darstellt.
/^([a-zA-Z0-9\-\.]+)@([a-zA-Z0-9\-\.]+\.[a-z]+)$/Er fängt zumindest die gröbsten Schnitzer ab. Wenn Perl das durch den regulären Ausdruck beschriebene Muster erkennt, kann man das Ergebnis einer Variablen zuweisen: $email = "$1\@$2"; Die Variable $email kann dann gefahrlos für den Aufruf eines externen Mail-Programmes verwendet werden.
Ähnliche Probleme können auch beim Newline-Zeichen (\n) oder beim Carriage Return (\r) auftreten. Ebenso müssen der Backslash und weitere Zeichen ausmaskiert werden.
Die sicherste Methode ist natürlich, Dateinamen generell unabhängig von Eingabeparametern zu machen. Man kann im Programm (oder in einer Konfigurationsdatei) die Zuordnung Parameter - Dateiname als Hash vorsehen. Also nicht z. B.:
... $dat = FORM{'topic'}; $filename = $PATH . $dat . '.html'; open(HELP,$filename); ...Im obigen Beispiel gibt es noch mehr Haken. So wird nicht geprüft, ob es die Datei gibt und es wird auch nicht explizit der Modus angegeben. Besser ist da schon folgender Code:
... my %Filenames = ( 'eins' => '/home/www/helpfiles/one.html', 'zwei' => '/home/www/helpfiles/two.html', 'drei' => '/home/www/helpfiles/three.html', ); ... $dat = FORM{'topic'}; $filename = $Filenames{$dat}; if (-e $filename) { open(FILE,"<$filename") || goto form; ... } else { errmsg("Keine Information zu $dat vorhanden!\n"); } ...
Zuerst überprüfen Sie, ob die Eingabe nur die erlaubten Zeichen enthält. Als nächstes werden von den zugelassenen Zeichen diejenigen maskiert, die als gefährlich angesehen werden. Dazu ein Beispiel:
... # Definition der Zeichenmengen my $SECURE = '\w\d'; my $DANGEROUS = '&`\'\\|"*?~<>^(){}\$\n\r\[\]'; if ($input =~ m/^[$SECURE$DANGEROUS]+$/g) { $input =~ s/([$DANGEROUS]+)/\\$1/g; } else { print "Bad input chars in $input\n"; goto form; } print "Result = [$input]\n"; ...Dieses Skript definiert zwei Zeichen-Mengen:
<FORM METHOD="GET" ACTION="http://host.domain/cgi-bin/testmich"> Anmeldung zur Weihnachtsfeier der Fakultät am 18. Dezember <P> <INPUT TYPE="radio" NAME="kommt" VALUE="ja" CHECKED> Ich komme.<br> <INPUT TYPE="radio" NAME="kommt" VALUE="nein"> Ich komme nicht. <P> Name: <INPUT TYPE="text" NAME="Name" SIZE="40" MAXLENGTH="60"><BR> Telefonnummer: <INPUT TYPE="text" NAME="tel" SIZE="20" MAXLENGTH="20"> <P> <INPUT TYPE="submit" VALUE="Weg damit"> </FORM>
bewirkt eine Darstellung wie
Anmerkung: Das in diesem Beispiel verwendete CGI-Programm gibt es nicht (schon, weil es den Rechner nicht gibt).
Eine 'echte' Anmeldungs-Prozedur würde die Zu- und Absagen mit Name und Telefonnummer in einer Datenbank speichern und dann die Bestätigung an den Client senden.
Das Senden einer solchen Antwort ist immer notwendig, denn der Benutzer muß auf seinem Bildschirm erkennen können, daß das Anklicken des Submit-Knopfes funktioniert hat. Im einfachsten Fall genügt eine kurze Meldung, daß die Eingabe verarbeitet wird, und ein Hinweis, daß der Benutzer mit der Back-Taste oder dem Back-Befehl seines Browsers zur vorherigen Information zurückkehren und weiterarbeiten kann.
Für genauere Informationen über die vom Server unterstützten
Übertragungs-Methoden und die Übergabe der Eingabedaten an das
CGI-Programm ist ein Studium der entsprechenden Fachliteratur nötig.
Als Methode können GET oder POST verwendet werden.
Nun etwas mehr Info zum Aufbau von Formularen. Zur Erinnerung: Formulare werden durch die Tags <FORM> ... </FORM> begrenzt, wobei über die Attribute METHOD und ACTION die Art der Verarbeitung und das Bearbeitungsprogramm auf dem Server spezifiziert werden:
<FORM METHOD="POST" ACTION="URL des Bearbeitungsprogramms" >
Zum Beispiel: <FORM METHOD="GET" ACTION="http://www.netzmafia.de/cgi-bin/formularcheck.cgi">
Die Zeile oben können Sie übrigens verwende, um ein Formular zu testen. Das Script liefert eine Liste aller Eingaben als Antwort.
Dmit sind wir auch schon bei den verschiednen Eingabe-Widgets angelangt. Innerhalb eines Formulars gibt es neben drei Eingabe-Tags, INPUT, SELECT und TEXTAREA.
HTTP/1.0 200 OKwobei HTTP/1.0 die HTTP-Version ist, 200 ist ein Statuscode und OK die zugehörige Meldung. Es gibt natürlich viele andere Codes.
Statuscode | zugehörige Meldung | Bedeutung |
---|---|---|
100 | Continue | Fortfahren. Wird derzeit noch nicht verwendet. |
101 | Switching Protocols | Protokoll wechseln. Wird derzeit noch nicht verwendet. |
200 | OK | Der Server konnte die angeforderten Daten wie gewünscht versenden. Dies ist der Normalfall, wenn keine Probleme auftauchen. |
201 | Created | Ein Objekt (z.B. eine Datei oder ein Verzeichnis) wurde auf dem Server erfolgreich angelegt. Beispielsweise, wenn die Anfrage des Browsers an den Server mit einer der HTTP-Übertragungsmethoden post oder put erfolgte. |
202 | Accepted | Der Server hat die Anfrage des Browsers akzeptiert, liefert aber keine Daten als Antwort. Der Server schreibt die Daten statt sie zu senden in eine Datei und teilt in der Meldung mit, wo die Daten später zu finden sein werden. |
203 | Non-Authoritative Information |
Dieser Statuscode sollte von einem Server anstelle von 200 zurückgegeben werden, wenn es sich nicht um den Original-Server handelt, sondern beispielsweise um einen Proxy-Server. Der Web-Browser erfährt auf diese Weise, dass die Daten erfolgreich gesendet werden konnten, aber nicht vom Original-Server kommen und daher keine Garantie auf deren Aktualität besteht. |
204 | No Content | Der Server hat die Anfrage erhalten, sendet jedoch keine Daten zurück. Gut verwendbar ist dieser Statuscode bei Verwendung in CGI-Scripts, die zwar etwas auf dem Server erledigen, aber keinen neuen HTML-Code an den aufrufenden Browser senden wollen. Aus Sicht des Anwenders bleibt der alte Bildschirminhalt bestehen. |
205 | Reset Content | Der angegebene Server existiert nicht bzw. der Server, der diese Antwort gibt, ist nicht der angefragte Server und kann den angefragten Server nicht finden. Die angeforderten Daten können deshalb nicht versendet werden. |
206 | Partial Content | Die angeforderten Daten werden in mehreren Portionen versendet. Mit Angaben zu content_length und content_range wird angegeben, wie viele Bytes von dem angeforderten Inhalt geliefert werden, und welcher Teil der Gesamtdaten. |
300 | Multiple Choices | Die angeforderten Daten sind unter mehreren verschiedenen URIs vorhanden (Mirror). Anstelle der Daten werden die verfügbaren URIs als Liste übertragen. Der Web-Browser kann den Anwender anschließend in einem Dialog einen URI auswählen lassen. |
301 | Moved Permanently | Die angeforderten Daten befinden sich nicht mehr unter dem URI, sie wurden dauerhaft auf eine andere Adresse verschoben. In der Statusmeldung wird angegeben, unter welchem URI sich die Daten jetzt befinden. Ein Web-Browser, der diese Antwort vom Server erhält, kann beispielsweise gleich die neue Adresse anfordern. |
302 | Moved Temporarialy | Die angeforderten Daten wurden vorübergehend zu einem anderen URI verschoben. In der Statusmeldung wird angegeben, unter welcher Adresse sich die Daten derzeit befinden. |
303 | See Other | Die angeforderten Daten sind unter einem angegebenen URI verfügbar und sollte von dort mit Hilfe der get-Methode angefordert werden. Dieser Statuscode ist für CGI-Scripts gedacht, die mit der post-Methode aufgerufen wurden und den Browser auf eine andere Ressource lenken wollen, die mit der get-Methode angefordert werden soll. |
304 | Not Modified | Die angeforderten Daten haben sich seit dem angegebenen Zeitpunkt nicht geändert und werden deshalb nicht gesendet. Dieser Statuscode ist neben dem Code 200 einer der häufigsten in der Praxis. Er wird verursacht durch Web-Browser, die aufgrund ihrer Cache-Einstellungen Daten erst wieder nach einer bestimmten Zeit vom Original-Server laden. |
305 | Use Proxy | Die angeforderten Daten sollen statt von diesem Server von dem in der Statusmeldung angegebenen Proxy-Server angefordert werden. |
306 | [Unused] | Reserviert. Wird derzeit aber nicht verwendet. |
307 | Temporary Redirect | Wie Statuscode 302. Gedacht für Fehlreaktionen einiger Browser auf 302. |
400 | Bad Request | Die Anfrage enthält Syntaxfehler. Der Server kann die Anfrage deshalb nicht bearbeiten. Das kann beispielsweise vorkommen, wenn die Anfrage dadurch zustande kam, dass ein Anwender versuchte, einen URI händisch in die Adresszeile des Browsers einzugeben und dabei ungültige Zeichen verwendete. |
401 | Unauthorized | Die angeforderten Daten sind zugangsgeschützt. Der Server kann die Daten nur senden, wenn eine gültige Zugangskennung, bestehend aus Benutzername und Passwort, bei der Anfrage mit gesendet wird. Das passiert in der Praxis immer dann, wenn eine Adresse aufgerufen wird, die z.B. durch .htacess zugangsgeschützt ist. Der Web-Browser zeigt dann, nachdem er diesen Statuscode erhalten hat, einen Dialog zum Eingeben von Benutzername und Kennwort an. Mit den eingegebenen Daten startet er dann eine neue Anfrage an den Server. |
402 | Payment Required | Die angeforderten Daten sind kostenpflichtig. Der Server braucht eine Bestätigung der Zahlung. Derzeit wird dies noch nicht verwendet. |
403 | Forbidden | Die angeforderten Daten sind zugangsgeschützt. Die angegebenen Zugangs-Daten sind ungültig, z.B., wenn zuvor der Statuscode 401 zurückgeliefert worden war und der Browser falsche Zugangsdaten gesendet hat. |
404 | Not Found | Der angeforderte URI existiert nicht. Status 404 tritt immer dann auf, wenn ein Verweis auf eine nicht oder nicht mehr existierende Adresse auf dem Server führt (Tippfehler? Seite gelöscht?). |
405 | Method Not Allowed | Die angegebene Übertragungsmethode ist auf dem Server nicht erlaubt. Die Daten werden deshalb nicht übertragen. |
406 | Not Acceptable | Die Anfrage ist in dieser Form nicht akzeptabel. Die Daten werden deshalb nicht übertragen. |
407 | Proxy Authentication Required |
Der anfragende Client ist ein Proxy-Server. Die Daten werden nur übertragen, wenn er sich als gültiger Proxy-Server ausweist. Dieser Statuscode findet derzeit noch keine Verwendung. |
408 | Request Timeout | Der Server hat eine erwartete Anfrage nicht innerhalb des dafür festgelegten Maximalzeitraums erhalten. Die Verbindung zum anfragenden Browser wird deshalb abgebaut. |
409 | Conflict | Der Server kann die angeforderten Daten nicht senden, weil ein Konflikt mit einem anderen Prozess aufgetaucht ist. |
410 | Gone | Die angeforderten Daten wurden zu einem anderen URI verschoben. Dem Server ist aber nicht bekannt, wohin. |
411 | Length Required | Die Daten werden nicht gesendet. Sie können nur gesendet werden, wenn die Anfrage eine Angabe zu content_length enthält. |
412 | Precondition Failed | Eine oder mehrere Bedingungen, die bei der Anfrage gestellt wurden, treffen nicht zu. Die angeforderten Daten werden deshalb nicht übertragen. |
413 | Request Entity Too Large |
Der Server kann die Anfrage nicht bearbeiten, weil diese zu viele Zeichen enthält. Die angeforderten Daten werden deshalb nicht übertragen. |
414 | Request-URL Too Long | Der Server kann die Anfrage nicht bearbeiten, weil die angeforderte Adresse zu viele Zeichen enthält. Die angeforderten Daten werden deshalb nicht übertragen. |
415 | Unsupported Media Type | Der Server kann die Anfrage nicht bearbeiten, weil er keinen Mime-Type für den angeforderten Datentyp kennt. Die angeforderten Daten werden deshalb nicht übertragen. |
416 | Requested Range Not Satisfiable |
Die Anfrage enthält Angaben, welcher Byte-Bereich von dem angeforderten URI übertragen werden soll. Sowohl der Anfangswert als auch der Endwert des angegebenen Bereichs liegen außerhalb des verfügbaren Bytebereichs. Die angeforderten Daten werden deshalb nicht übertragen. |
417 | Expectation Failed | Die Anfrage enthält im expect-Feld bestimmte Wünsche, die der Server nicht erfüllen kann. Die angeforderten Daten werden deshalb nicht übertragen. |
500 | Internal Server Error | Der Server kann die angeforderten Daten nicht senden, weil auf dem Server ein Fehler aufgetreten ist. Beispielsweise konnte das aufgerufene CGI-Script nicht gestartet werden oder es ist wegen eines Programmierfehlers abgestürzt. |
501 | Not Implemented | Die Anfrage enthält Anforderungen, die der Server nicht bearbeiten kann, weil die Voraussetzunen dazu nicht implementiert sind. |
502 | Bad Gateway | Zum Bearbeiten der Anfrage musste der Server einen anderen Server aufrufen, erhielt dabei jedoch eine Fehlermeldung. Die angeforderten Daten können deshalb nicht gesendet werden. |
503 | Service Unavailable | Der Server kann die Anfrage wegen Überlastung nicht bearbeiten. Die angeforderten Daten können deshalb nicht gesendet werden. |
504 | Gateway Timeout | Zum Bearbeiten der Anfrage musste der Server einen anderen Server aufrufen, erhielt dabei jedoch nach einem festgelegten Maximalzeitraum keine Antwort. Die angeforderten Daten können deshalb nicht gesendet werden. |
505 | HTTP Version Not Supported |
Der Server unterstützt die im HTTP-Header der Anfrage angegebene HTTP-Version nicht. Die angeforderten Daten werden deshalb nicht gesendet. |
![]() |
![]() |
![]() |