2016-04-03 1 views
-1

Ceci est une partie d'un programme CGI écrit en C. Lorsque le client clique sur le lien, je veux que le fichier commence à télécharger, avec le nom de fichier par défaut suggéré.Le nom de fichier de disposition de contenu "suggestion" est toujours ignoré. Pourquoi?

Je sais que la spécification indique clairement que le nom de fichier spécifié dans l'en-tête Content-disposition est simplement SUGGÉRÉ, mais il semble que peu importe le navigateur que j'utilise, il est toujours ignoré. J'interprète ce comportement comme signifiant que je fais quelque chose de mal.

Voici un extrait de code simplifié qui reproduit mon problème. Lorsqu'il est compilé à, disons, test.cgi le programme fonctionne, mais le navigateur enregistre les données avec le nom de fichier "test.cgi" et non "archive.tar.gz" comme suggéré.

(Fichier i/o erreur de vérification et autres bits de sécurité enlevés pour garder cette claire et brève.)

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <string.h> 

#define CHUNK_SIZE 1024 

int main(int argc, char *argv[]) { 
    int fd; 
    long bytes_remaining, bytes_to_get, bytes_read, bytes_sent, retval; 
    int chunksize; 
    unsigned char data_buffer[CHUNK_SIZE]; 
    char header_str[200]; 

    fd = open("archive.tar.gz", O_RDONLY); 
    if(fd == -1) { 
    printf("Content-type: text/html\n\n"); 
    printf("Unable to open file: %s.<br><br>\n", strerror(errno)); 
    return 0; 
    } 

    bytes_remaining = lseek(fd, 0, SEEK_END); 
    lseek(fd, 0, SEEK_SET); 

    snprintf(header_str, 200, "Content-Type: application/x-compressed\r\n\r\nContent-Disposition: attachment; filename=\"archive.tar.gz\"\r\n\r\n"); 
    write(1, header_str, strlen(header_str)); 

    while(bytes_remaining > 0) { 
    if(bytes_remaining > CHUNK_SIZE) bytes_to_get = CHUNK_SIZE; 
    else bytes_to_get = bytes_remaining; 
    bytes_read = read(fd, data_buffer, bytes_to_get); 
    bytes_sent = write(1, data_buffer, bytes_read); 
    bytes_remaining -= bytes_sent; 
    } 
    close(fd); 

    return 0; 
} 

Pourquoi mon nom de fichier suggéré constamment ignoré?

Merci.

+0

Avez-vous reçu la valeur dans le CGI? Fournissez un [mcve] et voyez [ask]. – Olaf

+0

Dans l'application actuelle, oui, le fichier à télécharger est déterminé par les paramètres dans l'URL demandée. Ce qui précède est un exemple minimal, complet et vérifiable. Compilez-le, mettez-le sur un serveur, demandez à whatever_you_compiled_it_to.cgi, et au lieu que le navigateur télécharge le fichier et le nomme archive.tar.gz, il est sauvegardé sous le nom de whatever_you_compiled_it_to.cgi. – pgg

+0

Non, ce n'est pas le cas. Il y a l'appel manquant, resp. le site Web qui entraîne l'appel. Vous n'avez même pas répondu à ce que j'ai demandé. – Olaf

Répondre

0

Le problème est qu'il y a un retour/retour à la ligne supplémentaire dans l'en-tête. Il devrait être:

snprintf(header_str, 200, "Content-Type: application/x-compressed\r\nContent-Disposition: attachment; filename=archive.tar.gz\r\n\r\n"); 

Comme écrit dans l'OP, la ligne Content-Disposition serait interprété comme une partie des données, ne fait pas partie de l'en-tête. En outre, les guillemets autour du nom de fichier suggéré ne sont pas nécessaires.