Tétéchargements aléatoires sur mon site

Bonjour à toutes et à tous,
Je ne sais pas si je suis sur le bon forum, me déplacer si nécessaire.
Merci.

Les fichiers à télécharger sont situés dans un dossier "telechargements_publics". (voir le lien ci-dessous)

Problème qui se produit depuis environ 6 mois, (très fréquent et aléatoirement)
Site en service depuis 17 ans.
En cliquant un fichier, il se télécharge bien dans tous les cas, si j'utilise Mozilla-Firefox / Win XP.

En utilisant Mozilla-Firefox / Win10 :
- Si le fichier à télécharger est petit (50 ko) cela fonctionne bien.
- Pour un fichier de 500 ko et plus (limite non définie), le fichier téléchargé a une taille 0 octet et "échec" s'affiche.
Parfois le nom du fichier est complété avec ".PART'" (partiel).
Parfois le nom du fichier comporte des caractères bizarres juste avant le point qui précède l'extension.

// Extrait de mon fichier dowload_publics.php (attention : pas download_publics.php)

header("Pragma: public"); // : Spécification public pour les proxys et serveurs ?
header("Expires: 0"); // set expiration time. Toute machine, Recherche toujours la version sur le serveur
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); // Avertir le navigateur,

header("Content-Type: application/download");

header("Content-Disposition: attachment; filename="" . basename($le_fichier) . """); // accepte les espaces et accents dans les noms de fichiers.

header("Content-Transfer-Encoding: binary"); // force en binaire le téléchargement bit à bit
header("Content-Length: ".filesize($chemin_fichier)); // spécifie la taille, chemin et nom de fichier
@readfile($chemin_fichier); // envoie le fichier

Pour faire le test et les constatations :
https://www.microfer.fr/telechargements_publics.php?

D'où vient ce problème ? et comment y remédier ?
Merci d'avance.

Bonjour @YvesP26

Je ne pense pas que votre problème soit une question de taille du fichier, mais plutôt une question de format associé à PDF.


D'où vient ce problème ? et comment y remédier ?


J'ai aussi le problème avec Windows 11 et Firefox.

Firefox me dit "partial transfer" après 1/4 de seconde.
Donc ce n'est pas un timeout.

Je n'en sais pas plus, désolé...

Bonjour,
Pouvez vous essayer ca :

header('Content-disposition: attachment; filename='.$le_fichier);
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding:binary ');
header('Content-Length: '.filesize($chemin_fichier));
header('Pragma: no-cache');
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
@ob_end_flush();
readfile($chemin_fichier);
@ob_flush();
@flush();

Et donnez nous le resultat.

Bonjour @YvesP26

Vous pourriez essayer en mettant directement l'adresse du fichier à télécharger.

Dans le cas d'un fichier PDF, suivant le navigateur utilisé :
- le fichier sera entièrement téléchargé
- le contenu du PDF sera affiché dans le navigateur


Vous pourriez essayer en mettant directement l'adresse du fichier à télécharger.


@YvesP26 souhaite comptabiliser les téléchargements, c'est ce que je comprends ici.

Je comprends très bien @Fritz2cat que @YvesP26 veuille comptabiliser les téléchargements.

Il suffit alors de créer une page intermédiaire qui va comptabiliser les téléchargements et donner le vrai lien pour télécharger le PDF.

C'est ce que je fais sur mon site.


Je comprends très bien @Fritz2cat que @YvesP26 veuille comptabiliser les téléchargements.

Il suffit alors de créer une page intermédiaire qui va comptabiliser les téléchargements et donner le vrai lien pour télécharger le PDF.

C'est ce que je fais sur mon site.


C'est ce qu'il fait deja je suppose car le script initial force le header au telechargement (donc sur une page séparé) le compteur (ou autre variables) doit être en amont surement. C'est bien cette page qui coince...

Bonjour à tous,
Et merci pour vos réponses.

@Gaston_Phone :
J'ai testé tous types de fichiers. Ce n'est pas un problème pdf.
Lorsque je mets un lien avec le nom du ficher ça fonctionne à tous les coups.
exemple :
https://www.microfer.fr/telechargements_publics/002-2-Guide_cpme_bonnes_pratiques.pdf

@Fritz2cat : Oui, je pense que c'est le même problème.

@CHORINP : OK, je vais tester.

rebonjour,
Le comptage des téléchargements fonctionne bien, même lorsque le téléchargement tombe en échec, et ce, depuis 17 ans. = Hors de cause.

(voir en fin de liste des fichiers un fichier xls et 2 fichiers zip.
J'utilise également le même PHP sur FREE et ça fonctionne depuis 15 ans.
Merci


J'ai testé tous types de fichiers. Ce n'est pas un problème pdf.
Lorsque je mets un lien avec le nom du ficher ça fonctionne à tous les coups.

Passer par un script PHP intermédiaire qui va comptabiliser et afficher l'adresse réelle.

D'autre part, dans le nom des fichiers, remplacer les "espaces" par des "_".
😉

@Gaston_Phone,
Passer par un script PHP intermédiaire qui va comptabiliser et afficher l'adresse réelle.
D'autre part, dans le nom des fichiers, remplacer les "espaces" par des "_".

Oui, c'est comme cela que je fonctionne.
Pas d'espaces dans les noms, comptages et mémorisation dans un fichier txt.


Passer par un script PHP intermédiaire qui va comptabiliser et afficher l'adresse réelle.
D'autre part, dans le nom des fichiers, remplacer les "espaces" par des "_".

Oui, c'est comme cela que je fonctionne

Non, vous lancez directement le téléchargement du fichier.

Via votre script **_dowload_publics.php_**, affichez l'adresse réelle du fichier.
Le visiteur clique sur le nouveau lien affiché, et ... le tour est joué.

Bonjour


J'utilise également le même PHP sur FREE et ça fonctionne depuis 15 ans.


Ça fait 10 ans que FREE ne fait plus de mise à jour de version PHP il en est resté à la version 5.6
Si votre script date d'il y a 15 ans il faudrait peut-être revoir ce script pour qu'il soit compatible avec votre version php d'OVH.


Non, vous lancez directement le téléchargement du fichier.

Je ne suis pas sûr de bien comprendre cette phrase ?
Il faut pas lancer ou il faut lancer directement ?

et pour la suite,
Dans mon post 1 il y a bien le chemin et le nom du fichier.
Je ne peux pas le mettre en dur, dans dowload_publics.php
c'est une variable $chemin_fichier.

header("Content-Transfer-Encoding: binary"); // force en binaire le téléchargement bit à bit
header("Content-Length: ".filesize($chemin_fichier)); // spécifie la taille, chemin et nom de fichier
@readfile($chemin_fichier); // envoie le fichier

Merci

Regarder un vrai exemple :

https://wordetweb.com/word-et-web/CMS-Table-caracteres-ASCII-FR.htm

Et :

https://www.wordetweb.com/word-et-web/WORDPRESS-guide-installation-de-WordPress-premier-domaine-chez-OVH-FR.htm#D-_Installation

Bonjour @YvesP26,

Si un des différents retours répond à votre demande, je vous invite à marquer ce dernier comme solution.

Dans le cas contraire, n’hésitez pas à ajouter des informations afin qu’une nouvelle réponse vous soit apportée par la communauté.

^FabL

Bonjour à tous,
Oui, si j'ai une solution je la communiquerai. j'ai l'habitude des forums.

Après avoir effectué d'autres tests sur autres PC, d'autres SE (win, linux), d'autres navigateurs.
En résumé :
- Le problème se produit aléatoirement dans tous les cas. (dans 95% des cas et 95% du temps.)
- Parfois il suffit d'attendre 10 mn et cela fonctionne.
- Ce n'est pas lié au type de fichier. (pdf, Zip, xls, JPG)
- Une commande directe fonctionne à tous les coups, Voir le lien ci-dessous. (4 ou 5 tests réalisés)
https://www.microfer.fr/telechargements_publics/002-2-Guide_cpme_bonnes_pratiques.pdf
- le compteur de téléchargements s'incrémente bien. (rafraichir la page éventuellement)
- en observant bien sous Win 10 / Firefox on voit que le téléchargement débute bien.
- Trés souvent, le nom du fichier est transmis et l'opération se termine en échec. taille = 0 octet.
- J'ai remarqué qu'il y avait 2 tentatives de téléchargements. (test avec fichier de 3Mo )
(Le compteur croît puis repart à zéro et l'échec précise "problème réseau")

Ma conclusion :
- problème de protocole de transmission. (des erreurs)
- Or tous mes paramètres de transmission sont dans mon fichier dowload_publics.php cité ci-avant.
Vous pouvez voir mes paramètres header.

J'ai essayé d'autres combinaisons du header. aucun succès. le problème subsiste.
Voilà où j'en suis. Je ne sais plus quoi tester.

Serait il possible d'avoir l'ensemble du code (appel/traitement) afin d'y jeter un coup d'oeil ?
Notamment la partie qui envoi a la page de download (avec variables) et le fichier de download en totalité.

Bonjour CHORINP,<br />je vais essayer de te joindre le fichier.  (Jamais fait sur ce forum)<br />j&#39;ai modifier l&#39;extension php en txt ou jpg  &#61;  pas possible<br /><br />en texte ci dessous.  (avec en commentaires tous mes tests sans succès)<br />session_start();<br /><br />	$le_chemin &#61;&#39;./telechargements_publics/&#39;;  	// chemin du fichier à télécharger<br />	$le_fichier &#61;  $_GET[&#34;mon_fichier&#34;] ;		// nom du fichier    Ci-dessous, suppprime les espaces en trop (dèbut et fin)<br />	$le_fichier &#61; trim($le_fichier);			// ajout 05/09/2012, évite problème aléatoire de décalage uniquement sur le site<br />	$chemin_fichier &#61; $le_chemin.$le_fichier ;  // concaténation<br />		<br />	$taill_max &#61; 100000;  // 100000 &#61; taille maxi du fichier à ré-enregistrer<br />	<br />// les fichiers à  bloquer<br />switch(strrchr(basename(strtolower(&#34;$chemin_fichier&#34;)), &#39;.&#39;)) { // strrchr : Trouve la dernière occurrence d&#39;un caractère dans une chaîne<br />case &#39;.php&#39;: $type &#61; &#39;exclu&#39;; break;							// strtolower : Renvoie une chaîne en minuscules<br />case &#39;.txt&#39;: $type &#61; &#39;exclu&#39;; break;  // laisser passer les   .text  ( lecture de table)  mais pas les txt<br />case &#39;.&#39;: $type &#61; &#39;exclu&#39;; break;<br />case &#39;&#39;: $type &#61; &#39;exclu&#39;; break;<br /><br />/*     à laisser passer (&#61; non exclu) <br />case &#39;.gz&#39;: $type &#61; &#39;application/x-gzip&#39;; break;<br />case &#39;.tgz&#39;: $type &#61; &#39;application/x-gzip&#39;; break;<br />case &#39;.zip&#39;: $type &#61; &#39;application/zip&#39;; break;<br />case &#39;.pdf&#39;: $type &#61; &#39;application/pdf&#39;; break;<br />case &#39;.png&#39;: $type &#61; &#39;image/png&#39;; break;<br />case &#39;.gif&#39;: $type &#61; &#39;image/gif&#39;; break;<br />case &#39;.jpg&#39;: $type &#61; &#39;image/jpeg&#39;; break;<br />case &#39;.doc&#39;: $type &#61; &#39;image/gif&#39;; break;<br />case &#39;.xls&#39;: $type &#61; &#39;image/jpeg&#39;; break;<br />case &#39;.docx&#39;: $type &#61; &#39;image/gif&#39;; break;<br />case &#39;.xlsx&#39;: $type &#61; &#39;image/jpeg&#39;; break;<br />case &#39;.text&#39;: $type &#61; &#39;text/plain&#39;; break; // laisser passer les   .text  ( lecture de table)  mais pas les txt<br />*/<br />default: $type &#61; &#39;OK&#39;; break;  		      // non trouvés ou sans extension (non exclus)<br />}<br /> //echo &#34; &#61;&#61;&#61;&#61;&#61;&#61;&#61;&gt;&gt;&gt; Fichier $type&#34; ;	  // test  attention ce test permet de voir la variable mais provoque une erreur.<br />		<br />if($type !&#61; &#34;exclu&#34;) {  // if non exclu<br />   //   Header(&#34;Location: $chemin_fichier&#34;);  // Méthode 1 permet de télécharger directement mais affiche les fichiers .jpg et ....<br />// ************** fix for IE catching or PHP bug issue. *************************<br />// Nouvelle méthode 2, permet de télécharger directement y compris les fichiers .jpg .htm ...<br />// extrait de http://php.net/manual/fr/function.header.php<br />			//header(&#39;Content-Description: File Transfer&#39;);   // ($*$ &#61; <br />			header(&#34;Pragma: public&#34;);  	// Pas sûr ?  : Spécification public pour les proxys et serveurs (Lolo)<br />			header(&#34;Expires: 0&#34;); 		// set expiration time. Toute machine, Recherche toujours la version sur le serveur (Laurent)<br />			header(&#34;Cache-Control: must-revalidate, post-check&#61;0, pre-check&#61;0&#34;);   // Avertir le navigateur,<br />			//header(&#39;Cache-Control: must-revalidate&#39;);  //  ($*$ &#61; modifié ne suffit pas)<br />			// browser must download file from server instead of cache<br /><br />			// force download dialog<br />			//header(&#34;Content-Type: application/force-download&#34;);  // ne sert pas?  declaration multiple du Content type (Laurent)<br />			header(&#34;Content-Type: application/download&#34;); // supprim pour test 01/03/2024<br />			//header(&#39;Content-Type: application/octet-stream&#39;); //   ($*$ &#61; modifié ne suffit pas)<br /><br />			// use the Content-Disposition header to supply a recommended filename and<br />			// force the browser to display the save dialog.<br />	 // header(&#34;Content-Disposition: attachment; filename&#61;&#34;.basename($le_fichier).&#34;;&#34;); // spécifie le nom de fichier pour la pièce jointe (de l&#39;url)<br />	 // header(&#34;Content-Disposition: attachment; filename&#61;&#34;.basename($chemin_fichier).&#34;;&#34;);   // les 2 lignes fonctionnent mais pas ne nom de fichier avec espace.<br />	 <br />	 //header(&#34;Content-Disposition: attachment; filename&#61;\&#34;&#34; . basename($le_fichier) . &#34;\&#34;&#34;);  // accepte les espaces et accents dans les noms de fichiers.<br />	   header(&#39;Content-Disposition: attachment; filename&#61;&#34;&#39;.basename($le_fichier).&#39;&#34;&#39;);  // accepte ...  ($*$ &#61; modifié ne suffit pas)<br />			/*<br />			The Content-transfer-encoding header should be binary, since the file will be read<br />			directly from the disk and the raw bytes passed to the downloading computer.<br />			The Content-length header is useful to set for downloads. The browser will be able to<br />			show a progress meter as a file downloads. The content-lenght can be determines by<br />			filesize function returns the size of a file.<br />			*/			<br />			header(&#34;Content-Transfer-Encoding: binary&#34;);   		   // force en binaire le téléchargement bit à bit  supprimé 01/03/2024 sans succès<br />			header(&#34;Content-Length: &#34;.filesize($chemin_fichier));  // spécifie la taille, chemin et nom de fichier  <br />			ob_clean(); // ajout test 01/03/2024 sans succès<br />            ob_end_flush(); // ajout test 01/03/2024 sans succès<br />			readfile($chemin_fichier);   						   // envoie le fichier     ($*$ &#61; modifié sans le &#64;read...)<br />			&#64;ob_flush(); // ajout test 01/03/2024 sans succès<br />			&#64;flush(); // ajout test 01/03/2024 sans succès<br />			<br />//****************   // sortie sans comptage *********************************<br />	// ATTENTION ci dessous, pour des tests &#34;echo&#34;,  supprimer les lignes header ci-dessus provisoirement. (sauf 42 43 44 les 3 premières)<br />	// Attention ! Le nom d&#39;un fichier ne doit pas contenir le caractère &#34;&amp;&#34; sinon problème d&#39;écriture du nombre de downloads (écrasement)<br />	// Attention ! noms des fichiers commencent par une majuscule. (à confirmer avec stristr au lieu de ereg)<br /><br />	$fp &#61; fopen(&#34;./pages/compter_dowload_pub.txt&#34;,&#34;r&#43;b&#34;); 		// ouvrir le fichier en lecture/écriture en binaire<br />		// echo &#39;<br /> test &#39;.$fp.&#39;<br />&#39; ; 	// $fp &#61; &#34;Resource id #2&#34; test (quel que soit le rang du fichier)<br />	flock($fp,2); // 1 ou 2 ? LOCK_SH &#61; 1 ?? &#61; bloque écriture ; LOCK_EX &#61; 2 &#61; bloque lecture  et écriture pour les autres . <br />        // 13/01/2017 flock($fp,1) au lieu de flock($fp,2);  pour un test &#61; sans effet<br />		<br />	$reponse &#61; 0; // utilisé également pour détection nom du fichier trouvé, pour sortir du while 04/06/2018<br />	if(is_resource($fp)){<br />		while(!feof($fp) and empty($reponse)){      // while(!feof($fp) and $reponse &#61;&#61; 3){<br />				$La_ligne &#61; ftell($fp);				// début de ligne (après \n) qui comprend le nom d&#39;un fichier, position du pointeur.<br />				$ligne_lue &#61; fgets($fp); 			// Récupère la ligne courante sur laquelle se trouve le nom d&#39;un fichier <br />													// echo &#39;<br />&#39; .$ligne_lue ; // test<br />				  // autre solution : 18/07/2018  (ereg dépassé, ne plus utiliser.)<br />				  if(preg_match(&#39;/&#39;.$le_fichier.&#39;/&#39;,$ligne_lue)){ // si le nom du fichier cherché est trouvé sur cette ligne modif 01/06/2018<br />													//echo &#39;<br />&#39; .$ligne_lue ; // test<br />					$reponse &#61; 1;					// 1 qui permet de sortir du while<br />				}<br />		}<br />		<br />		 if(!feof($fp) and $reponse &#61;&#61;&#61; 1){ // modifier le Nb de téléchargements						<br />			$longueur_nom_fichier &#61; strlen($le_fichier);  <br />			        //echo &#39;test &#39; .$longueur_nom_fichier . &#34;___&#34; .$le_fichier .&#39;<br />&#39; ; 	// (&#61; len nom fichier &#43; 10)   <br />			fseek($fp, $La_ligne &#43; $longueur_nom_fichier &#43; 1);	// repositionne le pointeur de fichier en début du Nb (Nb &#61; 7 car &#43; 2 espaces &#43; CR/NL)<br />					//settype($nb_dowload,&#34;integer&#34;);	// déclaration  inutile ?<br />			$nb_dowload &#61; fgets($fp,8);  	// récupèrer le nombre de downloads du fichier concerné (déplace le pointeur)<br />					//echo &#39;<br />_&#39;.$nb_dowload .&#39;_&#39;; <br />			$nb_dowload &#43;&#43; ;					// incrémenter le nombre<br />			$string &#61; sprintf(&#34;%07d&#34;,$nb_dowload);			// nb formaté 7 chiffres<br />			fseek($fp, $La_ligne &#43; $longueur_nom_fichier &#43; 1);	// repositionne le pointeur de fichier en début du Nb    //Nb &#61; 7 car &#43; CR/NL &#61; 9<br />				//écrire dans le fichier le nouveau Nb<br />				//echo &#39;_&#39;.$string.&#39;_&#39; ; 	// test<br />                  $reponse &#61; fwrite_stream($fp, $string, $taill_max);  		// 	17/06/2017<br />				//$_SESSION[&#39;reponse&#39;] &#61; $reponse; // stocker dans le fichier de session pour pouvoir le voir.<br />				<br />			// si le fichier à télécharger ne figure pas dans la liste, il faut l&#39;ajouter.<br />		}else if (empty ($nb_dowload)and feof($fp)) { <br />				//echo &#34;non trouvé&#34;;   // test  echo &#34;<body bgcolor="\&#34;#ff00ff\">\n&#34;; // test<br />            // fseek($fp, 0 ,SEEK_END);  // positionne le pointeur sur fin de fichier. inutile ? car il s&#39;y trouve déjà si non trouvé<br /><br />// vérifier que le fichier figure bien dans la liste ou qu&#39;il s&#39;agit bien d&#39;un vrai fichier téléchargeable. 20/07/2018<br />//  (bloquer les commandes du genre ftp://imperexclusivas:imperexclusivas@imperexclusivas.com/macaco.php? ou contient &#34;&#61;&#34; ou contient &#34;\&#34; ou contient &#34;&#64;&#34;)<br /><br />	$trouve &#61; 0;<br />	$mon_chemin &#61;&#39;./telechargements_publics/&#39;; // on relit la liste des fichiers<br />	if ($dir &#61; opendir($mon_chemin)) {  // affectation  du repertoire (non comparaison)<br />				while (false !&#61;&#61; ($file &#61; readdir($dir)) and empty ($trouve)) {// lecture du répertoire et recherche du nom de fichier		<br />					if (strcmp($file, $le_fichier) &#61;&#61; 0) { // si fichier identique trouvé<br />						$trouve &#61; true;<br />			//echo &#39;test &#39; .$file . &#34;_et_&#34; .$le_fichier .&#39;<br />&#39; ; 	//						<br />						$mon_host &#61; $_SESSION[&#39;mon_host&#39;]  ;		<br />						if ($mon_host &lt;&gt; &#39;127.0.0.1&#39;) {	// règle un petit petit problème en local : (les fichier ne sont pas listés mais alignés.)<br />							$string &#61; $le_fichier.&#34; 0000001  \n&#34;; //  nombre &#43; 2 espaces  et  (\r &#61; CR &#61; 0Dh  \n &#61; NL &#61; 0Ah) <br />									// ne pas mettre (\r &#61; CR &#61; 0Dh sinon problème sur le site : 0D en double)	<br />						} else {<br />							$string &#61; $le_fichier.&#34; 0000001  \r\n&#34;; //  nombre &#43; 2 espaces  et  (\r &#61; CR &#61; 0Dh  \n &#61; NL &#61; 0Ah) <br />							// mettre (\r &#61; CR &#61; 0Dh  en local)<br />						}			<br />						$reponse &#61; fwrite_stream($fp, $string, $taill_max); // écriture dans le fichier txt du nouveau fichier<br />							 //$_SESSION[&#39;reponse&#39;] &#61; $reponse; // stocker dans le fichier de session pour pouvoir le voir plus tard.			<br />					}<br />				}<br />			} // fin de if ($dir &#61; opendir( ... 			<br />		}  // fin de if(!feof($fp) and ...<br />	}  // fin de if(is_resource($fp) ...<br /><br />	flock($fp,3);						//  utile ?  (LOCK_UN &#61; 3) libère le verrou installé précédemment<br />	fclose($fp);                      	// fermer le fichier<br />} else{  // si fichier exclu<br /><br />	echo &#34; <center> Ce type de fichier (extension) n&#39;est pas autorisé au téléchargement, type : $type  <br /><br />&#34;;<br />	echo &#34; ./index.php?&lt;?php echo SID?&gt;  <br /> <br /> &#34; ;	<br />	echo &#34; <input type="button" name="bnom" /> <br /><br />&#34;;<br />	echo &#34; Vous devriez le signaler à Géryko (webmaster) </center>&#34; ;<br />}<br />?&gt;<br />				<br />	<br />// fonction utilisée dans la version 05/08/2012 et &#43; (voir &#34;php fwrite&#34; dans google)<br />function fwrite_stream($fp, $string, $taill_max) { ; // 10000 &#61; taille maxi du fichier à ré-enregistrer<br />if (strlen($string) &lt; $taill_max) {  // ajout 19/08/2016 la longueur n&#39;était pas prise en compte ! <br />    for ($written &#61; 0; $written &lt; strlen($string); $written &#43;&#61; $fwrite) {<br />        $fwrite &#61; fwrite($fp, substr($string, $written));<br />        if ($fwrite &#61;&#61;&#61; false) { // &#61;&#61;&#61; si égal et qu&#39;ils sont de même type. <br />            return $fwrite;<br />        }<br />    }<br />    return $written; // ajout de taill_max 26/10/2014  (attention $written n&#39;est pas la taille du fichier ! 06/2017)<br />	} // si taille trop longue.  $written est le nombre de caractères écrits<br />}<br />?&gt;</body>