Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP5][HTTP_Request2] Przy pobieraniu pliku, gubi pakiety danych
Forum PHP.pl > Forum > PHP
matix
Cześć,

Słuchajcie, do zrobienia mam skrypt który pobiera mi pliki mp3 z danego URL-a. Problem jest jednak taki, że nie mogę do tego wykorzystać standardowo nagłówków + readfile, tylko muszę jeszcze wykonać zapytanie z paroma ciasteczkami. Dlatego też wykorzystałem do tego Http Request2. Wszystko działa super, jednak gdy odpalam track po pobraniu, to jego jakość jest fatalna - tak jakby gubił połowę danych.


TrackPeer.php - model, który odpowiada za inicjowanie downloadu
  1. static public function doInitDownload($track)
  2. {
  3. include 'HTTP/Request2.php';
  4. include 'frontend/libs/tracks/observer.php';
  5.  
  6. $url = sprintf('someTrackUrl/%s/...' , $track->getTrackRemoteId());
  7.  
  8. $request = new HTTP_Request2($url);
  9. $request->setConfig(array(
  10. 'follow_redirects' => true,
  11. 'store_body' => false
  12. ));
  13.  
  14. $response = $request->send();
  15.  
  16. foreach ($response->getCookies() as $arCookie) {
  17. $request->addCookie($arCookie['name'], $arCookie['value']);
  18. }
  19.  
  20. $request->attach(new HttpRequestTracksObserver());
  21.  
  22. Download::getRequestHeaders($track->getTrackTitle() . '.mp3', null, 'audio/x-mp3');
  23.  
  24. $request->send();
  25.  
  26. die();
  27. }


Funkcja Download::getRequestHeaders():
  1. static public function getRequestHeaders($title = '', $size = NULL, $mime = 'application/octet-stream')
  2. {
  3. header('Content-Description: File Transfer');
  4. header('Content-Type: ' . $mime);
  5.  
  6. if ($size)
  7. {
  8. header('Content-Length: ' . $size);
  9. }
  10.  
  11. header('Content-Disposition: attachment; filename=' . $title);
  12. header('Content-Transfer-Encoding: binary');
  13. header('Expires: 0');
  14. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  15. header('Pragma: public');
  16. }


Teraz najważniejsza rzecz, czyli klasa HttpRequestTracksObserver:
  1.  
  2. <?php
  3.  
  4. class HttpRequestTracksObserver implements SplObserver
  5. {
  6.  
  7. public function update(SplSubject $subject)
  8. {
  9. $event = $subject->getLastEvent();
  10.  
  11. switch ($event['name'])
  12. {
  13. case 'receivedBodyPart':
  14. case 'receivedEncodedBodyPart':
  15.  
  16. echo $event['data'];
  17. flush();
  18. break;
  19. }
  20.  
  21. }
  22.  
  23. }


Jeżeli ktoś ma w tym doświadczenie i wie, dlaczego tak się dzieje, to bardzo proszę o pomoc.

Dzięki,
Mateusz.

=== EDIT ===
Już ogarnąłem ! Warto wykorzystać jednak readfile() + stream_context_create() !

  1. static public function doInitDownload($track)
  2. {
  3. include 'HTTP/Request2.php';
  4.  
  5. $url = '... mp3 path';
  6.  
  7. $request = new HTTP_Request2($url);
  8. $request->setConfig(array(
  9. 'follow_redirects' => true,
  10. 'store_body' => false
  11. ));
  12.  
  13. $response = $request->send();
  14. $session = end($response->getCookies());
  15.  
  16. $opts = array(
  17. 'http' => array(
  18. 'header' => 'Cookie: session=' . $session['value']
  19. )
  20. );
  21.  
  22. Download::remote($url, $track->getTrackTitle() . '.mp3', (substr($track->getTrackSize(), 0, -3) * 1024 * 1024), 'audio/x-mp3', $opts);
  23. }


  1. static public function Remote($url, $title = '', $size = NULL, $mime = 'application/octet-stream', $opts = array())
  2. {
  3. $title = $title ? $title : basename($url);
  4.  
  5. header('Content-Description: File Transfer');
  6. header('Content-Type: ' . $mime);
  7.  
  8.  
  9. if ($size)
  10. {
  11. header('Content-Length: ' . $size);
  12. }
  13.  
  14. header('Content-Disposition: attachment; filename=' . $title);
  15. header('Content-Transfer-Encoding: binary');
  16. header('Expires: 0');
  17. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  18. header('Pragma: public');
  19.  
  20. flush();
  21.  
  22. if ($opts)
  23. {
  24. readfile($url, false, stream_context_create($opts));
  25. }else{
  26. readfile($url);
  27. }
  28.  
  29. }


Mam nadzieję, że komuś się przyda biggrin.gif
wNogachSpisz
Swego czasu wiązałem spore nadzieje ze strem_content.
Niestety, to działa jak chce, zwyczajnie, na niektórych konfiguracjach nie jest wysyłany żaden zadany nagłowek..
Czytaj, Twoje:
  1. $opts = array(
  2. 'http' => array(
  3. 'header' => 'Cookie: session=' . $session['value']
  4. )
  5. );

któregoś malowniczego dnia nie zadziała, nie wyśle nagłowka cookie.
Możliwe że temat wyczerpuje ten bug:
http://pl.php.net/manual/en/function.strea...eate.php#100559
Niestety pewności nie ma, a ja potrzebuje rozwiązań pewnych.

Używam PEAR:HTTP_Requert z dołączonym PEAR:HTTP_Cookie_Menager.
Nie pamiętam dlaczego nie używam HTTP_Requert2, ale pamiętam że była to decyzja świadoma poparta argumentami nie do przemilczenia, dlatego polecam Ci zrobić to samo- skorzystać z bibliteki HTTP_Requert ale w wersji #1 http://pear.php.net/package/HTTP_Request/
matix
Okej, ogarnę to. Widzę, że też tu jest HTTP_Request_Listener na którym prawdę mówiąc najbardziej mi tutaj zależy. Chociaż to rozwiązanie co ja mam, też dziala - zauważ, że wpierw korzystam z HTTP Request2 aby pobrać Cookie, potem dopiero korzystam z steam_context_create.

P/MN.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.