Ankündigung

Einklappen
Keine Ankündigung bisher.

Curl Direkten Download/Stream mit Partial Content ohne Speicherung

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Curl Direkten Download/Stream mit Partial Content ohne Speicherung

    Hallo,

    ich möchte gerne Dateien von anderen Webservern(OneClick Hoster) herunterladen und direkt an den User weiterleiten ohne das die Dateien auf meinem Server zwischen gespeichert werden. Die Dateien sind 100MB bis 1GB groß.

    Wenn man nun mit nur einem Thread herunterlädt funktioniert es aktuell mit diesem Code:

    PHP-Code:
    $ch5 curl_init();
    if (isset(
    $_SERVER['HTTP_RANGE'])) {
        
    //http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file
        
    preg_match('/bytes=(\d+)-(\d+)?/'$_SERVER['HTTP_RANGE'], $matches);
        
    $offset intval($matches[1]);
        
    $end $matches[2] || $matches[2] === '0' intval($matches[2]) : $size 1;
        
    curl_setopt($ch5CURLOPT_RANGE"$offset-$end");
    }
    curl_setopt($ch5CURLOPT_URL$direct_link);
    curl_setopt($ch5CURLOPT_TIMEOUT3550); 
    curl_setopt($ch5CURLOPT_CONNECTTIMEOUT15); 
    curl_setopt($ch5CURLOPT_HEADERFUNCTION'readHeader');
    curl_exec($ch5);
    $dlsize curl_getinfo($ch5,CURLINFO_SIZE_DOWNLOAD );
    $time curl_getinfo($ch5,CURLINFO_TOTAL_TIME);
    curl_close($ch5);

    function 
    readHeader($ch$header// Send header from the Downloaded file to the User
    {
        
    header($header);
        return 
    strlen($header);

    bzw. fast genauso mit dem curl Callback "WRITEFUNCTION".

    Das Problem ist jetzt, das Curl/PHP die Datei innerhalb von Sekunden herunterlädt und die Datei dann langsam vom Client heruntergeladen wird. Das ist bis jetzt noch nicht schlimm, aber wenn der Client in seiner Anfrage nun einen Range wie z.B. "Range: Bytes 0-/*" und somit alle Bytes vom Anfang anfragt bis er abbricht und dann noch weitere Threads startet in denen er weitere Teile anfragt bekomme ich das Problem, das dann die Datei mehrmals Komplette bzw. teile doppelt heruntergeladen werden, was jetzt nicht schön ist aber theoretisch noch funktionieren würde.
    Allerdings ist es so, das die meisten Downloads bei One-Click Hostern durchgeführt werden beidenen man die Datei nur 1 mal heruntergeladen kann und dann ist der Link nicht mehr gültig und PHP kann die Anfragen dann nicht bedienen.

    Ich benutze nginx/1.6.2 und PHP 5.5.20-1 auf Ubuntu 12.04.5

    Beim Aufruf der PHP-Datei zum Downloaden habe ich versucht alle möglichen zwischen speicher zu deaktivieren und folgende Parameter in nginx gesetzt:
    gzip off;
    fastcgi_buffering off;

    PHP in nginx:
    try_files $uri =404;
    fastcgi_pass 127.0.0.1:7777;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_read_timeout 3600;
    fastcgi_keep_conn on;
    include fastcgi_params;


    Allerdings wird noch irgendwo etwas gespeichert/gepuffert, was ich daran erkenne, das wenn ich eine Datei herunterladen und den Download Progress mit schreibe dieses Ergebnis erziele:
    1421696759.4244 - Curl Open
    1421696759.4392 - DL:0/0 UL:0/0
    1421696759.4393 - DL:0/0 UL:0/0
    1421696759.4542 - DL:1192/104857600 UL:0/0
    1421696759.4543 - DL:14224/104857600 UL:0/0
    ...
    1421696761.1123 - DL:104843632/104857600 UL:0/0
    1421696761.1125 - DL:104857600/104857600 UL:0/0
    1421696761.1126 - Curl Closed
    Der Download durch Curl und PHP dauert ca 2 Sekunden, aber bis ich die Datei auf dem Client erhalte vergeht ca eine Minute. Das heißt im Klartext, dass das PHP Script beendet ist aber noch Dateien an den Client gesendet werden.

    Ums ganz kurz zu sagen, will ich das die Daten 1:1 von den Externen Server über meinen Server an den Client gesendet werden.
    und das nirgendwo etwas gepuffert wird, damit nicht zu viel von der Datei heruntergeladen wird.
    Ich benötige allerdings das PHP-Script dazwischen, da dort eine Download-ID in den Download-Link des One-Click Hosters umgewandelt und dieser Link aus einer MySQL Datenbank abgefragt wird und die heruntergeladenen Bytes gezählt werden und die gespeichert werden.

    Ich hoffe ihr könnt mein Problem verstehen und mir weiterhelfen.


  • #2
    Ich benötige allerdings das PHP-Script dazwischen, da dort eine Download-ID in den Download-Link des One-Click Hosters umgewandelt und dieser Link aus einer MySQL Datenbank abgefragt wird und die heruntergeladenen Bytes gezählt werden und die gespeichert werden.
    durchstöbere doch mal die threads von prohet.

    Kommentar


    • #3
      Zitat von moma Beitrag anzeigen
      durchstöbere doch mal die threads von prohet.
      Ok, habe ich mir mal angeschaut.
      Die Größe der Datei aus der Logdatei auslesen ist keine schlechte Idee. So bekomme ich dann schon mal die heruntergeladene Größe.

      Ich habe nun noch folgendes hinzugefügt:
      PHP-Code:
      // Turn off output buffering
      ini_set('output_buffering''off');
      // Turn off PHP output compression
      ini_set('zlib.output_compression'false);
               
      //Flush (send) the output buffer and turn off output buffering
      //ob_end_flush();
      while (@ob_end_flush());
               
      // Implicitly flush the buffer(s)
      ini_set('implicit_flush'true);
      ob_implicit_flush(true);
       
      //prevent apache from buffering it for deflate/gzip
      header('Cache-Control: no-cache'); 
      Allerdings wird dann die heruntergeladene Datei immer noch komplett im RAM gespeichert und dann an den Client gesendet.
      Ich möchte aber nur soweit herunterladen wie der Client die Datei annimmt bis der Client abbricht.

      Darum habe ich versucht im PHP Script immer nur 10MB der Datei anzufordern und die 10MB dann an den Client weiterzuleiten. Allerdings habe ich keine Möglichkeit gefunden zu prüfen, wann der Buffer zum Client hin aufgebraucht ist und ich die nächsten 10MB anfragen sollte.

      Gibt es eine Methode diesen Buffer abzufragen?
      Mit ob_get_length bekomme ich immer nur 0 zurück, da es scheinbar irgendwo anders gespeichert wird, aber ich weiß nicht wo.

      Kommentar


      • #4
        Die Größe der Datei aus der Logdatei auslesen ist keine schlechte Idee. So bekomme ich dann schon mal die heruntergeladene Größe.
        Ich kann noch immer nicht glauben, dass das der geschickteste Weg ist, wenn man doch selbst direkt im Code mit der curl-Lib arbeitet.

        Für mich hat das was von: Man sitzt live im Stadion, schaut aber nicht aufs Spielfeld, sondern liest den Internet-Liveticker auf dem Smartphone.

        Kommentar


        • #5
          Zitat von mermshaus Beitrag anzeigen
          Ich kann noch immer nicht glauben, dass das der geschickteste Weg ist, wenn man doch selbst direkt im Code mit der curl-Lib arbeitet.

          Für mich hat das was von: Man sitzt live im Stadion, schaut aber nicht aufs Spielfeld, sondern liest den Internet-Liveticker auf dem Smartphone.
          Ja, ich finde die Methode auch nicht schon. Aktuell lese ich die Größe auch über
          den Parameter CURLINFO_SIZE_DOWNLOAD aus. Das ist denke ich eine bessere Lösung. Allerdings ist es wieder die Größe die heruntergeladen wurde und nicht die, die an den Client gesendet wurde.

          Kommentar


          • #6
            Ich habe es jetzt so gelöst, dass ich die Dateien kurzzeitig bei mir auf dem Server speichere und sie dann beim ersten Aufruf herunterlade und an den Client sende und auf dem Server speichere, falls dann noch weitere Anfragen kommen wird die Datei genutzt die auf der Platte ist.

            Kommentar


            • #7
              Zitat von yannik995 Beitrag anzeigen
              Ich habe es jetzt so gelöst, dass ich die Dateien kurzzeitig bei mir auf dem Server speichere und sie dann beim ersten Aufruf herunterlade und an den Client sende und auf dem Server speichere, falls dann noch weitere Anfragen kommen wird die Datei genutzt die auf der Platte ist.
              was hast du denn für ein quotas?

              Kommentar


              • #8
                Zitat von moma Beitrag anzeigen
                was hast du denn für ein quotas?
                Ich habe einen Root 8Kerne 8GB Ram und 2 VServer, also Hardware sollte dafür genug vorhanden sein.

                Kommentar


                • #9
                  hab da nichts von quotas explizit an die 8 exbibytes byteplatte gelesen-> no.

                  Kommentar


                  • #10
                    Oh ja, die Info ist auch ganz hilfreich

                    Der Root besitzt eine 1TB Platte und die vServer jeweils 100GB

                    Und ich mache es nun so dass die Dateien nach einer Stunden gelöscht werden und so komme ich aktuell ganz gut zurecht.

                    Kommentar

                    Lädt...
                    X