Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 13-10-2008 13:24:57

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

[Résolu] Action Téléchargement de fichier

Bonjour,

J'ai besoin d'autres yeux sur mon code parce que je ne vois pas le problème smile

J'essaie d'envoyer au client un fichier exe dans une action de controller.

Le fichier envoyé fait bien la bonne taille, je peux l'enregistrer, mais il ne fonctionne pas, c'est un exe, donc fenêtre noire et rien du tout.

Si je télécharge le fichier directement depuis le ftp, il fonctionne très bien.

Mon action :

Code:

function downloadAction() 
  {    
      $this->_helper->viewRenderer->setNoRender();
      
      if (isset($this->getRequest()->fn)) {
          if (eregi($this->getRequest()->fn,$this->user->servicesautorises)) {
                              
              $f_name = $this->getRequest()->fn . '-Installer.exe';
                $f_location = Zend_Registry::get('config')->download->src_download_root . '/' . $f_name;
        
                header('Content-Disposition: attachment; filename='.$f_name.';');
                header('Content-Type: application/octet-stream');        
                header('Content-Transfer-Encoding: binary\n');
                header('Content-Length: ' . filesize($f_location));
                header('Pragma: no-cache');
                header('Cache-Control: must-revalidate, post-check=0, pre-check=0, public');
                header('Expires: 0');        
                readfile($f_location);
          }
          else {
              $this->_redirect('/');          
          }
      }
  }

Une idée ? ou une meilleure méthode peut-être ?

Merci.

A+ benjamin.

Dernière modification par Delprog (14-10-2008 00:40:23)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#2 13-10-2008 14:38:23

gauthier
Membre
Date d'inscription: 30-09-2008
Messages: 116
Site web

Re: [Résolu] Action Téléchargement de fichier

salut Benjamin,

quelques questions pour mieux comprendre ce qui se passe :

n'aurais-tu pas d'envoi de headers quelconques avant de dumper ton fichier ?
Es-tu sûr que le fichier fait exactement la même taille au départ et à l'arrivée ?
As-tu fait un md5 avant et après l'envoi pour contrôler l'intégrité de ton fichier durant le transfert ?

Enfin, peux-tu m'éclairer sur cette "fenêtre noire" ? Je ne comprends pas bien ; si ton fichier est corrompu, une erreur devrait être générée lors de l'exécution...


Consultant Zend Technologies // Blog perso : Logiciel libre et développement web -- http://freeblogware.org

Hors ligne

 

#3 13-10-2008 15:16:03

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

Salut smile

Non je n'ai aucun envoi de header avant puisque le seul traitement que je maitrise avant l'appel de l'action c'est mon bootstrap, qui ne fait donc aucun envoi de "header" (encore heureux :p)

J'ai un plugin pour la route, mais idem, il n'envoie surtout pas de header.


Sinon le fichier téléchargé et le fichier d'origine font exactement la même taille d'après les propriétés de windows, mais ne sont pas les mêmes. Si je regarde dans les propriétés de chacun, j'ai une différence dans l'onglet "Archive".

Fichier d'origine :

SFX ZIP archive (Mais c'est bien un exe hein)
Version à extraire                                   2.0
Système d'exploitation hôte            Windows
Nombre total de fichiers                           21
Longueur totale                          11 303 589
Longueur compressée                  4 708 810
Taux                                                     41%

Taille du module SFX                         34 324
Commentaire principal                        Absent
Mots de passe                                    Absent


Fichier téléchargé :

SFX ZIP archive (Mais c'est bien un exe hein)
Version à extraire                                    2.0
Système d'exploitation hôte                    DOS

Nombre total de fichiers                            20
Longueur totale                           11 303 433
Longueur compressée                   4 708 676
Taux                                                     41%

Taille du module SFX                         34 107
Commentaire principal                        Absent
Mots de passe                                    Absent


Donc visiblement il n'arrive pas entier smile Mais je ne sais pas d'où ça peut venir...

Pour la "Fenêtre noire" j'ai eu un élan de neuneu pour pondre cette expression. Il s'agit biensûr d'une fenêtre DOS. Si j'exécute l' exe en command pour voir le message j'ai :

Code:

Program too big to fit in memory

Voilà smile

A+ benjamin.

Dernière modification par Delprog (13-10-2008 15:21:14)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#4 13-10-2008 17:03:21

ichevc02
Membre
Date d'inscription: 25-07-2007
Messages: 127

Re: [Résolu] Action Téléchargement de fichier

essaie au lieu de readfile :

Code:

$this->_response->clearBody(); //efface le body de la reponse (aucas ou ..)
$chaine = file_get_contents(<monFichier>); // recupere le contenu du fichier
$taille = strlen($chaine); // recupere la taille
$this->_response->setBody($chaine);


//puis dans les headers :
$this->_response->setHeader('Content-Length',$taille,true); //header avec la taille du fichier

c'est juste une idee comme ca sans garantie wink
je m'en sers qu'en j'envoie du pdf

Hors ligne

 

#5 13-10-2008 17:41:04

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

Même problème smile

Donc mon nouveau code :

Code:

function downloadAction() 
  {    
      $this->_helper->viewRenderer->setNoRender();
      
      if ((isset($this->getRequest()->fn))&&(eregi($this->getRequest()->fn,$this->user->servicesautorises))) {

              $f_name = $this->getRequest()->fn . '-installer.exe';
                $f_location = Zend_Registry::get('config')->download->src_download_root . '/' . $f_name;
                                            
                $f_string = file_get_contents($f_location); // recupere le contenu du fichier
                $f_size = strlen($f_string); // recupere la taille                
                                            
                $this->_response->clearHeaders();
                $this->_response->clearBody();                 
                $this->_response->setBody($f_string);
                
               $this->_response->setHeader('Content-Disposition', 'attachment; filename='.$f_name.';', true);
               $this->_response->setHeader('Content-Type', 'application/octet-stream', true);
               $this->_response->setHeader('Content-Transfer-Encoding', 'binary', true);
               $this->_response->setHeader('Content-Length',$f_size,true);                       
               $this->_response->setHeader('Pragma','no-cache',true);
               $this->_response->setHeader('Cache-Control','must-revalidate, post-check=0, pre-check=0, public',true);
               $this->_response->setHeader('Expires',0, true);                
          
      }
      else {
          $this->_redirect('/private');          
      }
  }

C'est plus propre, mais ça ne change rien.

Dernière modification par Delprog (13-10-2008 17:42:51)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#6 13-10-2008 17:59:13

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

Par contre dans ton code tu fais :

Code:

....
$f_string = file_get_contents($f_location);
....
$this->_response->setBody($f_string);

Mais setBody est censé recevoir un string et pas du binaire non ? (sauf erreur de ma part)


A+ benjamin.


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#7 13-10-2008 18:08:43

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

Bon, pour prouver que les fichiers sont bons, ça fonctionne en faisant ça :

Code:

function downloadAction() 
  {    
      $this->_helper->viewRenderer->setNoRender();
      
      if ((isset($this->getRequest()->fn))&&(eregi($this->getRequest()->fn,$this->user->servicesautorises))) {

              $f_name = $this->getRequest()->fn . '-installer.exe';              
                $f_location = Zend_Registry::get('config')->download->src_download_root . '/' . $f_name;
                $this->_redirect('/' . $f_location);
                exit;                
      }
      else {
          $this->_redirect('/private');          
      }
  }

Ce qui ne me convient puisque je veux justement protéger l'accès aux fichiers en fonction des droits de l'utilisateur.

Dernière modification par Delprog (13-10-2008 18:15:07)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#8 13-10-2008 23:09:57

gauthier
Membre
Date d'inscription: 30-09-2008
Messages: 116
Site web

Re: [Résolu] Action Téléchargement de fichier

euh si je comprends bien tu fais un simple redirect là ; autrement dit, tu ne contrôles pas vraiment l'accès au fichier, puisque quelqu'un qui connaitrait l'URL pourrait y accéder sans souci...

Je repense à un truc... en relisant tes posts, je m'aperçois que tu sembles être sous Windows, lequel gère les binaires d'une façon spécifique.

essaies de faire ça (dans ton premier code) :

Code:

// readfile($f_location);
$fp = fopen($f_location,"rb");
fpassthru($fp);

Ca peut aider - la différence de taille entre l'original et la copie pourrait bien correspondre à certains caractères binaires manquants...


Consultant Zend Technologies // Blog perso : Logiciel libre et développement web -- http://freeblogware.org

Hors ligne

 

#9 13-10-2008 23:16:18

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

Pardon, il manquait un "pas" dans ma phrase smile il fallait lire :

Ce qui ne me convient pas

Le redirect c'était pour prouver que ça ne venait pas du fichier, ce ne sera en aucun cas ma solution :p

Effectivement je suis sous windows (*remontée de bile acide*)

Je teste ça desuite smile

Dernière modification par Delprog (13-10-2008 23:17:28)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#10 14-10-2008 00:38:10

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

Ca fonctionne très bien merci.

Par contre pour info, comme 'fpassthru' dirige immédiatement le résultat vers la sortie, si on veut utiliser la syntaxe :

Code:

$this->getResponse()->setHeader(....);

à la place de :

Code:

header(....);

(pour être vraiment propre jusqu'au bout)
il faut forcer l'envoie de la réponse par un :

Code:

$this->getResponse()->sendResponse();

avant d'envoyer 'fpassthru'

Donc mon code final :

Code:

  function downloadAction() 
  {          
      $this->_helper->viewRenderer->setNoRender();
      
      if ((isset($this->getRequest()->fn))&&(eregi($this->getRequest()->fn,$this->user->servicesautorises))) {
              // Si l'user est autorisé à dl le fichier et si le paramètre fn est passé    
              $f_name = $this->getRequest()->fn . '-installer.exe';                            
              $f_location = Zend_Registry::get('config')->download->src_download_root . '/' . $f_name;
                          
              if (file_exists($f_location)) {
                    // Continue seulement si le fichier existe
                    $f_size = filesize($f_location);
                    $fp = fopen($f_location,"rb");
                                                                                         
                    $this->getResponse()->clearHeaders()
                                        ->setHeader('Content-Description', 'File Transfer', true)
                                        ->setHeader('Content-Disposition', 'attachment; filename='.$f_name.';', true)
                                        ->setHeader('Content-Type', 'application/octet-stream', true)
                                        ->setHeader('Content-Transfer-Encoding', 'binary', true)
                                        ->setHeader('Content-Length',$f_size,true)                      
                                        ->setHeader('Pragma','no-cache',true)
                                        ->setHeader('Cache-Control','must-revalidate, post-check=0, pre-check=0, public',true)
                                        ->setHeader('Expires',0, true)
                                        ->sendResponse(); // force l'envoie immédiat des headers pour bien attraper le fpassthru
                    fpassthru($fp);
                    fclose($fp);
                    exit;
              }
              else {
                  // Si le fichier n'existe pas : mauvais paramètre fn
                  throw new Zend_Controller_Action_Exception(Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION,404);
                  exit;
              }
      }
      else {
          $this->_redirect('/private');          
      }
  }

Merci pour votre aide.

A+ benjamin.


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#11 14-10-2008 08:42:26

gauthier
Membre
Date d'inscription: 30-09-2008
Messages: 116
Site web

Re: [Résolu] Action Téléchargement de fichier

en effet fpassthru() dump directement le contenu du fichier sur la sortie standard...

en tout cas, je suis content d'avoir pu t'aider, même si ce fut laborieux wink (j'aurais du y penser plus vite, mais comme je n'utilise à peu près jamais PHP sous Windows...)


Consultant Zend Technologies // Blog perso : Logiciel libre et développement web -- http://freeblogware.org

Hors ligne

 

#12 14-10-2008 08:45:53

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: [Résolu] Action Téléchargement de fichier

mais comme je n'utilise à peu près jamais PHP sous Windows...

Et comme tu es chanceux, si j'avais le pouvoir de décision sur les serveurs, crois moi qu'on serait en Linux. Pas que je sois anti microsoft, mais malgré Zend qui optimise les performances avec le FastCGI, on est encore très loin des performances d'un serveur LAMP.

smile


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages