MonsieurBon: HTTP Header fuer file download

Hallo zusammen

Etwas, worüber ich immer wieder stolpere (ob nun mit Perl oder PHP) und zudem ich noch keine zufriedenstellende Antwort gekriegt habe, ist die Frage wie ein HTTP Header für einen File download aussehen sollte. Und zwar in dem Fall, in welchem ich nicht weiss, was für eine Art File der Benutzer anfordert. Bis jetzt verwende ich folgenden Header:

Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Length: $output_size
Content-Disposition: attachment;filename=$file

$output_size enthält die Filegröße und $file den Filenamen. Das File gebe ich dann jeweils mit echo/print o.ä. aus.

Wie gut/schlecht ist diese Header Wahl?

  1. Hallo,

    Content-Type: application/octet-stream
    Content-Transfer-Encoding: binary
    Content-Length: $output_size
    Content-Disposition: attachment;filename=$file

    $output_size enthält die Filegröße und $file den Filenamen. Das File gebe ich dann jeweils mit echo/print o.ä. aus.

    Wie gut/schlecht ist diese Header Wahl?

    für den Fall, dass du dich nicht um die Beschaffenheit der gelieferten Daten kümmern willst, und dass der Client das ebenfalls nicht tun muss, sondern die gelieferte Ressource einfach als Datei speichern soll - dann ist das IMHO das Beste, was du tun kannst.
    Du solltest nur noch sicherstellen, dass $file einen gültigen Dateinamen enthält; da du das Zielsystem und dessen Einschränkungen nicht kennst, beschränke dich am besten auf [0-9a-z].

    Ciao,
     Martin

    --
    Irgendwann in grauer Vorzeit benutzte einer unserer prähistorischen Vorfahren ein Schimpfwort anstelle der Keule.
    Die Zivilisation hatte begonnen.
    1. Hallo Martin

      für den Fall, dass du dich nicht um die Beschaffenheit der gelieferten Daten kümmern willst, und dass der Client das ebenfalls nicht tun muss, sondern die gelieferte Ressource einfach als Datei speichern soll - dann ist das IMHO das Beste, was du tun kannst.

      Das waere die Idee. Der MIME-Type einer Datei kann doch sowieso nicht mit letzter Sicherheit festgestellt werden, oder?

      Du solltest nur noch sicherstellen, dass $file einen gültigen Dateinamen enthält; da du das Zielsystem und dessen Einschränkungen nicht kennst, beschränke dich am besten auf [0-9a-z].

      Das wird natuerlich bereits beim upload der Datei ueberprueft! :-)

      Gruss
      Fabian

      1. Das waere die Idee. Der MIME-Type einer Datei kann doch sowieso nicht mit letzter Sicherheit festgestellt werden, oder?

        Richtig, aber man kann darauf schließen und besonders wenn du die Datei dem Besucher anbietest, solltest du deren Eigenschaften kennen (oder zumindst Serverseitig auswerten können).

        1. Richtig, aber man kann darauf schließen und besonders wenn du die Datei dem Besucher anbietest, solltest du deren Eigenschaften kennen (oder zumindst Serverseitig auswerten können).

          Kennen nicht, da die Dateien von anderen Usern bereitgestellt werden. Auswerten waere eine Moeglichkeit.

          Muesste ich im Header nur den MIME-Type aendern?

          Gruss
          Fabian

          1. Muesste ich im Header nur den MIME-Type aendern?

            Ansich ja, aber als reiner Datenstrom ist das - wie Martin sagt - ansich auch ok, sofern du den MIME-Type nicht micht Sicherheit bestimmen kannst.

      2. Hallo Fabian,

        Der MIME-Type einer Datei kann doch sowieso nicht mit letzter Sicherheit festgestellt werden, oder?

        nein, er wird normalerweise festgelegt, indem eine Seite sagt: So sei es.
        Ein HTML-Dokument kann der Webserver auch mit dem MIME-Typ text/plain liefern; ein folgsamer Client sollte daraufhin den Quellcode auch als reinen Text anzeigen, auch "wenn er es besser weiß". Der IE neigt beispielsweise dazu, den MIME-Typ zu ignorieren, wenn er glaubt, das Dateiformat erkannt zu haben, und stellt auch als text/plain gelieferten Code als HTML dar, wenn er aussieht wie HTML.
        Es gibt einige Fälle dieser Art, wo verschiedene Interpretationen einer Datei/Ressource möglich sind, daher kann man höchstens *einen* MIME-Typ bestimmen, der zu den Daten passen könnte - das muss aber nicht der Typ sein, den der Absender gemeint hat.

        In deinem Fall kommt dazu, dass du ja *gar nicht willst*, dass die Daten vom Client überhaupt interpretiert werden. Er soll sie speichern und gut. Dafür ist der unspezifische MIME-Typ application/octet-stream genau richtig.

        Du solltest nur noch sicherstellen, dass $file einen gültigen Dateinamen enthält; da du das Zielsystem und dessen Einschränkungen nicht kennst, beschränke dich am besten auf [0-9a-z].
        Das wird natuerlich bereits beim upload der Datei ueberprueft! :-)

        Ja, aber denke daran, dass das Internet heterogen ist. Während dein vermutlich Linux-basierter Webserver meint, ein Dateiname mit einem Doppelpunkt sei okay, wird ein Windows-Client damit Schwierigkeiten haben. Deshalb habe ich empfohlen, an dieser Stelle so restriktiv wie möglich zu prüfen.
        Natürlich muss diese Überprüfung schon beim Upload stattfinden; wenn du sicher sein kannst, dass keine Dateien aus anderen Quellen dazukommen, kannst du beim Download eventuell drauf verzichten. Aber es tut ja nicht weh, den Namen sicherheitshalber nochmal zu checken; vielleicht hat in der Zwischenzeit jemand (du selbst?) per FTP eine Datei hochgeladen und so deine Prüfung umgangen.

        So long,
         Martin

        --
        Die letzten Worte des Systemadministrators:
        Nur gut, dass ich ein intaktes Backup habe.