Pourquoi certains fichiers téléchargés ne connaissent-ils pas leur taille? [dupliquer]

82

Cette question a déjà une réponse ici:

Parfois, lors du téléchargement d’un fichier dans un navigateur Web, la progression du téléchargement ne "connaît" pas la taille totale du fichier, ni sa progression dans le téléchargement. Elle indique simplement la vitesse à laquelle il est téléchargé, avec une total comme "Inconnu".

Pourquoi le navigateur ne connaît-il pas la taille finale de certains fichiers? Où trouve-t-il cette information en premier lieu?

Coldblackice
la source
13
Les fichiers créés dynamiquement n'ont pas de taille, ils viennent en tant que flux jusqu'à ce que EOF soit atteint.
Fiasco Labs

Réponses:

114

Pour demander des documents à des serveurs Web, les navigateurs utilisent le protocole HTTP. Vous pouvez connaître ce nom dans votre barre d’adresse (il est peut-être masqué maintenant, mais lorsque vous cliquez sur la barre d’adresse, copiez l’URL et collez-la dans un éditeur de texte, vous verrez http://au début). HTTP est un protocole texte simple. Cela fonctionne comme ceci:

Tout d'abord, votre navigateur se connecte au serveur du site Web et envoie l'URL du document qu'il souhaite télécharger (les pages Web sont également des documents) et quelques détails sur le navigateur lui - même ( User-Agent, etc.). Par exemple, pour charger la page principale sur le site SuperUser http://superuser.com/, mon navigateur envoie une demande qui ressemble à ceci:

GET / HTTP/1.1
Host: superuser.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.0 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: [removed for security]
DNT: 1
If-Modified-Since: Tue, 09 Jul 2013 07:14:17 GMT

La première ligne spécifie le document que le serveur doit renvoyer. Les autres lignes sont appelées en-têtes; ils ressemblent à ceci:

Header name: Header value

Ces lignes envoient des informations supplémentaires qui aident le serveur à décider quoi faire.

Si tout va bien, le serveur répondra en envoyant le document demandé. La réponse commence par un message d'état, suivi de quelques en-têtes (avec des détails sur le document) et enfin, si tout va bien, du contenu du document. Voici à quoi ressemble la réponse du serveur SuperUser à ma requête:

HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Type: text/html; charset=utf-8
Expires: Tue, 09 Jul 2013 07:27:20 GMT
Last-Modified: Tue, 09 Jul 2013 07:26:20 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
Date: Tue, 09 Jul 2013 07:26:19 GMT
Content-Length: 139672

<!DOCTYPE html>
<html>
    [...snip...]
</html>

Après la dernière ligne, le serveur de SuperUser ferme la connexion.

La première ligne ( HTTP/1.1 200 OK) contient le code de réponse , dans ce cas c'est 200 OK. Cela signifie que le serveur a décidé qu'il peut retourner un document, comme demandé, et promet que le contenu qui va suivre sera un tel document. Si ce n'est pas le cas, le code sera autre chose et donnera une indication de la raison pour laquelle le serveur ne renvoie pas simplement un document en réponse: par exemple, s'il ne peut pas trouver le document demandé, il est supposé renvoyer 404 Not Foundet si vous n'êtes pas autorisé à accéder au contenu en question, celui-ci est censé être renvoyé 403 Forbidden.

Après cette première ligne d’état, les en-têtes de réponse suivent; ils fournissent plus d'informations sur le contenu renvoyé, tel que son Content-type.

Suivant est une ligne vide. Cela indique qu'il n'y aura plus d'en-têtes de réponse. Tout ce qui est au-delà de cette ligne correspond au contenu du document demandé. Ainsi, dans l'exemple ci-dessus, se <!DOCTYPE html>trouve la première ligne de la page d'accueil de SuperUser (un document HTML). Si je demandais un document à télécharger, il s'agirait probablement de caractères charabia, car la plupart des formats de document sont illisibles sans traitement préalable.

Retour aux en-têtes. Le plus intéressant pour nous est le dernier, Content-Length. Il indique au navigateur le nombre d'octets de données auxquels il doit s'attendre après la ligne vide. Il s'agit donc en gros de la taille du document exprimée en octets. Cet en-tête n'est pas obligatoire et peut être omis par le serveur. Parfois, la taille du document est imprévisible (par exemple, lorsque le document est généré à la volée), parfois les programmeurs fainéants ne l'incluent pas (assez commun sur les sites de téléchargement de pilotes), parfois les sites Web sont créés par des débutants qui ne savent pas d'un tel en-tête.

Quoi qu'il en soit, quelle qu'en soit la raison, l'en-tête peut être manquant. Dans ce cas, le navigateur ne sait pas combien de données le serveur va envoyer et affiche donc la taille du document comme inconnue , attendant que le serveur ferme la connexion. Et c'est la raison pour laquelle la taille des documents est inconnue.

Gronostaj
la source
4
Remarque très mineure: les navigateurs prennent en charge des protocoles autres que HTTP. Mais d’autres protocoles sont rares de nos jours et les mêmes concepts s’appliquent à d’autres protocoles même si les détails sont différents.
Robert Fisher
5
@ RobertFisher FTP est un protocole rare? : p
Thomas
5
@ Thomas C'est mon expérience ces jours-ci. Cela fait plusieurs années que je me souviens avoir vu une URL FTP dans mon navigateur. Il y a quelques années, j'utilisais ftp (directement plutôt que via un navigateur) au travail (presque en totalité), mais ces tâches sont désormais gérées par scp. La seule chose que j'utilise aujourd'hui avec ftp, c'est le téléchargement de contenu sur un hôte Web minimaliste. Bien sûr, YMMV. ^ _ ^
Robert Fisher le
2
C'est exactement le genre de réponse qui me fait aimer ce site. Comment puis-je lui accorder une prime?
Ce Guy brésilien
1
@ ruda.almeida si vous êtes en désaccord avec cela, vous pouvez en parler sur meta.superuser.com, nous en discuterons et peut-être que quelqu'un rouvrira la question.
gronostaj
54

L'en- Content-Lengthtête HTTP est facultatif dans certains cas et, en tant que tel, il peut ne pas être transmis avec le fichier. la fin du fichier sera signalée lorsque le socket sera fermé.

Ignacio Vazquez-Abrams
la source
1
Pour être précis, HTTP 1.0 a défini la longueur du contenu en fermant le socket après chaque document. Ceci est toujours pris en charge dans HTTP 1.1 pour des raisons de compatibilité. Mais HTTP 1.1 permet de réutiliser des connexions pour plusieurs documents si le Content-Lengthchamp d’en-tête est utilisé ou si le document est transféré Transfer-Encoding: chunked. Ce dernier permet de générer dynamiquement un contenu et de l’envoyer par morceaux au fur et à mesure de sa génération et de signaler la fin du document.
x4u
3

Lorsque le contenu (par exemple un .pdfdocument ou une feuille Excel) est créé à la volée, la taille ne peut pas être connue auparavant. Dans ce cas, le serveur ne peut pas vous envoyer la taille du téléchargement auparavant et le navigateur ne peut pas afficher la taille totale.

Uwe Plonus
la source
9
@ alfo va devoir être en désaccord ... si je suis en train de diffuser de la vidéo, ou même si je suis en train de diffuser des données dont la taille n'est pas fixe, s'il s'agit de transmettre rapidement les données à l'utilisateur, Je ne saurai pas la taille au moment où je commence la transmission
Foon
4
@Alfo Vous pouvez créer des données comme des .pdffichiers à la volée. Tant que les données ne sont pas écrites de manière compétitive, vous ne connaissez pas la taille, mais vous pouvez déjà envoyer les données au navigateur. Je l'ai déjà fait en Java et envoyé un fichier Excel au navigateur qui est généré à la volée. Du côté des navigateurs, cela ressemblait à un téléchargement, mais du côté des serveurs, il s’agissait d’une diffusion en continu. Il est donc possible de diffuser des .pdf fichiers même si vous ne pouvez pas imaginer cela. Depuis le navigateur, cela ressemble à un téléchargement sans durée connue.
Uwe Plonus
8
@Alfo - il suffit que la création soit terminée avant que le dernier paquet ne soit envoyé au client.
GalacticCowboy
4
@ Alfo Je n'ai jamais parlé de la vidéo, mais du streaming en général, qui peut aussi être un .pdffichier ou une feuille Excel!
Uwe Plonus
2
@Alfo - Vous avez un point valide, les fichiers dynamiques peuvent être entièrement créés d'abord en mémoire, puis envoyés via HTTP, ce qui facilite le calcul de la longueur du contenu. Toutefois, si le serveur envoie de nombreux fichiers volumineux créés dynamiquement qui seront divisés en plusieurs paquets, il est logique que le serveur commence à envoyer les morceaux au fur et à mesure de leur calcul (par opposition à la création de tous les fichiers volumineux en mémoire, puis envoie-le). HTTP 1.1 a spécialement conçu le codage de transfert en bloc à cette fin.
dr jimbob