Le serveur HTTP n’envoie pas le fichier complet à WGET, Firefox. Réinitialisation de la connexion par paire?

J’écris sur un serveur HTTP et je ne parviens pas à envoyer des fichiers plus volumineux. Si je les attrape avec netcat, la sortie semble parfaite. Si j’utilise un navigateur ou wget, je n’ai parfois que le fichier complet. WGET continue à avoir des erreurs “connexion réinitialisée par un pair”, voir le résultat ci-dessous Firefox dit “la connexion a été réinitialisée”.

Voici la procédure appropriée qui envoie des données au client:

int handle_request(int sockfd, struct cached_file content) { char buffer[1024]; // FIXME hardcoded arbitrary buffer size for header unsigned int sent_bytes; unsigned int total = 0; unsigned int bytes_left = content.size; printf("I have to send %u bytes of content.\n", content.size); snprintf(buffer, 1024, "HTTP/1.1 %s\nContent-Type: %s\nContent-Length: %s\n\n", content.statuscode, content.contenttype, content.sizessortingng); sent_bytes = send(sockfd, buffer, strlen(buffer), MSG_MORE); printf("I wanted to send %u bytes of header, and I sent %u.\n", strlen(buffer), sent_bytes); while (total < bytes_left) { sent_bytes = send(sockfd, content.data+total, bytes_left, 0); if (sent_bytes == -1) { printf("send() returned -1\n"); break; } total += sent_bytes; bytes_left -= sent_bytes; } printf("I sent %u bytes of content. I had %u left to send.\n", total, bytes_left); if (sent_bytes == -1) logprint("socket error!", errno); } 

Voici le résultat de wget essayant de récupérer le fichier:

 wget --sortinges 1 http://localhost:8081/image.jpg --2015-07-01 13:21:42-- http://localhost:8081/image.jpg Resolving localhost (localhost)... ::1, 127.0.0.1 Connecting to localhost (localhost)|::1|:8081... failed: Connection refused. Connecting to localhost (localhost)|127.0.0.1|:8081... connected. HTTP request sent, awaiting response... 200 OK Length: 700895 (684K) [image/jpeg] Saving to: 'image.jpg.10' image.jpg.10 53%[===============================> ] 363.31K --.-KB/s in 0.001s 2015-07-01 13:21:42 (688 MB/s) - Read error at byte 372031/700895 (Connection reset by peer). Giving up. wget --sortinges 1 http://localhost:8081/image.jpg --2015-07-01 13:21:43-- http://localhost:8081/image.jpg Resolving localhost (localhost)... ::1, 127.0.0.1 Connecting to localhost (localhost)|::1|:8081... failed: Connection refused. Connecting to localhost (localhost)|127.0.0.1|:8081... connected. HTTP request sent, awaiting response... 200 OK Length: 700895 (684K) [image/jpeg] Saving to: 'image.jpg.11' image.jpg.11 6%[==> ] 42.69K --.-KB/s in 0s 2015-07-01 13:21:43 (500 MB/s) - Read error at byte 43711/700895 (Connection reset by peer). Giving up. 

Débogage de la sortie du serveur http:

 I have to send 700895 bytes of content. I wanted to send 65 bytes of header, and I sent 65. I sent 700895 bytes of content. I had 0 left to send. 

J’apprécierais une autre paire d’yeux! Pourquoi cela se produit-il et comment puis-je le réparer?

Je suppose que l’erreur est liée au code que vous n’avez pas montré ici.

Dans une implémentation simple, c’est une erreur courante de ne pas lire complètement la requête mais seulement de lire la première ligne ou des octets pour déterminer la page demandée, puis d’envoyer la réponse et enfin de fermer.

Étant donné qu’au moment de la fermeture, il existe encore des données non lues du client, la connexion sera réinitialisée par l’homologue. Vous ne voyez pas cet effet avec nc car la requête que vous envoyez avec nc est probablement plus courte que celle du navigateur. Par conséquent, toutes les données de la requête sont lues dans le cas de nc, mais pas dans le navigateur.

En dehors de cela, votre réponse est invalide même si les navigateurs l’acceptent. Votre ligne de statut (la première ligne) s’arrête après le code de statut au lieu d’append la phrase de motif, voir http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1 . De plus, vous utilisez \n au lieu de \r\n comme séparateur de ligne.

Je ne sais pas si c’est nécessaire, mais lorsque j’inspecte les en-têtes envoyés par un simple site Web , il y a des guillemets autour des valeurs:

 Accept-Ranges:"bytes" Cache-Control:"max-age=25920000" Connection:"Keep-Alive" Content-Length:"4777" Content-Type:"image/gif" Date:"Wed, 01 Jul 2015 17:55:52 GMT" Expires:"Tue, 26 Apr 2016 17:55:52 GMT" Keep-Alive:"timeout=30, max=100" Last-Modified:"Mon, 28 Apr 1997 01:25:47 GMT" Server:"Apache/1.3.28 (Unix) mod_gzip/1.3.19.1a mod_perl/1.28" 

Est-il possible que le type de contenu ne soit pas correct?