Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

transfert de fichier du server au client

5 réponses
Avatar
Alex
Bonjour,

J'écris actuellement un petit script php pour transférer
des fichiers d'un serveur vers les clients (web).

Ca marche bien sur des petits fichiers, le problème arrive
sur des gros fichiers (j'ai testé sur un de 1Go), le
transfert s'arrête aléatoirement au bout de quelques
dizaines de secondes (des fois le téléchargement est arrivé à
30%, d'autre fois à 75%,...).

Et je comprends vraiment pas pourquoi...

Voici un bout de mon script:

- D'abord j'envoie les headers http

header('HTTP/1.1 200 OK');
header('Status: 200 OK');
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2,
date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");

header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header('Accept-Ranges: bytes');
header('Content-Transfer-Encoding: Binary');
header('Content-Type: application/force-download');
//header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
//header("Content-Disposition: inline; filename=$name");
header('Content-Length: '.$length);

- Ensuite je boucle pour envoyer le fichier
(et j'écris en même temps un fichier de debug sur le server)

$fd = fopen("debug.txt", "a");
fwrite($fd, "start of transfert\n");
fclose($fd);

while(true) {
if (connection_aborted()) {
$fd = fopen("debug.txt", "a");
fwrite($fd, "connection aborted\n");
fclose($fd);
break ;
} else if (connection_status() != 0) {
$fd = fopen("debug.txt", "a");
fwrite($fd, "connection status\n");
fclose($fd);
break ;
} else if (feof($fp)) {
$fd = fopen("debug.txt", "a");
fwrite($fd, "end of file\n");
fclose($fd);
break ;
} else {
print(fread($fp, 1024*8));
flush();
}
}

$fd = fopen("debug.txt", "a");
fwrite($fd, "end of transfert\n");
fclose($fd);






Alors déjà, première constatation, le
header('Content-Length: '.$length);
retourne bien la bonne taille à l'octet pret!
(wget mon_script.php indique bien la bonne taille à
télécharger).

Ensuite, quand j'ouvre le fichier "debug.txt", la
seul chose de marquer est:
"start of transfer
start of transfer
start of transfer
..."
(la commande wget relance le téléchargement quand
le transfert à été interrompu, d'ailleurs celui-ci
marque: "connection closed").

j'ai essayé en essayant de commenter mes 2 tests
sur connection_aborted() et connection_status(),
mais meme erreur de perte de connection de la part
du client.
Idem en essayant de lire non par bloc de 1024*8
mais seulement de 1024.

Quelqu'un aurait-il une idée?

Merci

--
Alex

5 réponses

Avatar
P'tit Marcel
J'écris actuellement un petit script php pour transférer
des fichiers d'un serveur vers les clients (web).
Ca marche bien sur des petits fichiers, le problème arrive
sur des gros fichiers (j'ai testé sur un de 1Go), le
transfert s'arrête aléatoirement au bout de quelques
dizaines de secondes



Ce forum n'est pas qu'en écriture seule....

Lis le fil "Pb telechargement de fichier avec PHP" entamé le 28/2 à 17h13.


eça
--
P'tit Marcel

Avatar
Thierry
bonjour

je suis bien d'accord avec P'tit Marcel relativement à ses intervention:
- dans ce fil
- dans le fil "Pb de téléchargement de fichier avec PHP"

Ca marche bien sur des petits fichiers, le problème arrive
sur des gros fichiers (j'ai testé sur un de 1Go), le
------------------------------------------^ !!!!!!!


heu, c'est quoi ton application ???
si c'est de la viéo... as tu pensé au streaming ??

Quelqu'un aurait-il une idée?


oui:

sinon la balise html <a> aurotise divers protocoles dans son paramètre href.
Dans la mesure ou ton script PHP est probablement appelé par un GET http
après la sélection d'un lien dans une page, pourquoi ne pas remplacé ce lien
par
<a href='ftp://domain.tld/vraimentTresGrosFichierDeLaMort.ext'>DL</a>
---------^

dans la mesure ou la seule utilité que je connaisse à utiliser PHP pour un
dl
est de pouvoir positionner les headers http pour outrepasser les
comportements
par défauts des navigateurs relativement à certains type MIME,
alors la syntaxe ci-dessus te permet d'obtenir le même résultat.

autre idée: créer un torrent


Merci


de rien

Avatar
Alex
bonjour

je suis bien d'accord avec P'tit Marcel relativement à ses intervention:
- dans ce fil
- dans le fil "Pb de téléchargement de fichier avec PHP"


Effectivement, je vous demande donc de m'excuser pour le mal commis.
Fil que je vais lire de suite.


Ca marche bien sur des petits fichiers, le problème arrive
sur des gros fichiers (j'ai testé sur un de 1Go), le
------------------------------------------^ !!!!!!!


heu, c'est quoi ton application ???
si c'est de la viéo... as tu pensé au streaming ??


J'ai effectivement mis une grosse video pour tester,
mais sinon non ce sont des données diverses et variés
où les fichiers peuvent aller de quelques Ko à un voir
plusieurs Go.


Quelqu'un aurait-il une idée?


oui:

sinon la balise html <a> aurotise divers protocoles dans son paramètre href.
Dans la mesure ou ton script PHP est probablement appelé par un GET http
après la sélection d'un lien dans une page, pourquoi ne pas remplacé ce lien
par
<a href='ftp://domain.tld/vraimentTresGrosFichierDeLaMort.ext'>DL</a>
---------^


Pour plusieurs raisons qui n'intéresseront sans doute personne, mais
je vous donne la principale quand meme (vu que vous les demandez):

Le serveur de fichier / stockage n'est pas la même machine que le
serveur web. Et donc en gros le serveur web peut communiquer en réseau
local avec ce server de fichier, mais il n'est pas possible d'accéder
directement au serveur de fichiers.


dans la mesure ou la seule utilité que je connaisse à utiliser PHP pour un
dl
est de pouvoir positionner les headers http pour outrepasser les
comportements
par défauts des navigateurs relativement à certains type MIME,
alors la syntaxe ci-dessus te permet d'obtenir le même résultat.


Je viens de vous en donnez une deuxième (sauf si vous me proposez une
solution plus élégante que le php pour faire ce que je fais).


autre idée: créer un torrent



torrent c'est pas du téléchargement collaboratif?

Enfin bref, je dois aussi pouvoir gérer les droits d'accès au fichier
(via login / mot de passe), savoir qui l'a téléchargé et tout et tout et
tout, et donc interdire que quelqu'un puisse communiquer directement
l'adresse http://www..../mon_script.php?file=toto.zip
(si la personne ne s'est pas identifié sur le site, il ne recevra pas le
fichier).




Enfin voila, j'ai résolu mon problème, et toutes les fonctionnalités
escomptées sont en place.

Merci


de rien


Encore merci.

--
Alex


Avatar
thierry

Le serveur de fichier / stockage n'est pas la même machine que le
serveur web. Et donc en gros le serveur web peut communiquer en réseau
local avec ce server de fichier, mais il n'est pas possible d'accéder
directement au serveur de fichiers.


effectivement autant pour moi


Enfin voila, j'ai résolu mon problème, et toutes les fonctionnalités
escomptées sont en place.


la solution pourrait interesser du monde :)


sinon (pas grand chose à voir avec php mais) il doit être possible de
créer un alias sur le serveur http via un disque réseau... non ?

Avatar
Alex

Le serveur de fichier / stockage n'est pas la même machine que le
serveur web. Et donc en gros le serveur web peut communiquer en réseau
local avec ce server de fichier, mais il n'est pas possible d'accéder
directement au serveur de fichiers.


effectivement autant pour moi


Enfin voila, j'ai résolu mon problème, et toutes les fonctionnalités
escomptées sont en place.


la solution pourrait interesser du monde :)


sinon (pas grand chose à voir avec php mais) il doit être possible de
créer un alias sur le serveur http via un disque réseau... non ?


c'était un pb de timeout...
j'ai donc rajouté un set_time_limit dans ma boucle de lecture/envoie
du fichier, puisque d'après le manuel:

"Lorsqu'elle est appelée, set_time_limit() remet le compteur à zéro. En
d'autres termes, si la limite par défaut est à 30 secondes, et qu'après
25 secondes d'exécution du script l'appel set_time_limit(20) est fait,
alors le script tournera pendant un total de 45 secondes avant de
finir."

while (!feof($fp)) {
print(fread($fp, 1024*8);
set_time_limit(30);
}

résoud mon pb

--
Alex