Newsgroup: it.comp.lang.javascript
Titolo: Ancora upload...

Stiamo impazzendo...
Stiamo sempre cercando di file l'upload di file da client PC su server www
con il
metodo POST:
<FORM ENCTYPE="multipart/form-data" ACTION="cgitest.exe" METHOD=post>
dove cgitest.exe è un CGI scritto in C.
Nello stdin riusciamo a trovare solo il contenuto di file inferiori a 64K!
Per i file di dimensioni maggiori non si riesce ad avere di ritorno neanche
la variabile d'ambiente CONTENT_LENGTH.
Qualcuno sa se è un limite dei browser o della rete o altro?
Netscape invia un messaggio di errore di rete mentre cerca di inviare i
dati, Explorer apre una pagina con DNS error...
Grazie, Marco & Mara
--
ICL Italia
TeamPRO TeamWARE


<INPUT TYPE="file" size=40  NAME="file1">
<TEXTAREA NAME="COMMENTS1" ROWS="4" COLS="33"
WRAP=PHYSICAL></TEXTAREA>
<INPUT NAME="nominativo"  SIZE=33">
INPUT TYPE="Submit" VALUE="  Esegui  ">&nbsp;<INPUT
TYPE="Reset" VALUE="Cancella">
</FORM>
</BODY>
</HTML>
Puoi reindirizzare i dati di una form e il file selezionato
con input type=file al programma cgi
che può essere un semplice programmino in C che legge i dati
dallo stdin e scrive su un file temporaneo, dopodichè,
finita l'operazione apri in lettura il file temporaneo, ti
prendi quello che ti serve e scrivi in modalità append
nel file indicato nel richiamo al cgi che sopra ho indicato
filedioutput.
Il programma in C deve essere di questo tipo:
setta l'apertura dei file in binario con, (altrimenti se ti
arrivano file in binario, leggendo da stdin perdi dei
caratteri, sabato e domenica sono rimasto in ufficio fino
alle 2 di notte prima di capire perchè non ricevevo i file
completi):
setmode(fileno(stdin), O_BINARY));
dopodichè leggi dalla variabile d'ambiente la dimensione dei
dati che ti sta arrivando via posta
dim=atol(getenv("CONTENT_LENGTH"));
ricava il nome del file di output
strcpy(nome_file,(getenv(QUERY_STRING)); // il nome indicato
sopra come filedioutput
//  cgi?filedioutput
leggi da stdin dim caratteri
totale_letti=0;
while(totale<dim)
{
   Bytes_ricevuti=read(stdin->fd,tmp,4096));  // tmp è int
tmp[4097];
   if(Bytes_ricevuti==0)
   {
     totale=dim + 100; // così se ci sono problemi ti
assicuri l'uscita dal ciclo
   }
   totale=totale+Bytes_ricevuti;
   fwrite(tmp,(int)Bytes_ricevuti,1,out));   // FILE *out
out=fopen "nomefiletemporaneo","w");
}
In breve: devi scrivere su un file temporaneo perchè i dati
che ricevi sono strutturati a pacchetti
di questo tipo:
-----------------------------7cf8cc94c
Content-Disposition: form-data; name="file1";
filename="C:\WINDOWS\Desktop\foto\scrollbox.gif"
Content-Type: image/gif
GIF89a    ³     ÿk ÿO9ÿ"
Jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù      ,          S È
ª 3K+º - |ä?mä ª$6vk { ,ßCWã|°ó7ß  ü WBÁ1-\" Ë¦s
uV£Ð£0 °n¹Z®<K-'Å"³ú|¢TÖÂ¶?p i" ;
-----------------------------7cf8cc94c
Content-Disposition: form-data; name="COMMENTS1"
Dati scritti nel textarea
-----------------------------7cf8cc94c
Content-Disposition: form-data; name="nominativo"
dati presi da input1
-----------------------------7cf8cc94c
Content-Disposition: form-data; name="email"
dati presi da input 2
-----------------------------7cf8cc94c--
La prima parte del pacchetto contiene la gif che ho spedito
con input type=file
la seconda parte contiene i dati di una textarea
la terza e la quarta parte contengono dei dati presi da
input.
Dunque ti leggi il file, filtri i dati di interesse e li
riscrivi su filedioutput.
N.B. ti faccio scrivere su un file temporaneo e non ti
faccio filtrare i dati durante la lettura perchè
rischi di perdere dei caratteri o di perdere la connessione.
Un ultima cosa e poi concludo, la ricezione dei dati tramite
form
segue le specifiche del RFC 1867 del tutto sperimentali e
poco chiare, persino l'upload file della Microsoft ha dei
bachi, per rifare il programma in modo professionale ho
dovuto scrivere più di 500 righe di codice.......
--
Bye
Ro<*¿*>berto