Page 1 sur 1

Utilisation de startpos avec ftp_put ou ftp_nb_put

Posté : 09 mars 2015, 13:46
par Kapoue
Bonjour,

Quelqu'un a t'il déjà utilisé le dernier paramètre startpos de la fonction ftp_put ou ftp_nb_put ?
J'ai fait une classe FTP qui permet d'envoyer tout un tas d'informations récursivement sur un autre serveur en passant par une interface AJAX afin de ne pas avoir d'erreur de temps d'affichage lors de l'envoi ou la récupération de nombreux fichiers. Le souci est que si les fichiers à envoyer sont trop gros, avec un débit pourri, seule une partie du fichier est envoyée. J'ai donc voulu couper ces gros fichiers en passant par un fichier temporaire plus petit (100ko) que j'envoie via ftp_put et c'est là que j'ai besoin de startpos. Le souci est que lorsque startpos est supérieur à 0, la fonction envoie bien un retour comme quoi tout s'est bien passé mais en fait le fichier n'a pas grossi, ça se voit sur filezilla, le fichier fait toujours 100ko. Plus de détails sur un autre forum : http://www.developpez.net/forums/d15015 ... tp_nb_put/, sans réponse.

C'est pourquoi, je vous demande si quelqu'un a déjà été confronté à ce problème. Ce paramètre a été ajouté mais je ne trouve aucune doc le concernant.

Merci d'avance pour votre aide.

Voici le bout de code qui appelle ftp_put :

Code : Tout sélectionner

public function Envoyer($Fichier, $FichierLocal = "", $Depart = 0) { if ($this->Connection === false) { return false; } if ($FichierLocal == "") { $FichierLocal = $Fichier; } $Ret = @ftp_put($this->Connection, $Fichier, $FichierLocal, FTP_BINARY, $Depart); return $Ret; }

Re: Utilisation de startpos avec ftp_put ou ftp_nb_put

Posté : 09 mars 2015, 14:10
par @rthur
Bonjour et bienvenue sur PHPfrance,

Personnellement, je n'ai jamais utilisé ce paramètre.

Avant toute chose :
- il faut isoler le problème, c'est à dire faire une page PHP la plus simple possible qui ne contient que le code qui te semble problématique.
- vérifier sur 1 ou 2 autres serveurs FTP si le problème est confirmé afin d'éliminer la possibilité que ce soit un bug du serveur FTP distant.

Et ensuite, 3 possibilités pour faire le debug :
1) Trouver un message d'erreur.
- Il faudrait déjà que tu retires l'arobace devant ton nom de fonction car mettre un arobace permet de masquer les erreurs or c'est justement l'inverse que l'on souhaite pour comprendre un problème ;-)
- Si malgré ça rien ne s'affiche, essaye de regarder dans les logs de ton serveur PHP (cf phpinfo() pour trouver le fichier de log) et dans les logs de ton serveur FTP si tu y as déjà accès.

2) Regarder "sous le capot", c'est à dire dans le code source de PHP pour comprendre ce que fait cette fonction (il faut s'y connaitre en C++) : https://github.com/php/php-src/blob/fc3 ... ftp.c#L882

3) Analyser les trames réseau avec Wireshark pour voir les données qui transitent. Le protocole FTP étant relativement simple et non crypté. https://www.wireshark.org

Re: Utilisation de startpos avec ftp_put ou ftp_nb_put

Posté : 09 mars 2015, 16:30
par Kapoue
Merci @rthur pour ces infos, je vais essayer tout ça et je te tiens au courant.

Re: Utilisation de startpos avec ftp_put ou ftp_nb_put

Posté : 10 mars 2015, 10:54
par Kapoue
Bonjour @rthur,

De bon matin, je me suis attaqué aux étapes que tu m'as données.

J'ai fait une page simple avec juste le code pour découper le fichier et envoyer chaque morceau à la suite de ce qui a été envoyé :

Code : Tout sélectionner

$TailleFichier = filesize($NomFichier); $Depart = 0; $Connection = ftp_connect(FTPSERVEUR); ftp_login($Connection, FTPUTILISATEUR, FTPMOTDEPASSE); ftp_chdir($Connection, FTPDOSSIER); ftp_pasv($Connection, true); do { $NomFichierTemp = TEMP."/fichiertemp.tmp"; $FichierTemp = fopen($NomFichierTemp, "w"); $Fichier = fopen($NomFichier, "r"); fseek($Fichier, $Depart); $Temp = fread($Fichier, TAILLEFICHIERMAX); fwrite($FichierTemp, $Temp); fclose($Fichier); fclose($FichierTemp); $Retour = ftp_put($Connection, $NomFichier, $NomFichierTemp, FTP_BINARY, $Depart) ? "oui" : "non"; echo "envoi a partir de ".$Depart." : ".$Retour." ".ftp_size($Connection, $NomFichier)."<br />"; $Depart += TAILLEFICHIERMAX; } while ($Depart < $TailleFichier && $Retour != "non"); echo $Retour ? "oui" : "non"; ftp_close($Connection);
Et j'ai fait le test sur 2 serveurs différents (juste en changeant la définition de FTPSERVEUR, FTPUTILISATEUR, FTPMOTDEPASSE et FTPDOSSIER.
Sur le premier serveur FTP (sous Windows), la boucle s'arrête la 3e fois : la première fois, le fichier est créé et fait bien 100ko, la 2 fois la fonction ftp_put a bien fonctionné mais le fichier fait toujours 100ko, la 3 fois ftp_put renvoie une erreur et pour cause, ça demande d'écrire à partir de 200ko sur un fichier qui fait 100ko.
Sur le 2 serveur FTP (sous Linux), la boucle s'arrête à la fin du gros fichier à découper, chaque ligne indique que la fonction ftp_put a fonctionné mais le fichier toujours 100ko ce qui indique que la fonction ne fait rien. Déjà en fonction du serveur FTP, la même fonction est interprettée différemment.
J'ai testé en recupérant avec filezilla le fichier envoyé et en le comparant via un éditeur hexadecimal avec le fichier temp, si je laisse 0 dans le dernier paramètre (startpos) de la fonction ftp_put, le fichier envoyé est bien identique au dernier fichier temp. Par contre si je mets autre chose que 0 dans ce paramètre, c'est le premier morceau envoyé qui est sur le serveur FTP au lieu du dernier.
Je vais fouiller dans le code de la fonction ftp_put via le lien que tu m'as passé afin de voir ce qu'elle fait, juste pour voir.
Et je crois que je vais finir par me plonger dans les commandes FTP que j'ignore complètement et faire appel à la fonction ftp_raw.
A suivre...

Re: Utilisation de startpos avec ftp_put ou ftp_nb_put

Posté : 26 mars 2015, 12:54
par Kapoue
Bonjour,

J'avais d'autres choses à faire, j'ai donc mis de côté ce problème pendant quelques jours. Je me suis repenché dessus ce matin.
Je viens de fouiller le code de la fonction ftp_put, il y a un bout de code concernant le fait que startpos est supérieur à 0, en gros la commande ftp REST est envoyée. J'ai donc essayé de faire ça (en traduisant le C++ en PHP)

Code : Tout sélectionner

$arg = str_pad(sprintf("%d", $Depart), 11); ftp_raw($Connection, "REST ".$arg);
avant de faire un ftp_put sans le dernier paramètre mais j'ai un message d'erreur "501 Reply marker is invalid". Je dois certainement me gourrer quelque part. J'ai cherché des bouts de code PHP qui permettent de passer tout par ftp_raw car en faisant ftp_raw($Connection, "REST ".$LeNomDeMonFichier); le fichier est bien créé mais reste vide. Je ne trouve pas comment envoyer les données.

Je continuerai la recherche plus tard