WauWau: korrekter HTTP-Statuscode für 404...

Hallo,

sehr seltsam: Folgendes müsste eigentlich wunderbar funktionieren:

header("HTTP/1.0 404 Not Found");

tud es aber nicht. Nein, ich habe vorher noch nix an den Browser
gesendet - so dumm bin ich nun auch wieder nicht.

ICh habe mir schon  den log angeschaut:

192.168.1.20 - - [05/May/2004:23:59:40 +0200] "GET /news/2004/5/6/unddasnicht HTTP/1.1" 404 - "-" "Opera/7.50 (Windows NT 5.0; U)  [de]"

scheint ja sogar der Server richtig verstanden zu haben. Nur habe ich es mit dem IE, Mozilla, Opera getestet, und alle 3 Browser scheinen diesen Header nicht zu verstehen - sie zeigen einfach nix an.

Was ist hier falsch?

verwunderte Grüße,

WauWau

PS: PHP4.3.3 über SAPI auf Apache2. Falls das relevant sein sollte.
    Ist es aber afaik nicht so richtig in diesem Fall.

--
ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
E-Mail WauWau: [mailto:der-wauwau@gmx.de]
  1. Moin!

    sehr seltsam: Folgendes müsste eigentlich wunderbar funktionieren:

    header("HTTP/1.0 404 Not Found");

    192.168.1.20 - - [05/May/2004:23:59:40 +0200] "GET /news/2004/5/6/unddasnicht HTTP/1.1" 404 - "-" "Opera/7.50 (Windows NT 5.0; U)  [de]"

    Tut es doch auch.

    scheint ja sogar der Server richtig verstanden zu haben. Nur habe ich es mit dem IE, Mozilla, Opera getestet, und alle 3 Browser scheinen diesen Header nicht zu verstehen - sie zeigen einfach nix an.

    Was sollen sie anzeigen? Du sendest ja nichts außer dem Statuscode.

    PS: PHP4.3.3 über SAPI auf Apache2. Falls das relevant sein sollte.
        Ist es aber afaik nicht so richtig in diesem Fall.

    Ist insofern relevant, als dass PHP als Modul eingebunden sein muß, um den von dir verwendeten Header senden zu können. Die CGI-Version muß sich mit header("Status:...") begnügen.

    - Sven Rautenberg

    1. Hallo Sven,

      header("HTTP/1.0 404 Not Found");
      192.168.1.20 - - [05/May/2004:23:59:40 +0200] "GET /news/2004/5/6/unddasnicht HTTP/1.1" 404 - "-" "Opera/7.50 (Windows NT 5.0; U)  [de]"
      Tut es doch auch.

      Ja, scheinbar. Aber die beim Apachen eingestellte 404-Errorseite - oder überhaupt irgendeine 404-Seite - wird nicht angezeigt, was ich eigentlich erwartet hätte.

      scheint ja sogar der Server richtig verstanden zu haben. Nur habe ich es mit dem IE, Mozilla, Opera getestet, und alle 3 Browser scheinen diesen Header nicht zu verstehen - sie zeigen einfach nix an.
      Was sollen sie anzeigen? Du sendest ja nichts außer dem Statuscode.

      Sie sollen eine "404 - Diese Seite blabla...."-eigene Fehlerbeschreibung sehen (ErrorDocument 404 ....).

      PS: PHP4.3.3 über SAPI auf Apache2. Falls das relevant sein sollte.
          Ist es aber afaik nicht so richtig in diesem Fall.
      Ist insofern relevant, als dass PHP als Modul eingebunden sein muß, um den von dir verwendeten Header senden zu können. Die CGI-Version muß sich mit header("Status:...") begnügen.

      Nun, dann müsste es ja eigentlich so funktionieren, oder?

      WauWau

      --
      ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
      E-Mail WauWau: [mailto:der-wauwau@gmx.de]
      1. Hallo WauWau,

        Sie sollen eine "404 - Diese Seite blabla...."-eigene Fehlerbeschreibung sehen (ErrorDocument 404 ....).

        Wenn Du eine Seite mit PHP generierst, dann ist das nicht mehr die Zuständigkeit vom Apache, d.h. ErrorDocument greift nicht mehr. Du müsstest die Fehlerseite bspw. per readfile() oder virtual() einbinden, um den gewünschten Effekt zu erzielen.

        Viele Grüße,
        Christian

        1. Hallo Christian,

          Sie sollen eine "404 - Diese Seite blabla...."-eigene Fehlerbeschreibung sehen (ErrorDocument 404 ....).
          Wenn Du eine Seite mit PHP generierst, dann ist das nicht mehr die Zuständigkeit vom Apache, d.h. ErrorDocument greift nicht mehr.

          Wirklich? Das verwundert mich jetzt aber sehr. Denn afaik überwacht der Apache ja den gesamten CGI-Prozess (man sende mal in einem Perl-Scriptchen einfach mal Daten los, ohne mit "content-type: blabla\n\n" anzufangen). Wenn also ein 404 beim Apachen ankommen würde, hätte ich von ihm erwartet, dass er als content nach dem 404-Header eine 404-Fehlerbeschreibung dranhängt.

          recht verwunderte Grüße,

          WauWau

          --
          ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
          E-Mail WauWau: [mailto:der-wauwau@gmx.de]
          1. Hola,

            ok, ich mache es jetzt einfach so, wie du es vorgeschlagen hast:

            header("HTTP/1.0 404 Not Found");
              header("Location: /server/errors/?404");
              exit;

            Ist das dann eigentlich "valides" HTTP? Ich meine, darf ein "Location" eigentlich noch nach dem 404-Fehler-Hinweis kommen?

            Die getesteten Browser interpretieren es richtig.

            WauWau

            --
            ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
            E-Mail WauWau: [mailto:der-wauwau@gmx.de]
            1. hi,

              header("HTTP/1.0 404 Not Found");
                header("Location: /server/errors/?404");
                exit;

              Ist das dann eigentlich "valides" HTTP?

              nein. Location erfordert einen vollständigen URL inkl. protokoll-angabe, also
              header("Location: http://www.example.com/...");

              Ich meine, darf ein "Location" eigentlich noch nach dem 404-Fehler-Hinweis kommen?

              ich weiss gerade nicht, ob das sinnvoll ist.
              404 heisst nicht gefunden,
              der location-header erzeugt aber gleichzeitig einen "302 found".

              Die getesteten Browser interpretieren es richtig.

              war noch nie ein argument.

              gruss,
              wahsaga

              --
              http://wazgnuks.net/ - back from the dead
          2. hi,

            Wenn also ein 404 beim Apachen ankommen würde,

            beim apachen kommt kein 404 "an".
            bei dem kommt zunächst mal der request des clients an, und die ressource wird auch gefunden - sonst könntest du ja nicht _im_ script per header() den status code 404 ausgeben.
            header() ist aber dazu da, zusätzliche _response_header festzulegen, also nichts was beim apachen "ankommt", sondern was dieser zurückgibt.

            hätte ich von ihm erwartet, dass er als content nach dem 404-Header eine 404-Fehlerbeschreibung dranhängt.

            für den apachen ist ja gar kein "file not found" aufgetreten.
            die ressource wurde gefunden, und _diese_ hat jetzt festgelegt, welchen zusätzlichen header der apache dem client zurückschicken soll.

            gruss,
            wahsaga

            1. Hallo wahsaga,

              Wenn also ein 404 beim Apachen ankommen würde,
              beim apachen kommt kein 404 "an".

              Sorry für meine liederliche Ausdrucksweise ;-). Ich meine in etwa
              "Wenn also ein 404-Statuscode (im Header) vom CGI-Programm an den Apachen gesendet wird,..."

              bei dem kommt zunächst mal der request des clients an, und die ressource wird auch gefunden - sonst könntest du ja nicht _im_ script per header() den status code 404 ausgeben.

              ganz genau. Request wird nämlich durch die mod_rewrite-Mühle gejagt, dann was gefunden (ansonsten kommt sowieso ein 404, vom Apachen generiert, so wie es soll), dann der Script (mit parametern) aufgerufen, und wenn der dann sagt, dass das, was eigentlich aufgerufen wurde, nicht existiert, dann gibt er einen solchen "404-Header" (...) aus. Also an den Apachen, der es wiederum an den Client weiterleitet.

              header() ist aber dazu da, zusätzliche _response_header festzulegen, also nichts was beim apachen "ankommt", sondern was dieser zurückgibt.

              Ja, das ist mir schon klar ;-). Übrigens ist es hier kein zusätlicher header, sondern ganz genau die erste Zeile des Headers. Denn afaik fangen HTTP-Header ja mit

              HTTP/1.0 XXX BESCHREIBUNG

              an (XXX = Statuscode).

              hätte ich von ihm erwartet, dass er als content nach dem 404-Header eine 404-Fehlerbeschreibung dranhängt.
              für den apachen ist ja gar kein "file not found" aufgetreten.

              Richtig, aber er hat den Header bekommen, danach wurde der Script beendet. Er sendet also an den Client lediglich einen Header, kein "Content". Also könnte er sich denken: "So, jetzt hänge ich da mal meine eigene 404-Fehlerbeschreibung dran". Wäre doch zu schön um wahr zu sein, oder?

              die ressource wurde gefunden, und _diese_ hat jetzt festgelegt, welchen zusätzlichen header der apache dem client zurückschicken soll.

              Wobei es keine zusätzliche war ;-) - oder?

              btw: Meine Lösung -> [pref:t=80707&m=469673]. Nachdem ich die erste Headerzeile mit dem 404 ausgebe, kommt noch ein "Location"-header, der den Client auf eine ordentliche 404-Seite verweist[1].

              WauWau

              [1] Armer Klient wird richtig durchgeschüttelt: Die Seite dort verweist ihn dann nochmal weiter - und letztenendes bringt dann der "404"-Header auch nix mehr ;-)

              --
              ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
              E-Mail WauWau: [mailto:der-wauwau@gmx.de]
              1. Moin!

                "Wenn also ein 404-Statuscode (im Header) vom CGI-Programm an den Apachen gesendet wird,..."

                Wieso CGI? Du arbeitest mit PHP als Apache-Modul, da ist nirgendwo CGI im Spiel.

                Außerdem überlege mal:
                Was soll der arme Apache denn machen, wenn jemand anderes einen 404 als Header sendet, aber nicht die Apache-festgelegte 404-Seite haben will, sondern eine eigene.

                Soll der Apache jetzt entscheiden "Hat keinen Body gesendet, da hänge ich mal meinen dran"? Warum dies? Es gibt einige Statuscodes, an die gehört kein Body.

                Also: Die Verantwortung liegt komplett in Händen des Skriptschreibers, inklusive aller Header und Bodys - ohne dass der Apache sich dann um irgendwas kümmert. Und das ist gut so.

                btw: Meine Lösung -> [pref:t=80707&m=469673]. Nachdem ich die erste Headerzeile mit dem 404 ausgebe, kommt noch ein "Location"-header, der den Client auf eine ordentliche 404-Seite verweist[1].

                Du mischst HTTP-Status 404 und 301/302. Das ist böse. Denn was soll da rauskommen? Entweder ist die Seite 404, dann wird der mitgesendete Body angezeigt, um den Benutzer über den Fehler zu informieren.

                Oder die Seite ist 302. Dann schickt der Browser einen neuen Request an den Server, um diese Seite anzufordern. Das bedeutet aber insbesondere für Suchmaschinen: Die Seite ist eben gerade NICHT 404. Man konnte dem Link folgen, dort wurden Redirects bis zum eigentlichen Content gefunden - also rein in die Datenbank.

                - Sven Rautenberg

                1. Hallo Sven,

                  "Wenn also ein 404-Statuscode (im Header) vom CGI-Programm an den Apachen gesendet wird,..."
                  Wieso CGI? Du arbeitest mit PHP als Apache-Modul, da ist nirgendwo CGI im Spiel.

                  Ist es nicht trotzdem irgendwie CGI?

                  Außerdem überlege mal:
                  Was soll der arme Apache denn machen, wenn jemand anderes einen 404 als Header sendet, aber nicht die Apache-festgelegte 404-Seite haben will, sondern eine eigene.

                  Und wenn nix an dem header dran hängt? Dann könnte der Apache ja mitdenken, was sich selbstverständlich auch per irgendeiner Direktive steuern ließe.

                  Soll der Apache jetzt entscheiden "Hat keinen Body gesendet, da hänge ich mal meinen dran"? Warum dies? Es gibt einige Statuscodes, an die gehört kein Body.

                  Aber bei 404 ist das ungünstig. Weil da alle Browser, mit denen ich das getestet habe, dann nix darstellen. Garnix. Aber sobald auch nur ein einziges Zeichen im "Content" steht, zeigt der IE seine eigene 404-Seite an.

                  Also: Die Verantwortung liegt komplett in Händen des Skriptschreibers, inklusive aller Header und Bodys - ohne dass der Apache sich dann um irgendwas kümmert. Und das ist gut so.

                  na dann.... ;)

                  Du mischst HTTP-Status 404 und 301/302.

                  Deswegen ja das Posting dort - ich habe gefragt, ob das eigentlich gut so ist.

                  Das ist böse.

                  Nicht schlagen, nicht schlagen! *g* ;)

                  Na wenn's so ist, dann bin ich doch mal böse, nicht wahr?

                  Denn was soll da rauskommen?

                  Ein 404, für dessen Beschreibung der Browser der URi nach "Location:" folgt. Also ein 404 mit externer Beschreibung ;-)

                  Entweder ist die Seite 404, dann wird der mitgesendete Body angezeigt, um den Benutzer über den Fehler zu informieren.
                  Oder die Seite ist 302. Dann schickt der Browser einen neuen Request an den Server, um diese Seite anzufordern.

                  Oder es ist WauWau-404, dann kann der Browser einen neuen Request an den Server schicken, um die Seite für die Fehlerbeschreibung anzufordern.

                  Na dann mache ich ees eben auf die umständliche art und weise.

                  Das bedeutet aber insbesondere für Suchmaschinen: Die Seite ist eben gerade NICHT 404. Man konnte dem Link folgen, dort wurden Redirects bis zum eigentlichen Content gefunden - also rein in die Datenbank.

                  Afaik indezieren Suchmaschinen keine passwortgeschützten Seiten ;-)

                  WauWau

                  --
                  ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
                  Self ist der WauWau
              2. hi,

                btw: Meine Lösung -> [pref:t=80707&m=469673]. Nachdem ich die erste Headerzeile mit dem 404 ausgebe, kommt noch ein "Location"-header, der den Client auf eine ordentliche 404-Seite verweist[1].

                ich mache es wie folgt machen:

                wenn in meinem script der fall auftritt, dass es zu einer per mod_rewrite-URL aufgerufenen ID keinen datenbankeintrag gibt, binde ich einfach nur per require meine error404.php ein.

                die macht dann folgendes:
                1. header('404 ...') ausgeben
                2. html-code der fehlerseite ausgeben
                3. am ende ein exit; um die verarbeitung des haupt-scriptes zu beenden.

                also "normales" error-dokument gebe ich im apachen die selbe seite an - der "zusätzliche" 404 im script stört ja an dieser stelle nicht.

                gruss,
                wahsaga

                --
                http://wazgnuks.net/ - back from the dead
                1. Hallo wahsaga,

                  btw: Meine Lösung -> [pref:t=80707&m=469673]. Nachdem ich die erste Headerzeile mit dem 404 ausgebe, kommt noch ein "Location"-header, der den Client auf eine ordentliche 404-Seite verweist[1].
                  wenn in meinem script der fall auftritt, dass es zu einer per mod_rewrite-URL aufgerufenen ID keinen datenbankeintrag gibt, binde ich einfach nur per require meine error404.php ein.
                  die macht dann folgendes:

                  1. header('404 ...') ausgeben
                  2. html-code der fehlerseite ausgeben
                  3. am ende ein exit; um die verarbeitung des haupt-scriptes zu beenden.
                    also "normales" error-dokument gebe ich im apachen die selbe seite an - der "zusätzliche" 404 im script stört ja an dieser stelle nicht.

                  Ja, das wäre auch soweit ganz schön und gut so :). Nur könnte es letztenendes Probleme mit irgendwelchen $_SERVER-Variablen geben, da die Error-PHP-Datei wiederum eine andere einbindet, usw. - und lezttenedes komme ich auch nicht mehr an irgendwas ran... *grübelgrübel* - ich glaube ich mache mir diesbezüglich einfach zuviele Gedanken.

                  Ich werde einfach eine kleine "interface.php"-Datei in mein ErrorDateien-Verzeichnis reinbauen, sodass man dann einfach

                  require "../errors/interface.php";
                     load_error(404);

                  schreibt, und die "load_error"-Datei included dann die Datei "404.php" oder sonstirgendeine festgelegte Datei und "exit;" anschließend das script.

                  basta ;)

                  WauWau

                  --
                  ss:) zu:) ls:& fo:) de:] va:) ch:° n4:( rl:( br:^ js:| ie:% fl:{ mo:|
                  Self ist der WauWau