MrSchmidtdtdtdt: fopen mit externer url?

"allow_url_fopen" ist aktiviert. Weshalb funktioniert ein Aufruf mit "small.mp4", jedoch nicht "http://www.beispie.de/small.mp4"?

<?
$root=getenv("DOCUMENT_ROOT");
$file = "small.mp4";
header("Content-Type: video/mp4");
//header("Content-Type: application/octet-stream"); // downloads the file

$start=0;
$size = filesize($file);
$length = $size;
$end = $size - 1;

//header('HTTP/1.1 206 Partial Content');
header("Accept-Ranges: $start-$end");
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: $length");


$data = fopen("$file", "r");
fseek($data, $start);

$bytesleft = $size-$start + 1;
$buffer = 1024 * 256; // 256kb
while(!feof($data)){
    if($bytesleft > $buffer){
        echo fread($data, $buffer);
        flush();
    }else{
        echo fread($data, $bytesleft);
        flush();
    }
    //sleep(1);  // Speedlimit = one buffer per second
}


fclose($data);
exit;
?>
  1. Tach,

    "allow_url_fopen" ist aktiviert. Weshalb funktioniert ein Aufruf mit "small.mp4", jedoch nicht "http://www.beispie.de/small.mp4"?

    der erste Gedanke war, dass http://www.beispie.de/small.mp4 einen 404 liefert, aber das war vermutlich nur als Beispiel gedacht; dafür gibt es die reservierten Beispieldomains. Wird von fopen ein Warning ausgegeben (ist das error_reporting passend gesetzt, so dass warnings auch ausgegeben werden)? Steht in $data ein Stream drin oder vielleicht FALSE, weil das fopen fehlgeschlagen ist?

    mfg
    Woodfighter

    1. Hi!

      Wird von fopen ein Warning ausgegeben (ist das error_reporting passend gesetzt, so dass warnings auch ausgegeben werden)? Steht in $data ein Stream drin oder vielleicht FALSE, weil das fopen fehlgeschlagen ist?

      Nein.. tatsächlich wird alles korrekt geladen, wie mir scheint. Der Stream startet bloß nicht. Hier ein Beispiel: http://goo.gl/jGtZZM

      1. Moin,

        Nein.. tatsächlich wird alles korrekt geladen, wie mir scheint. Der Stream startet bloß nicht. Hier ein Beispiel: http://goo.gl/jGtZZM

        Evtl. liegt hier der Hund begraben:

        $size=filesize($path);
        

        Ich glaube nicht, dass filesize sich auf URLs anwenden lässt (jedenfalls nicht so, wie Du es vermutlich erwartest, also dass Du die Größe des Videos zurück bekommst).

        Viele Grüße, Jörg

      2. Tach,

        Hier ein Beispiel: http://goo.gl/jGtZZM

        filesize($path) dürfte wohl FALSE sein, da in deinem Filesystem vermutlich keine Datei mit diesem Namen existiert (auch das sollte übrigens ein Warning ausgeben) und ein Video mit "Content-Length: 0" ist ziemlich schnell vorbei.

        mfg
        Woodfighter

        1. Hi,

          filesize($path) dürfte wohl FALSE sein, da in deinem Filesystem vermutlich keine Datei mit diesem Namen existiert

          Daß das probiert wird mit dem filesize ist m.E. eine direkte Folge der PHP-Vermischung von file- und http-Funktionalität ...

          Gäbe es für den http-Zugriff eigene Funktionen statt des Mißbrauchs der File-Funktionen, wäre dieses Problem vermutlich gar nicht erst aufgetaucht ...

          cu,
          Andreas a/k/a MudGuard

          1. Tach,

            Gäbe es für den http-Zugriff eigene Funktionen statt des Mißbrauchs der File-Funktionen, wäre dieses Problem vermutlich gar nicht erst aufgetaucht ...

            die wirre Entstehungsgeschichte für PHP lässt halt an diversen Stellen anmerken, dass es nicht darum ging eine geplante Sprache zu entwickeln, sondern eher darum Funktionalität schnell zur Verfügung zu stellen.

            mfg
            Woodfighter

    2. Hallo und guten Abend,

      nur so nebenbei:
      Bestimmt nicht der Server bei HTTP 1.1 Chunked Content, wie groß die Stücke werden?
      Und dann müsste man auch erst einmal gucken, ob er überhaupt einen chunked-Header gesendet hat.

      Ich vermute hier, dass die Firewall des Webserver-Hosts keine ausgehenden HTTP-Requests zulässt.

      Grüße
      TS

  2. Hallo und guten Morgen,

    "allow_url_fopen" ist aktiviert. Weshalb funktioniert ein Aufruf mit "small.mp4", jedoch nicht "http://www.beispie.de/small.mp4"?

    Funktioniert der HTTP OUT grundsätzlich nicht? Mal nur mit einem file_get_contents() getestet? Eigener Server? Oder welcher Hoster?

    Ich vermute dann mal, die Firewalleinstellungen lassen keinen HTTP-Requests von innen nach außen zu. Ist bei den meisten kleinen Pakten sogar häufig die Grundeinstellung.

    Grüße
    TS

  3. Hallo,

    "allow_url_fopen" ist aktiviert. Weshalb funktioniert ein Aufruf mit "small.mp4", jedoch nicht "http://www.beispie.de/small.mp4"?

    also ein bisschen Debugging könntest du ruhig selbst betreiben. Zum Beispiel die Rückgabewerte der diversen Funktionen auswerten, die du verwendest. Dann könntest du das Problem systematisch eingrenzen.

    Ich bin mir aber ziemlich sicher, dass Jörg schon auf der richtigen Fährte ist.

    Denn wenn schon gnädigerweise der Zugriff auf HTTP-Ressourcen auch über die File-Funktionen emuliert wird, darf man dennoch nichts Unmögliches verlangen oder erwarten.

    $size = filesize($file);
    
    $data = fopen("$file", "r");   // was soll der Unfug, eine einzelne Stringvariable nochmal
                                   // in einen String einzubetten? Immer wieder ...
    fseek($data, $start);
    

    Okay, fopen() mag gelingen, das habe ich nur wegen der unsinnigen Notation stehenlassen.

    Mit filesize() geht's aber schon los: Das wird über den HTTP-Wrapper fehlschlagen, weil der kein stat() unterstützt. Könntest du daran erkennen, dass filesize() FALSE liefert und eine Warning schmeißt.

    Ähnlich schlecht wird es vermutlich mit fseek() aussehen, obwohl ich da keine klare Aussage finde. Aber vermutlich liefert fseek() in deinem Fall auch -1 und zeigt damit den Fehlschlag der Operation an.

    So long,
     Martin

  4. Danke für alle Antworten. Tatsächlich gibt es Probleme mit filesize & fseek. Welche Optionen bieten sich am ehesten an, um das gewünschte Verhalten zu erzielen?

    1. Tach,

      Danke für alle Antworten. Tatsächlich gibt es Probleme mit filesize & fseek. Welche Optionen bieten sich am ehesten an, um das gewünschte Verhalten zu erzielen?

      du kannst die nötigen Infos aus dem HTTP-Header ($http_response_header) auslesen oder du benutzt etwas anderes als fopen für deinen HTTP-Request.

      mfg
      Woodfighter

      1. Hallo und guten Morgen,

        Danke für alle Antworten. Tatsächlich gibt es Probleme mit filesize & fseek. Welche Optionen bieten sich am ehesten an, um das gewünschte Verhalten zu erzielen?

        du kannst die nötigen Infos aus dem HTTP-Header ($http_response_header) auslesen oder du benutzt etwas anderes als fopen für deinen HTTP-Request.

        Nicht unbedingt. Bei Chunked Übertragung gibt es ggf. keine Content-Length am Stück, sondern immer nur die des nächsten Paketes. Und da hängt dann hinten die nächste Längenangabe dran.

        Grüße
        TS

    2. Hallo und guten Abend,

      Tatsächlich gibt es Probleme mit filesize & fseek. Welche Optionen bieten sich am ehesten an, um das gewünschte Verhalten zu erzielen?

      diskret aufbauen mit fsockopen und fopen und dann die Errors und die Timeouts auch alle auswerten und benutzen.

      Aber vorher testen, ob Du auf deinem Server überhaupt Socket-Zugriffe NACH DRAUßEN durchführen darfst. Dazu musst Du ja nicht den Stream nehmen, sondern erst einmal eine normale Datei.

      Und wenn Du hier suchst in den älteren Threads oder im Archiv (ist noch nicht lange her), dann findest Du auch noch eine angefangene Lösung für den chunked Download, auch wenn der Server Dir zuerst eine Umleitung schickt...

      Grüße
      TS

    3. Tach!

      Welche Optionen bieten sich am ehesten an, um das gewünschte Verhalten zu erzielen?

      readfile(), wenn du auf die Dateilängenangabe verzichtest.

      dedlfix.