AllesMeins: Header "weiterreichen"

Hiho,

ich öffne per fsockopen() eine Verbindung zu einem anderen Server und übermittele einige POST Daten und rufe auf diese weise eine Seite ab. Wenn ich nun einfach per echo ausgebe was da zurück kommt so enthält das auch sämtliche header (HTTP/1.1 200 OK Date: Wed, 23 Feb 2005 16:24:21 GMT Server: usw.) die auch alle als text ausgegeben werden. Ist es irgendwie möglich diese Ausgaben nicht als Text erscheinen zu lassen sondern alles was ankommt auch so an den Browser weiterzuleiten, so dass alle header vom Browser auch als header erkannt werden und der Inhalt ganz normal angezeigt wird? Ist das möglich oder muss ich die header irgendwie per regex mühsam erst mal rausfiltern, zerlegen und dann per header() entsprechend wieder zurückgeben?

Grüsse

Marc

  1. muss ich die header irgendwie per regex mühsam erst mal rausfiltern, zerlegen und dann per header() entsprechend wieder zurückgeben?

    Ja, da PHP innerhalb des Seiteninhalts ausgeführt wird, musst du für Dinge die nach "außen" sollen  spezielle Befehle verwenden: header(), setcoockie()

    Regex ist nicht nötig. Der Header ist durch eine Leerzeile vom Content getrennt. Es reicht eine einfache Suche nach: \r\n\r\n

    1. Hallo du da draußen,

      Regex ist nicht nötig. Der Header ist durch eine Leerzeile vom Content getrennt. Es reicht eine einfache Suche nach: \r\n\r\n

      Zumindest unter Unix-Systemen.

      Grüße von hier drinnen, aus Biberach an der Riss,
      Candid Dauth (ehemals Dogfish)

      --
      „Bismarck biss Mark, bis Mark Bismarck biss!“
      http://cdauth.net.tc/
      ie:{ fl:( br: va:} ls:[ fo:| rl:( n4:( ss:) de:> js:( ch:| sh:( mo:) zu:|
      1. Regex ist nicht nötig. Der Header ist durch eine Leerzeile vom Content getrennt. Es reicht eine einfache Suche nach: \r\n\r\n

        Zumindest unter Unix-Systemen.

        Ähm... wie jetzt? Ist HTTP betriebssystemabhängig? Auf welchen Teil bezog sich eigentlich deine Antwort?

        1. Hallo du da draußen,

          Regex ist nicht nötig. Der Header ist durch eine Leerzeile vom Content getrennt. Es reicht eine einfache Suche nach: \r\n\r\n
          Zumindest unter Unix-Systemen.
          Ähm... wie jetzt? Ist HTTP betriebssystemabhängig?

          Nein, aber \n. \n entspricht immer dem Zeilenumbruch des aktuellen Systems, also unter Unix dem NL und unter Windows CR NL (also das, was unter Unix \r\n wäre). Fragst du also unter einem Windows-System nach \r\n, fragst du letztendlich nach CR CR NL, und das würde bei HTTP keinen Zeilenumbruch herausbekommen.

          Abhilfe schafft da, mit der ASCII-Nummer der Zeichen zu arbeiten, und diese zu maskieren (\x10 oder so – hab die Nummern gerade nicht zur Hand).

          Grüße von hier drinnen, aus Biberach an der Riss,
          Candid Dauth (ehemals Dogfish)

          --
          „Bismarck biss Mark, bis Mark Bismarck biss!“
          http://cdauth.net.tc/
          ie:{ fl:( br: va:} ls:[ fo:| rl:( n4:( ss:) de:> js:( ch:| sh:( mo:) zu:|
          1. Hallo ihr da draußen,

            Nein, aber \n. \n entspricht immer dem Zeilenumbruch des aktuellen Systems, also unter Unix dem NL und unter Windows CR NL (also das, was unter Unix \r\n wäre). Fragst du also unter einem Windows-System nach \r\n, fragst du letztendlich nach CR CR NL, und das würde bei HTTP keinen Zeilenumbruch herausbekommen.

            Okay, es heißt ja LF (LineFeed) und nicht NL (New Line).

            Grüße von hier drinnen, aus Biberach an der Riss,
            Candid Dauth (ehemals Dogfish)

            --
            „Bismarck biss Mark, bis Mark Bismarck biss!“
            http://cdauth.net.tc/
            ie:{ fl:( br: va:} ls:[ fo:| rl:( n4:( ss:) de:> js:( ch:| sh:( mo:) zu:|
            1. Nein, aber \n. \n entspricht immer dem Zeilenumbruch des aktuellen Systems, also unter Unix dem NL und unter Windows CR NL

              Laut Manual (Strings / Zeichenketten) steht \n nur für LF.

              Okay, es heißt ja LF (LineFeed) und nicht NL (New Line).

              Interpretiere ich das als ein Einsehen des Fehlers deinerseits?

              1. Hallo du da draußen,

                Laut Manual (Strings / Zeichenketten) steht \n nur für LF.

                Hmm… Fehler im Manual oder Fehler in Toms und CKs Kopf? ;-)
                Das war doch zumindest einer der beiden, der das gesagt hatte, oder nicht? Und wäre es falsch gewesen, hätte der andere garantiert sofort genörgelt. ;-)

                Okay, es heißt ja LF (LineFeed) und nicht NL (New Line).
                Interpretiere ich das als ein Einsehen des Fehlers deinerseits?

                Nein.

                Grüße von hier drinnen, aus Biberach an der Riss,
                Candid Dauth (ehemals Dogfish)

                --
                „Bismarck biss Mark, bis Mark Bismarck biss!“
                http://cdauth.net.tc/
                ie:{ fl:( br: va:} ls:[ fo:| rl:( n4:( ss:) de:> js:( ch:| sh:( mo:) zu:|
                1. 你好 Candid,

                  Laut Manual (Strings / Zeichenketten) steht \n nur für LF.

                  Hmm… Fehler im Manual oder Fehler in Toms und CKs Kopf? ;-)

                  Weder noch, die Sache ist komplizierter:

                  \n wird auf Windows-Systemen beim Schreiben in Dateien, die im ASCII-Modus
                  geoeffnet wurden, zu \015\012 (CRLF). Unter Unizen wird das zu \012 (LF).
                  Unter MacOS < 10 wird das zu \015 (CR), das ganze ungekehrt beim einlesen.
                  Solange man die Datei immer auf demselben System bearbeitet, macht das ganze
                  keine Probleme -- es wird erst kritisch, wenn man es mit verschiedenen
                  Systemen zu tun bekommt, also z. B. Textarea-Feldern oder sowas, oder
                  Textdateien, die im Binary-Modus auf ein anderes OS uebertragen wurden -- da
                  bekommt man die Unterschiede naemlich zu spueren.

                  再见,
                  CK

                  --
                  Mit einem Windhauch kannst du das Feuer loeschen. Mit einem Windhauch kannst du das Feuer entfachen.
                  1. \n wird auf Windows-Systemen beim Schreiben in Dateien, die im ASCII-Modus
                    geoeffnet wurden, zu \015\012 (CRLF).

                    Hmmm... Das konnte ich eben unter Windows 2000 Server mit PHP 4.3.10 nicht nachvollziehen.

                    $filename = 'test.txt';
                    $somecontent = "Füge dies\nder Datei hinzu\n";

                    $handle = fopen($filename, "w"));
                    fwrite($handle, $somecontent));
                    fclose($handle);

                    ergibt sowohl mit "w" als auch mit "wb" geöffnet immer eine 26 Bytes große Datei zurück, in der im Notepad dann auch das "LF-Kästchen" statt eines Umbruchs zu sehen ist.

                    => \n == \012

                    1. 你好 dedlfix,

                      $handle = fopen($filename, "w"));
                      fwrite($handle, $somecontent));
                      fclose($handle);

                      ergibt sowohl mit "w" als auch mit "wb" geöffnet immer eine 26 Bytes große
                      Datei zurück, in der im Notepad dann auch das "LF-Kästchen" statt eines
                      Umbruchs zu sehen ist.

                      => \n == \012

                      Tjo, dann benutzt du ganz einfach die falsche Version von PHP und du musst
                      explizit definieren, dass du eine Transformation willst :)

                      Note:  Different operating system families have different line-ending conventions. When you write a text file and want to insert a line break, you need to use the correct line-ending character(s) for your operating system. Unix based systems use \n as the line ending character, Windows based systems use \r\n  as the line ending characters and Macintosh based systems use \r as the line ending character.

                      If you use the wrong line ending characters when writing your files, you might find that other applications that open those files will "look funny".

                      Windows offers a text-mode translation flag ('t') which will transparently translate \n to \r\n when working with the file. In contrast, you can also use 'b' to force binary mode, which will not translate your data. To use these flags, specify either 'b' or 't' as the last character of the mode parameter.

                      The default translation mode depends on the SAPI and version of PHP that you are using, so you are encouraged to always specify the appropriate flag for portability reasons. You should use the 't' mode if you are working with plain-text files and you use \n to delimit your line endings in your script, but expect your files to be readable with applications such as notepad. You should use the 'b' in all other cases.

                      If you do not specify the 'b' flag when working with binary files, you may experience strange problems with your data, including broken image files and strange problems with \r\n characters.

                      In C passiert das uebrigens automatisch, hrhr...

                      再见,
                      CK

                      --
                      73.255437% der Statistiken spielen eine Genauigkeit vor, die durch die angewandte Methode nicht gerechtfertigt wird.
                      1. => \n == \012

                        Tjo, dann benutzt du ganz einfach die falsche Version von PHP und du musst
                        explizit definieren, dass du eine Transformation willst :)

                        Windows offers a text-mode translation flag ('t') which will transparently translate \n to \r\n when working with the file.

                        Ah ja. Die deutschsprachige Version der Seite schweigt sich leider darüber aus. (Die englische hatte ich gestern nicht bemüht. Normalerweise bevorzuge ich die aus ebendiesem Grunde.)

                        Etwas weiter oberhalb der von dir zitierten Stelle steht übrigens:

                        Note: As of PHP 4.3.2, the default mode is set to binary for all platforms that distinguish between binary and text mode. If you are having problems with your scripts after upgrading, try using the 't' flag as a workaround until you have made your script more portable as mentioned below.

                        Das heißt also, dass man "heutzutage" explizit dieses Verhalten einschalten muss. Die Gefahr, da automatisch darüber zu stolpern, würde ich also eher als gering einstufen.

                  2. Hallo du da draußen,

                    \n wird auf Windows-Systemen beim Schreiben in Dateien, die im ASCII-Modus
                    geoeffnet wurden, zu \015\012 (CRLF). Unter Unizen wird das zu \012 (LF).
                    Unter MacOS < 10 wird das zu \015 (CR), das ganze ungekehrt beim einlesen.

                    Habe ich das jetzt richtig verstanden?

                    Wenn ich jetzt folgenden String habe:
                    "\n"
                    -- ich habe den selbst in meine PHP-Datei geschrieben, dann ist das quasi das gleiche wie
                    "\012"
                    . Egal unter welchem System. Und erst wenn PHP jetzt eine Datei beschreibt, konvertiert es automatisch alle "\012" zum Zeilenumbruch des entsprechenden Betriebssystems?

                    Grüße von hier drinnen, aus Biberach an der Riss,
                    Candid Dauth (ehemals Dogfish)

                    --
                    „Bismarck biss Mark, bis Mark Bismarck biss!“
                    http://cdauth.net.tc/
                    ie:{ fl:( br: va:} ls:[ fo:| rl:( n4:( ss:) de:> js:( ch:| sh:( mo:) zu:|
                    1. 你好 Candid,

                      \n wird auf Windows-Systemen beim Schreiben in Dateien, die im
                      ASCII-Modus geoeffnet wurden, zu \015\012 (CRLF). Unter Unizen wird
                      das zu \012 (LF). Unter MacOS < 10 wird das zu \015 (CR), das ganze
                      ungekehrt beim einlesen.

                      Habe ich das jetzt richtig verstanden?

                      Wenn ich jetzt folgenden String habe:
                      "\n"
                      -- ich habe den selbst in meine PHP-Datei geschrieben, dann ist das quasi
                      das gleiche wie
                      "\012"
                      . Egal unter welchem System.

                      Jo.

                      Und erst wenn PHP jetzt eine Datei beschreibt, konvertiert es
                      automatisch alle "\012" zum Zeilenumbruch des entsprechenden
                      Betriebssystems?

                      Jepp, wobei man bei neueren Versionen wohl den Modus explizit aktivieren
                      muss. Frueher[tm] war der von Haus aus bei allen Nicht-b-Modi aktiviert.

                      再见,
                      CK

                      --
                      Die Summe zweier gerade Primzahlen ist immer eine Quadratzahl.
                2. Hallo du da draußen,

                  Ich bin nicht draußen, ich bin drin. Wäre ich draußen könnte ich hier drin nicht mitlesen. :-)

                  Laut Manual (Strings / Zeichenketten) steht \n nur für LF.

                  Hmm… Fehler im Manual oder Fehler in Toms und CKs Kopf? ;-)
                  Das war doch zumindest einer der beiden, der das gesagt hatte, oder nicht? Und wäre es falsch gewesen, hätte der andere garantiert sofort genörgelt. ;-)

                  Diese Aussage kenne nicht. Ich will jetzt auch nicht die drei oder vier Postings der beiden im Archiv danach durchsuchen... Hat jemand einen passenden Quellen-Link?

                  Ich nehme auch nicht an, dass \n unterschiedlich interpretiert wird, da sonst sicher auch in den Userkommentaren ein entsprechender Hinweis wäre.

                  Auch ein echo strlen("\n") . bin2hex("\n"); unter php auf Windows 2000 Server liefert ein 10a ab.

                  Interpretiere ich das als ein Einsehen des Fehlers deinerseits?
                  Nein.

                  Na dann auf in die nächste Runde :-)

    2. Hiho,

      ich habe mal ein wenig rumprobiert. Die folgenden Befehle werden nach dem Trennen als header erkannt. Ich hab versucht die einzeln per header() rauszugeben und erhalte einen error 500 internal server error von meinem test-Apache.

      HTTP/1.1 200 OK
      Date: Wed, 23 Feb 2005 17:17:23 GMT
      Server: Apache/1.3.29 (Unix)
      Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
      Content-Disposition: attachment; filename=Test-Datei.tar
      Content-Transfer-Encoding: binary
      Expires: Thu, 19 Nov 1981 08:52:00 GMT
      Pragma: no-cache
      X-Powered-By: PHP/4.3.10
      Content-Length: 20480
      Connection: close
      Content-Type: application/x-tar

      Irgend eine Idee was davon den Error 500 verursachen könnte, sprich was ich nicht per header() ausgeben darf?

      Das hier ist mein Test-Script:

      =====================================================
      while(!feof($fp)) {

      $in = fgets($fp, 128);
      if($in == "\r\n"){
        $cut = 1;
      }
      if($cut != 1){
        echo header(chop($in));
      } else {
        echo $in;
      }

      Marc

      1. Irgend eine Idee was davon den Error 500 verursachen könnte, sprich was ich nicht per header() ausgeben darf?

        Der 500er Error hat doch sicher irgendetwas im errorlog hinterlassen? Schau doch mal nach, was das war.

      2. Hiho Marc,

        while(!feof($fp)) {

        $in = fgets($fp, 128);
        if($in == "\r\n"){
          $cut = 1;
        }
        if($cut != 1){
          echo header(chop($in));
        } else {
          echo $in;
        }

        1. Du solltest dringend abprüfen, ob der Response mit dem Status 200 Quitiert wurde.
        2. "echo header()" Was soll das? header() gibt int zurück, aber sorgt für das Versenden des Headers, welcher der Funktion als Parameter übergeben wurde. Somit ist ab diesem Moment Essig mit weiteren Headern.
        3. header("Server: blablabla"); - akzeptiert ein Server in aller Regel nicht.
        4. header("Date: blablabla"); - akzeptiert ein Server in aller Regel nicht.
        5. 3. und 4. führen nicht zu einem Status 500.
        6. "\r\n\r\n" <CRLF><CRLF> ist Trenner von Header zu Content, warum gibst Du ihn zwei mal aus?

        Welcher Server?
        Welches SAPI?
        Welche Versionen?

        Gruß aus Berlin!
        eddi

        1. Hiho,

          2.) das war ein Fehler beim zusammenkopieren. Da war vorher noch eine Testausgabe drinne die ich nicht sauber rausgelöscht habe. Mein fehler
          6.) Verstehe ich irgendwie nicht.

          Aber ich bin inzwischen schon so weit das die header richtig akzeptiert werden. Es kommt zwar noch keine saubere Datei hintern raus, aber die sache mit den headern ist erst mal durch...

          Grüsse

          Marc

          1. Re:

            while()
                if(!)
                    header()

            # Server sendet jetzt seinerseits CRLFCRLF

            else
                    echo $in;
                    # Erster Durchlauf ist welche Zeichenkette?
                    # Zeiter Durchlauf ist welche Zeichenkette?

            Gruß aus Berlin!
            eddi

  2. Hallo,

    Vielleicht eine blöde Idee, aber was passiert, wenn du das, was du als Antwort nach dem POST-Request bekommst, einfach per header() an den Client weiterleitest?

    Gruß,
    Severin

    --
    They that can give up essential liberty to obtain a little temporary safty deserve neither liberty nor safty.
    -- Benjamin Franklin