AND51: Was darf ein CGI-Programm für Apache ausgeben?

Hallo!

Was darf ein CGI-Skript ausgeben?
Darf es wirklich NUR mit

Content-Type: text/html

oder einem anderen MIME-Typ beginnen? Wie kann ich denn manuell einen Fehler erzeugen und so z. B. "204 No Content" oder "502 Bad Gateway" ausgeben?

Benutze Apache 2.2.x und habe gelesen, dass man das hier mit 'Status' machen könnte:

Status: 204 No Content

(mehr nicht). Ich kann leider nicht feststellen, dass das erfolgreich vonstatten geht. Gut, bei Fehler 204 kann man schlecht etwas feststellen, deshalb habe ich das hier versucht, leider ohne Erfolg:

Status: 403 Forbidden

Der Server quittiert dies im Errorlog jedoch mit "Premature end of script headers". Ich darf auch keinen kompletten HTTP-Response erzeugen, wie diesen hier:

HTTP/1.1 403 Forbidden
Server: Mein Test-Server
Connection: close

...denn dann steht im Errorlog "malformed header from script. Bad header=HTTP/1.1 403 Forbidden".

Wisst ihr weiter? Vielen Dank für eure Bemühungen!

  1. Wisst ihr weiter? Vielen Dank für eure Bemühungen!

    Tja. Ich hatte früher auch mal Probleme Header korrekt auszugeben.
    Ich habe dann gefunden dass das CGI Modul doch ideal ist, um sich valide Versionen ausgeben zu lassen, als Vorlage so zu sagen.

    Ein möglicher Fehler: Du vergisst, dass ein header durch \n\n abgeschlossen wird.
    Ein anderer möglicher Fehler: Man vergisst, das man bereits Teile des Response-Body ausgeben hat, was im Minimum \n\n ist.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
    1. Hey,

      danke für deine Antwort. Also am fehlenden \n\n kann es nicht liegen, denn ob ich es mit oder ohne mache (normalerweise immer mit), es bleibt ein Fehlschlag.

      Was meinst du mit "vergessen, dass man schon Teile des Body ausgegeben hat"? Ich möchte ja keinen Body ausgeben. Wenn ich z. B. den Code "403 Forbidden" ausgebe, dann soll entweder der Server seine Standard-ErrorDocumente schicken (ok, dann kann ich auch gleich selbst eine Ausgabe generieren), oder der Browser soll eine eigene Seite à la "Seite nicht gefunden" anzeigen. Letzteres wäre mir persönlich am liebsten.

      1. Hallo,

        danke für deine Antwort. Also am fehlenden \n\n kann es nicht liegen, denn ob ich es mit oder ohne mache (normalerweise immer mit), es bleibt ein Fehlschlag.

        gibst du tatsächlich zweimal CR/LF (also 0x0D, 0x0A) aus, oder nur zwei Linefeeds? Letzteres wäre nämlich nicht korrekt und könnte die beschriebenen Effekte verursachen.

        Was meinst du mit "vergessen, dass man schon Teile des Body ausgegeben hat"? Ich möchte ja keinen Body ausgeben.

        Doch, möchtest du. Es ist zwar technisch ausreichend, wenn nur ein HTTP-Statuscode im Header als Antwort zum Client gelangt; anstandshalber möchte man aber bitte auch eine lesbare Information haben. Und sei's nur die Ausgabe des HTTP-Statuscodes und der Klartext-Fehlermeldung, etwa "403 Forbidden".

        Wenn ich z. B. den Code "403 Forbidden" ausgebe, dann soll entweder der Server seine Standard-ErrorDocumente schicken

        Das ist, wenn ich die CGI-Spezifikation richtig verstehe, nicht vorgesehen. Das CGI-Programm muss, wenn es einmal aufgerufen ist, alle Ausgaben einschließlich der korrekten HTTP-Header selbst regeln. Die Standard-Errordokumente des Servers kommen nur dann zum Zuge, wenn das CGI-Programm gar nicht erst gestartet werden kann, weil der Server bereits einen Fehler feststellt (z.B. 401, 403, 404, 500).

        ok, dann kann ich auch gleich selbst eine Ausgabe generieren

        Eben. ;-)

        oder der Browser soll eine eigene Seite à la "Seite nicht gefunden" anzeigen. Letzteres wäre mir persönlich am liebsten.

        Das tun anständige Browser nur, wenn sie gar nicht erst eine Verbindung zum Server aufbauen können (Host not found, Connection refused). Kommt die Verbindung aber zustande, dann geben sie brav die Information aus, auch die Fehlermeldung, die sie vom Server erhalten.
        Doch halt ... IrgendEin Browser existiert da noch, der es für richtiger hält, dem Nutzer die differenzierte Fehlerinformation vom Server vorzuenthalten und ihm stattdessen die nahezu informationsfreie Zeile "Seite nicht gefunden" anzuzeigen. Zumindest in der Defaulteinstellung.

        So long,
         Martin

        --
        Die letzten Worte des Systemadministrators:
        Nur gut, dass ich ein intaktes Backup habe.
        1. Wenn ich z. B. den Code "403 Forbidden" ausgebe, dann soll entweder der Server seine Standard-ErrorDocumente schicken
          Das ist, wenn ich die CGI-Spezifikation richtig verstehe, nicht vorgesehen. Das CGI-Programm muss, wenn es einmal aufgerufen ist, alle Ausgaben einschließlich der korrekten HTTP-Header selbst regeln. Die Standard-Errordokumente des Servers kommen nur dann zum Zuge, wenn das CGI-Programm gar nicht erst gestartet werden kann, weil der Server bereits einen Fehler feststellt (z.B. 401, 403, 404, 500).

          Egal was die Spezifikation sagt. Ein 403 Response kann auch durch ein cgi Script ausgegeben werden. Apache 2.0 erlaubt das.

          Nimm den Fall einer url
          http://example.org/is_vorbidden

          Der Begriff CGI ist nach aussen vollkommen wegabstrahiert.

          Traditionell versteht man unter cgi so etwas
          http://example.org/cgi/some.pl?query

          Der Fall trifft aber heutzutage immer weniger zu.

          mfg Beat

          --
          ><o(((°>           ><o(((°>
             <°)))o><                     ><o(((°>o
          Der Valigator leibt diese Fische
          1. Hallo,

            »» > Wenn ich z. B. den Code "403 Forbidden" ausgebe, dann soll entweder der Server seine Standard-ErrorDocumente schicken
            »» Das ist, wenn ich die CGI-Spezifikation richtig verstehe, nicht vorgesehen. [...]
            Egal was die Spezifikation sagt. Ein 403 Response kann auch durch ein cgi Script ausgegeben werden. Apache 2.0 erlaubt das.

            selbstverständlich geht das - ich wollte nur darauf hinaus, dass das CGI-Programm, wenn es einmal aufgerufen ist, diese Dinge selbst in die Hand nehmen muss. Es kann AFAIK nicht mehr den Server veranlassen, *seine* Standard-Fehlerseiten auszugeben (außer 500, wenn das Script nicht ordnungsgemäß arbeitet).

            Nimm den Fall einer url
            http://example.org/is_vorbidden
            Der Begriff CGI ist nach aussen vollkommen wegabstrahiert.

            Sicher, ich spreche auch nur von der CGI-Schnittstelle zwischen Apache und einem externen Programm, nicht von *bestimmten* Scripten in einem *bestimmten* Verzeichnis.

            Traditionell versteht man unter cgi so etwas
            http://example.org/cgi/some.pl?query

            Wobei ich nie verstanden habe, warum die Server-Betreiber ein dediziertes CGI-Verzeichnis bestimmen, anstatt -wie heute üblich- Perl- oder PHP- oder sonstige Scripte dort auszuführen, wo sie nun mal liegen.

            So long,
             Martin

            --
            Ich bin im Prüfungsstress, ich darf Scheiße sagen.
              (Hopsel)
    2. Hello,

      Ein möglicher Fehler: Du vergisst, dass ein header durch \n\n abgeschlossen wird.

      Bedeutet das \n\n  hier 0D 0A 0D 0A ?
      Sonst wäre es nämlich falsch.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Ein möglicher Fehler: Du vergisst, dass ein header durch \n\n abgeschlossen wird.
        Bedeutet das \n\n  hier 0D 0A 0D 0A ?
        Sonst wäre es nämlich falsch.

        Habe das jetzt auch angepasst.
        Vielleicht hilft anderen auch der Gebrauch von
        use constant

        Hier mein mächtig cooler Code ;)

        use constant { NL => "\n", CRLF => "\015\012"};

        NL als interne logische Newline für Perl

        CRLF als Network-Newline

        ein paar Anwendungen für CRLF im Programm.

        if( $HttpError{set} != 0){
           print "Status: ",$HttpError{status},CRLF ,
              "Content-Type: text/html; charset=ISO-8859-1",CRLF,CRLF,
              $HttpError{message};
           exit;
        }

        #...

        print "Content-type:text/html",CRLF;
        set_cookies();
        $User{job} and print "Expires: -1",CRLF;
        print 'Cache-Control: private', CRLF;
        print CRLF; # header Sektion beenden

        Ansonsten wird für interne print ausgaben NL verwendet.

        mfg Beat

        --
        ><o(((°>           ><o(((°>
           <°)))o><                     ><o(((°>o
        Der Valigator leibt diese Fische
  2. Hallo!

    Was darf ein CGI-Skript ausgeben?
    Darf es wirklich NUR mit

    Content-Type: text/html

    Hallo,

    ein "normales" CGI behandelt selbst einen/seinen Header.
    Du kannst aber deinem Skript ein nph- voranstellen und der Apache wird sich um nichts kümmern und Du musst alles selbst machen.

    vergl. http://www.jmarshall.com/tools/cgiproxy/

    alles so aus den Kopf heraus

    Ulli