Newsgroup: it.comp.lang.c
Titolo: Inviare un file da programma CGI in C

Salve,
mi è venuta una curiosità cercando di apprendere il protocollo/interfaccia
CGI. Come faccio ad inviare al browser un file che non sia una semplice
pagina di testo? Magari un file audio o un pdf o una immagine ?
Se faccio printf("Content-Type: text/html\r\n\r\n") il browser riceve i
tag html che invio dopo gli header, ma come faccio a inviare come output
un file pdf o un qualsiasi altro tipo di file?
Se scrivo printf("Content-Type: image/jpeg\r\n\r\n"), dopo, come faccio a
spedire il contenuto del file ?
Qualcuno ha esperienze del genere ?
Francesco

 spedire il contenuto del file ?
Scrivi il contenuto del file su STDOUT usando fwrite.
Se non vuoi caricartelo tutto in memoria, puoi leggerlo e scriverlo a
blocchi usando fread e fwrite.
Max

 blocchi usando fread e fwrite.
Ok, grazie, ci proverò.
Francesco

 Scrivi il contenuto del file su STDOUT usando fwrite.
Ovviamente, volevo dire 'stdout' (minuscolo).
Max



Provo a leggere il file con questo codice
while ((rec_size=fread(&rec,sizeof(rec),1,fimage))>0)
{
//printf("%s",rec);
printf("block size %d blocco %d<br>\n",rec_size,++i);
}
ma mi restituisce sempre rec_size=1, mentre ho definito il buffer, rec,  di
256 caratteri.
Il file viene aperto con
FILE *fimage;
fimage=fopen("immagine.jpg","r");

Il Mon, 12 Feb 2007 15:41:36 +0100, Max M. ha scritto:

Ecco il semplice programmino che ho realizzato, ma che non funziona
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define REC_SIZE 512
int main(void)
{
int rec_size;
char rec[REC_SIZE];
FILE *image;
image=fopen("immagine.jpg","r");
printf("Content-Type: image/jpeg\r\n\r\n");
// Scrive il file su stdout
while ((rec_size=fread(rec,sizeof(rec),1,image))>0)
{
fprintf(stdout,"%s",rec);
}
fclose(image);
}
nel browser viene solo visualizzato il nome del file, ma l'immagine non
viene visualizzata.
Francesco

 }
non puo' funzionare una cosa cosi'.
stai leggendo un file binario probabilmente pieno
di zeri. Lo zero viene interpretato come fine stringa!
Quindi non puoi usare fprintf e "%s", perche'
al primo 0 lui smette di copiare la stringa sullo stdout.
devi usare fread per leggere la roba in un buffer
e poi fwrite per scrivere il contenuto del buffer.
ciao,
g.

 
Ok, grazie, così il programma non funziona:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define REC_SIZE 512
int main(void)
{
int rec_size;
char rec[REC_SIZE];
FILE *image;
image=fopen("immagine.jpg","r");
printf("Content-Type: image/jpeg\r\n\r\n");
while ((rec_size=fread(rec,sizeof(rec),1,image))>0)
{
fwrite(rec, sizeof(rec), 1, stdout); 
}
fclose(image);
}
Francesco

 }
Per ciascuna lettura, devi scrivere un numero di byte equivalente a quelli
letti (rec_size), che potrebbe benissimo essere inferioriore a sizeof(rec)
e molto probabilmente lo sarà nell'ultimo blocco. 
Max

 Max
Scusami, ho scritto una ca..ata, il programma funziona, ho aggiunto
un "non" in più.
Francesco

> 256 caratteri.
Appunto.
Inoltre - *importante* - si sta scrivendo sullo 'stdout' che di default 
e' aperto in modalita' *testo*. Su sistemi Unix non ci sono problemi; su 
Windows, per esempio, il codice non funzionera' (ricordo che si sta 
inviando un file binario - un jpg). Lo stdout [2], quindi, deve essere 
riaperto, o impostato, in modalita' binaria [3], altrimenti in scrittura 
alcuni car. vengono convertiti (eg. NL => CR+NL su PcDos/Win, NL => CR 
su Mac). Anche la scrittura dell'header fatta con printf("Content-Type: 
image/jpeg\r\n\r\n") avra' problemi simili.
Ciao
Note:
[1] attenzione: nell'esempio che ho fatto i controlli d'errore sono 
'minimamente' implementati (eg. usare anche la ferror())
[2] ma in un CGI si dovrebbe fare lo stesso per lo stdin
[3] come farlo dipende dal sistema, eg. su Win potrebbe essere: 
_setmode(_fileno(stdout), _O_BINARY);
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

Scusami, devo ringraziarti per il tuo consiglio. In effetti, con le
modifiche da te suggerite, il programma funziona. Per una svista avevo
scritto che il programma non funzionava, invece funzionava correttamente.
Francesco