CRôW1: Video über 404, PHP, Session und Readfile erzeugen

Hallo liebes Selfhtml-Forum,

eine etwas komplexere Frage:

ich baue ein Programm, das auf dem Abfangen von 404-Fehlermeldungen basiert. Jeder Aufruf wird von einer PHP-Datei (Errordocument 404) geprüft und dem User entsprechende Inhalte angezeigt, entweder HTML-Seiten oder Bilder, welche über ReadFile aus einem anderen Teil des Servers hergeholt werden. Dabei wird über Session geprüft, ob der User Berechtigung hat, die Seite oder die Bilder zu sehen.

Wenn ich nun auf die gleiche Weise ein WMV-Video erzeugen bzw. herholen möchte, das im Mediaplayer "gepuffert" werden soll, so geht diese Pufferung immer schief. (Der Download bei Header('content-disposition: attachment') funktioniert!)

Ich schicke für die Wiedergabe (NICHT den Download) folgende Header:

  
header("Status: 200 OK");  
header("HTTP/1.1 200 OK");  
$etag = md5_file($Absolute_Adresse_Des_Videos);  
$last_modified_time = filemtime($Absolute_Adresse_Des_Videos);  
header('Cache-Control: max-age');  
header('Pragma: public');  
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");  
header("Etag: $etag");  
header('Accept-Ranges: bytes');  
header('Content-Length: '. filesize($Absolute_Adresse_Des_Videos));  
header('Content-Type: video/x-ms-wmv');

und schließlich

  
readfile($Absolute_Adresse_Des_Videos);

Ohne Session führen diese Header zu einem perfekten Ergebnis: Ein Video, das vom Mediaplayer gleich einem "original" Video gepuffert wird.
Wenn ich jedoch dabei vor den Headern die Session aktiviere, um die Berechtigung zu prüfen, so schafft der Mediaplayer nicht mal eine Verbindung zu dem Video herzustellen.

Gibt es vllt. eine Möglichkeit, die Sessiondaten abzufragen, ohne den Header zu beeinflussenen? Gibt es andere Header, mit denen ich die Veränderungen durch die Session rückgängig machen kann? Oder andere Möglichkeiten?

Vielen Dank für euer Mitdenken und euren Rat!

  1. Moin!

    Ohne Session führen diese Header zu einem perfekten Ergebnis: Ein Video, das vom Mediaplayer gleich einem "original" Video gepuffert wird.
    Wenn ich jedoch dabei vor den Headern die Session aktiviere, um die Berechtigung zu prüfen, so schafft der Mediaplayer nicht mal eine Verbindung zu dem Video herzustellen.

    Klingt logisch: Der Mediaplayer ist ein anderer Client, als der bisher vom User benutzte Browser, und er kennt selbstverständlich dessen Cookies nicht. Also schickt er kein Sessioncookie mit, und deine Sessionprüfung läuft zwangsläufig ins Leere.

    - Sven Rautenberg

    1. Klingt logisch: Der Mediaplayer ist ein anderer Client, als der bisher vom User benutzte Browser, und er kennt selbstverständlich dessen Cookies nicht. Also schickt er kein Sessioncookie mit, und deine Sessionprüfung läuft zwangsläufig ins Leere.

      Aber mit session_open müßte die Session-ID doch übernommen werden, oder? *grübel* -> Nein, quark, weil der Cookie die ID ja nicht mitschickt.

      Es geht aber auch dann nicht, wenn ich die Session-ID in der URL übergebe und von dort Auslese und über session_id an die Session weiterreiche (vor dem session_open natürlich).

      Mein Erklärungsansatz geht dahin, dass der Mediaplayer das Video nicht puffern bzw. nicht erreichen kann, weil session_open die Header-Daten unleserlich macht.

      1. Hi,

        Es geht aber auch dann nicht, wenn ich die Session-ID in der URL übergebe und von dort Auslese und über session_id an die Session weiterreiche (vor dem session_open natürlich).

        Du meinst wohl session_start.

        Mein Erklärungsansatz geht dahin, dass der Mediaplayer das Video nicht puffern bzw. nicht erreichen kann, weil session_open die Header-Daten unleserlich macht.

        Dann gewoehne der Session ab, eigene Header zu erzeugen.
        Also insb. Benutzung von Cookies deaktivieren, und die Angaben zum Caching auf geeignetere Werte setzen.

        Wenn auch das noch nichts hilft, dann koennte man noch ueber den zweiten Parameter von header versuchen, fuer das Vorhaben unguenstige Header-Werte wieder zu ueberschreiben.

        Welche das sind, dazu sollte man dann mal schauen, welche Header bei der Session-Variante erzeugt werden, mit einem entsprechenden Browser-Plugin o.ae.

        Und was sicher auch noch empfehlenswert sein duerfte, wenn du grosse Datenmengen (Videodaten) aus einem Script heraus ausgeben willst - session_write_close aufrufen, nachdem die Berechtigung zum Aufruf der Ressource geprueft wurde. Andernfalls wird naemlich die Datendatei der Session so lange offen gehalten und damit fuer andere Scriptinstanzen gesperrt, wie dein Script laeuft.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
        1. Welche das sind, dazu sollte man dann mal schauen, welche Header bei der Session-Variante erzeugt werden, mit einem entsprechenden Browser-Plugin o.ae.

          Gänzlich unmodifiziert gibt das Script diese Header aus.

          HTTP/1.1 200 OK
          Date: Fri, 06 Feb 2009 14:20:48 GMT
          Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch13 mod_ssl/2.2.3 OpenSSL/0.9.8c
          X-Powered-By: PHP/5.2.0-8+etch13
          Set-Cookie: PHPSESSID=e2c04c1ef089e00e2869e6097831dceb; path=/
          Expires: Thu, 19 Nov 1981 08:52:00 GMT
          Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
          Pragma: no-cache
          Transfer-Encoding: chunked
          Content-Type: text/html

          Entscheidend sind dabei wohl die Header Expires, Chache-Control und Pragma.

          Nach meiner Modifikation kommen die folgenden Header:

          HTTP/1.1 200 OK
          Date: Fri, 06 Feb 2009 14:25:07 GMT
          Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch13 mod_ssl/2.2.3 OpenSSL/0.9.8c
          X-Powered-By: PHP/5.2.0-8+etch13
          Set-Cookie: PHPSESSID=54bf3c45f375e8fb1e61ac1bc5b92814; path=/
          Expires: Thu, 19 Nov 1981 08:52:00 GMT
          Cache-Control: max-age
          Pragma: public
          Last-Modified: Tue, 03 Feb 2009 08:26:33 GMT
          Etag: 46d24ac240c5b25e7fbd855f5c67357d
          Accept-Ranges: bytes
          Content-Length: 90461690
          Content-Type: video/x-ms-wmv

          Die Header einer "normalen" WMV-Datei sehen so aus:

          HTTP/1.1 200 OK
          Date: Fri, 06 Feb 2009 18:26:29 GMT
          Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch13 mod_ssl/2.2.3 OpenSSL/0.9.8c
          Last-Modified: Tue, 03 Feb 2009 08:26:33 GMT
          ETag: "125c0aa-56455fa-6dc4a040"
          Accept-Ranges: bytes
          Content-Length: 90461690
          Content-Type: video/x-ms-wmv

          Und was sicher auch noch empfehlenswert sein duerfte, wenn du grosse Datenmengen (Videodaten) aus einem Script heraus ausgeben willst - session_write_close aufrufen, nachdem die Berechtigung zum Aufruf der Ressource geprueft wurde. Andernfalls wird naemlich die Datendatei der Session so lange offen gehalten und damit fuer andere Scriptinstanzen gesperrt, wie dein Script laeuft.

          Danke für den Tipp, werde mal das Manual zu der Funktion befragen! :))

          Paar Minuten und einige Tests später:
          *schnall* Jetzt ist mir auch klar, warum manchmal ein Sessionfehler kommt, wenn ich ein Video zwei mal hintereinander aufrufe...