berlinsurfer: Komisches Content-Type Problem

Hallo,
ich gebe mittels eines PHP-Skripts ein ZIP aus- Problem ist, dass der Content-Type nicht stimmt, obwohl ich ihn per PHP richtig(?) gesetzt habe.
Hier der Code:

defined('_JEXEC') or die('Restricted access');  
$f = $this->downloadArticle();  
header("Content-Type: application/pdf");  
header("Content-Disposition: attachment; filename=" . basename($f));  
header("Pragma: no-cache");  
header("Expires: 0");  
header('Content-Length: '. filesize($f));  
readfile("$f");

Allerdings ergibt get_headers (von einem anderen Server logischerweise) folgendes aus:
[0] => HTTP/1.1 200 OK
[1] => Date: Fri, 24 Feb 2012 07:12:44 GMT
[2] => Server: Apache
[3] => X-Powered-By: PHP/5.2.12-0.dotdeb.1
[4] => Set-Cookie: 0c213845e9f18935ef3643dd94ba5e80=724b01f6cd509e437d3b7d2ddb5a9949; path=/
[5] => Set-Cookie: ce56e8a0729d1d736783f2a0f1286da9=de-DE; expires=Sat, 23-Feb-2013 07:12:44 GMT; path=/
[6] => Connection: close
[7] => Content-Type: text/html

Warum erscheint hier der falsche Content-Type (text/html) ?
Danke schon mal,
berlinsurfer

--
Science flies you to the moon.
Religion flies you into buildings.
selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
  1. Richtigerweise heißt es natürlich:

    header("Content-Type: application/zip");  
    
    

    Allerdings wird immer noch text/html ausgegeben. Firefox errät den Content-Type richtig, wohingegen Safari auf den Server vertraut und so .html anhängt...

    --
    Science flies you to the moon.
    Religion flies you into buildings.
    selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
  2. Hi,

    defined('_JEXEC') or die('Restricted access');

    $f = $this->downloadArticle();
    header("Content-Type: application/pdf");
    header("Content-Disposition: attachment; filename=" . basename($f));
    header("Pragma: no-cache");
    header("Expires: 0");
    header('Content-Length: '. filesize($f));
    readfile("$f");

    
    >   
    > Allerdings ergibt get\_headers (von einem anderen Server logischerweise) folgendes aus:  
    > [0] => HTTP/1.1 200 OK  
    > [1] => Date: Fri, 24 Feb 2012 07:12:44 GMT  
    > [2] => Server: Apache  
    > [3] => X-Powered-By: PHP/5.2.12-0.dotdeb.1  
    > [4] => Set-Cookie: 0c213845e9f18935ef3643dd94ba5e80=724b01f6cd509e437d3b7d2ddb5a9949; path=/  
    > [5] => Set-Cookie: ce56e8a0729d1d736783f2a0f1286da9=de-DE; expires=Sat, 23-Feb-2013 07:12:44 GMT; path=/  
    > [6] => Connection: close  
    > [7] => Content-Type: text/html  
    >   
    > Warum erscheint hier der falsche Content-Type (text/html) ?  
      
    Das wird der Default sein, den PHP immer sendet, wenn keine andere Angabe gemacht wird. Und von den anderen Headern, die du oben im Code hast, ist unten ja auch nicht viel zu sehen ...  
      
    Hast du das error\_reporting vernünftig eingestellt?  
    Hast du in die heruntergeladene Datei mal reingeschaut (Texteditor), ob sich darin ggf. PHP-Fehlermeldungen befinden?  
    Hast du mal mit headers\_already\_sent geprüft, ob du an obiger Stelle noch weitere Header hinzufügen kannst, oder ob es dazu vielleicht bereits zu spät ist?  
      
    MfG ChrisB  
      
    
    -- 
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    
    1. Hast du das error_reporting vernünftig eingestellt?

      Aber sowas von vernünftig.

      Hast du in die heruntergeladene Datei mal reingeschaut (Texteditor), ob sich darin ggf. PHP-Fehlermeldungen befinden?

      Das ist die Originalzipdatei, wenn ich sie umbenenne (.html entferne) und dann entpacke, funktioniert sie tadellos.

      Hast du mal mit headers_already_sent geprüft, ob du an obiger Stelle noch weitere Header hinzufügen kannst, oder ob es dazu vielleicht bereits zu spät ist?

      Ich bin radikaler vorgegangen:

      header_remove()  
      
      

      Ändert sich aber nichts.

      --
      Science flies you to the moon.
      Religion flies you into buildings.
      selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
  3. Tach!

    ich gebe mittels eines PHP-Skripts ein ZIP aus- Problem ist, dass der Content-Type nicht stimmt, obwohl ich ihn per PHP richtig(?) gesetzt habe.

    Von deinen gesetzten Headern ist kein einziger in der Ausgabe zu sehen. Ist die Ausgabe aller Fehlermeldungen aktiviert? Deine Header kommen wahrscheinlich gar nicht beim Apachen an.

    readfile("$f");

    Das Einrahmen der Variable in ""-Anführungszeichen ist sinnlos.

    Allerdings ergibt get_headers (von einem anderen Server logischerweise) folgendes aus:

    Es gibt auch für Browser eingebaute und zusätzliche Tools, um sich die HTTP-Header anzusehen, die konkret dieser Browser sieht. Für den Firefox beispielsweise gibt es die livehttpheaders-Extension.

    dedlfix.

    1. Von deinen gesetzten Headern ist kein einziger in der Ausgabe zu sehen. Ist die Ausgabe aller Fehlermeldungen aktiviert? Deine Header kommen wahrscheinlich gar nicht beim Apachen an.

      Und wie bekomme ich das raus?

      Das Einrahmen der Variable in ""-Anführungszeichen ist sinnlos.

      Habe ich entfernt.

      Es gibt auch für Browser eingebaute und zusätzliche Tools, um sich die HTTP-Header anzusehen, die konkret dieser Browser sieht. Für den Firefox beispielsweise gibt es die livehttpheaders-Extension.

      Werde ich mal schauen, danke.

      --
      Science flies you to the moon.
      Religion flies you into buildings.
      selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
      1. Tach!

        Von deinen gesetzten Headern ist kein einziger in der Ausgabe zu sehen. Ist die Ausgabe aller Fehlermeldungen aktiviert? Deine Header kommen wahrscheinlich gar nicht beim Apachen an.
        Und wie bekomme ich das raus?

        Normalerweise funktioniert header() - außer wenn die Header bereits abgefahren sind, sprich: wenn schon eine Ausgabe stattfand. Teste das mit dem von ChrisB vorgeschlagenen headers_sent(). Du kannst auch eine Ausgabe provozieren, dann solltest du Fehlermeldungen zu Gesicht bekommen. Zum Probieren, dass die Header grundsätzlich gesendet werden, kannst du text/plain verwenden und das Content-Disposition erstmal weglassen. Dann findet im Browser auch eine Ausgabe statt, bei der du eventuelle Fehlermeldungen sehen solltest. Dass die Ausgabe an der Stelle nicht unterdrückt ist, kannst du über phpinfo() testen (Werte display_errors und error_reporting).

        dedlfix.

        1. Danke dedlfix,
          ich habe mittels headers_sent() geprüft, ob schon Header verändert wurden, dass war nicht der Fall. Auch error_reporting(E_ALL) ergab keine Fehler. Den Mime-Type habe ich auf text/plain und mal spaßeshalber auf image/png gesetzt, allerdings zeigte sich keinerlei Veränderung, der Content-Type (auch in dem von dir erwähnten Plugin für FF) ist immer noch text/html.
          Gibt es sowas wie Default Content-Types? Stichwort htaccess oder php.ini ?
          Danke für die Bemühungen!

          --
          Science flies you to the moon.
          Religion flies you into buildings.
          selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
          1. Entschuldigt, wenn ich nerve, aber ich verstehe es einfach nicht.
            Wenn ich mir mittels print_r(Heiders_list()) anzeigen lassen, welche Header an den Client geschickt werden sollen, erscheint der Content-Type richtig:
            [4] => Content-Type: application/zip

            Wenn ich die Ausgabe nun aber wieder unterdrücke, wird wieder HTML als Mime-Type angezeigt. Ist das irgendeine wirre Serverkonfiguration?

            --
            Science flies you to the moon.
            Religion flies you into buildings.
            selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
            1. Tach!

              Wenn ich mir mittels print_r(Heiders_list()) anzeigen lassen, welche Header an den Client geschickt werden sollen, erscheint der Content-Type richtig:

              Dann gehe ich mal davon aus, dass PHP richtig arbeitet. Als andere Problemursachen fallen mir da ein: ein Proxy und der Browser-Cache. Beim Proxy habe ich Zweifel, denn der andere Server, mit dem du deine erste Kontrolle vorgenommen hast, wird keinen Proxy im Weg haben. Beim Browser-Cache dürfte eigentlich keine Ausgabe von livehttpheaders zu sehen sein. Ergo: ich hab grad keine Ahnung, was die Ursache sein könnte.

              Wenn ich die Ausgabe nun aber wieder unterdrücke, wird wieder HTML als Mime-Type angezeigt. Ist das irgendeine wirre Serverkonfiguration?

              Kannst du die Server-Konfiguration anschauen, speziell die betreffende VHost-Konfiguration und die Verzeichnis-Konfigurationen (.htaccess)?

              dedlfix.

            2. Wenn ich mir mittels print_r(Heiders_list()) anzeigen lassen, welche Header an den Client geschickt werden sollen, erscheint der Content-Type richtig:
              [4] => Content-Type: application/zip

              Wenn ich die Ausgabe nun aber wieder unterdrücke, wird wieder HTML als Mime-Type angezeigt.

              Vielleicht habe ich dich falsch verstanden, aber das eine hat mit dem anderen erstmal nichts zu tun. print_r(headers_list()) gibt aus, was PHP zu senden gedenkt. Das muss aber nicht zwangsläufig das sein, was der Browser empfängt, denn dazwischen hängt mindestens der Webserver.

              Wie dem auch sei, bei solchen unerklärlichen Geschichten ist es ratsam, ganz von vorne anzufangen. Erstelle eine neue PHP-Datei header.php mit folgendem Inhalt:

              <?php
              header("Content-Type: bla/fasel");
              ?>
              Blafasel

              In diesem Skript ist nur das Allernötigste drin, um das Problem einzugrenzen. Rufe es mit wget --server-response --output-document=- http://dein.example.com/header.php auf.

              Kommt was anderes als

              HTTP/1.1 200 OK
              Content-Type: bla/fasel
              [weitere Daten]

              Blafasel

              wende dich an deinen Hoster. Funktioniert's hingegen, baue das Testskript Schritt für Schritt zum Ziel aus. Schreibe erst HTML-Code statt Blafasel. Bleibt es bei bla/fasel, ändere die Content-Type-Zeile in application/zip. Empfängst du application/zip, sende eine Datei (vorher --output-document entfernen). Und so weiter.

              1. Vielleicht habe ich dich falsch verstanden, aber das eine hat mit dem anderen erstmal nichts zu tun. print_r(headers_list()) gibt aus, was PHP zu senden gedenkt. Das muss aber nicht zwangsläufig das sein, was der Browser empfängt, denn dazwischen hängt mindestens der Webserver.

                Das wusste ich nicht. Vielen Dank.

                In diesem Skript ist nur das Allernötigste drin, um das Problem einzugrenzen. Rufe es mit wget --server-response --output-document=- http://dein.example.com/header.php auf.

                Der Tipp war Gold wert. Letztenendes lag das Problem am Joomla-Framework. Hier also die Lösung für einige, die auf diesen Thread stoßen mögen. Selbst beim format=raw wird standardmäßig als Mime-Encoding text/html benutzt. Möchte man das ändern, um so z. B. Downloads anzubieten, ist folgender Code nötig:

                $doc =& JFactory::getDocument();  
                $doc->setMimeEncoding('application/zip');  
                
                

                Danke an alle, die mitgeholfen haben!

                --
                Science flies you to the moon.
                Religion flies you into buildings.
                selfcode: ie:{ fl:| br:^ va:? ls:< fo:{ rl:( n4:{ ss:} de:[ js:} ch:{ sh:) mo:? zu:)
                1. Hi,

                  Letztenendes lag das Problem am Joomla-Framework.

                  Dass du dieses verwendest, hast du uns ja auch leider zuvor verschwiegen.

                  MfG ChrisB

                  --
                  RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                  1. Letztenendes lag das Problem am Joomla-Framework.

                    Dass du dieses verwendest, hast du uns ja auch leider zuvor verschwiegen.

                    Das war doch offensichtlich …

                    Hier der Code:
                    defined('_JEXEC') or die('Restricted access');

                    … wenn man nicht nur genau hinguckt, sondern im Geiste auch hinterfragt :)