HTTP Status 504 Gateway Timeout

Was diese Meldung in Verbindung mit CGI/1.1 bedeutet

Wer CGI-Scripts entwickelt, hat diese Meldung bestimmt schon einmal gesehen: Der Browser meldet einen Gateway-Timeout mit dem HTTP-Status 504. Was bedeutet diese Meldung nun in Verbindung mit CGI? Betrachten wir die Abkürzung CGI!

CGI: Common Gateway Interface

CGI ist ein Standard nach RFC 3875 und gibt es seither in der Version 1.1. Die Schnittstelle wird im Webserver konfiguriert, beispielsweise indem ein ScriptAlias eingerichtet wird. Bei einem HTTP-Request auf ein ausführbares Script in einem Verzeichnis, auf das der ScriptAlias verweist, wird das Script ausgeführt und der Webserver erwartet die Antwort des Scripts in STDIN.

Aus der Sicht des Webservers ist also STDIN der Gateway. Antwortet das Script nicht innerhalb einer im Webserver konfigurierten Auszeit, das heißt, schickt das Script nicht innerhalb dieser Zeit Daten nach STDOUT, erzeugt der Webserver die o.g. Meldung mit dem HTTP-Status 504 und sendet dies zurück in Richtung Browser bzw. User-Agent.

Nun ist ein CGI-Script mit langen Antwortzeiten eine unschöne Sache, gerade für den Besucher. Dennoch lässt sich ein Status 504 vermeiden, wenn das Script zu Beginn seiner länger andauernden Laufzeit wenigstens die Response-Header an den Webserver schickt. Dazu ist der Ausgabekanal zu entpuffern, bei einem Perl-Script mit $| = 1;

Welche Header muss ein CGI-Skript überhaupt senden?

Kurze Antwort: Gar keine, wenn in der Serverkonfiguration die entsprechenden Default-Werte gesetzt sind, mindestens für den Content-Type. In diesem Fall muss das CGI-Script jedoch mindestens eine Leerzeile in Richtung STDOUT senden, womit der Webserver signalisiert bekommt, dass im Folgenden alle Inhalte keine Header mehr sind, sondern der HTTP-Message-Body.

Lange Antwort: Ein CGI-Skript sendet vom Programmierer festgelegte Response-Header in Richtung STDOUT (Webserver). Einzelne Header sind mit einem einfachen Zeilenumbruch getrennt zu senden. Ein doppelter Zeilenumbruch ergibt eine Leerzeile, welche im Skript nach dem letzten zu sendenden Header notiert wird.

Der Webserver parst die vom CGI-Skript empfangenen Header und ergänzt diese mit weiteren Response-Headers, entsprechend seiner Konfiguration und den im Request gesendeten Headers. Beispiel für eine solche Ergänzung:

    Request-Header:
    Accept-Encoding: gzip, deflate

    Response-Header:
    Content-Encoding: gzip

Der Browser sendet einen Request-Header, welcher dem Webserver mitteilt, dass die Response komprimiert gesendet werden darf. Der Webserver schaut in seiner Konfiguration nach, stellt fest, dass dies möglich ist und liefert die Response entsprechend aus. Der Programmierer des CGI-Skripts muss sich darum keine Sorgen machen.

Non Parsed Header Scripts NPH

Seiner Konfiguration folgend, verzichtet der Webserver auf das Parsen der vom CGI-Skript gelieferten Header vollständig und reicht diese lediglich durch in Richtung Browser. Der Programmierer des CGI-Skripts zeigt sich voll verantwortlich dafür, dass ALLE für die Response erforderlichen Header von seinem Skript geliefert werden.

NPH ermöglicht dem vom Webserver gestarteten Prozess Daten nach STDOUT (Webserver) zu schreiben solange dieser Prozess lebt. Diese Daten betrachtet der Webserver als HTTP-Header, jeder dieser Ausgaben sollte also mit einem CRLF abgeschlossen sein. Somit kann dieser CGI-Prozess das im Webserver konfigurierte Timeout überschreiten, der Webserver pusht diese Header und sendet erst dann alles zum Browser wenn er gegen Ende des Prozesses einen Header gefolgt von einer Leerzeile bekommt, in der Regel ist das der Content-Type-Header.

#!/usr/bin/perl use strict; use warnings; use constant CRLF => "\r\n"; binmode STDOUT; $| = 1; print "HTTP/1.0 200 OK".CRLF; for(1..1000){ sleep 1; print "ping: 1".CRLF; } print "Content-Type: text/plain", CRLF, CRLF, "OK";

Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.