Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web servers, web development, networking and security services. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Matični Fortran-77 CGI interfejs


Želimo da prosledimo ulazne parametre i upload-ujemo fajl sa web browser-a na program f77 Fortran, koji se nalazi na Apache web serveru, ali nismo uspeli da pronađemo korisne informacije o tome. Naš cilj je da ne koristimo biblioteke, Perl, i ništa van standardnog f77 koji dolaze sa programom FreeBSD. Postoje neka ograničenja zbog nedostatka opštosti u f77 I/O jedinicama, ali ona rade upravo ono što nam je veoma potrebno i to samo u nekoliko linija koda.

Prosleđivanje parametara


Ovde je prikazan primer stranice koja traži dve vrednosti i prosleđuje ih programu FORTRAN, koji ispisuje HTML odgovor:
<html> Please fill each box with 4 characters.. <form method="POST" action="./test1.cgi"> <input name="val1" type="text" maxlength="20"> <input name="val2" type="text" maxlength="20"> <input type="submit" value=" Submit"> </form></html>
Metod prosleđivanja parametra "POST" je izabran iz razloga što prenosi podatke izvršnom fajlu preko standardnog ulaza. Alternativan "GET" metod koristi promenljive okruženja, koji nisu dostupni iz standardnog programa Fortran-77. Tekst prosleđen promenljivoj test1.cgi je string izrazito neprijateljski nastrojen Fortran-u, kao što je tekst:
&val1=abcd&val2=1234
Ovo nije lako za analiziranje u Fortran-u od iz razloga što će lokacije kolone vrednosti prolaziti kroz string na osnovu dužine imena i vrednosti - ali pošto Vi kontrolišete dužinu imena promenljive na HTML stranici, možete da kontrolišete lokacije kolone podatka u specijalnom slučaju, gde je sadržaj promenljive fiksne dužine, što je slučaj kod polja selection, checkbox i radio button. U tim slučajevima jednostavan fiksan format čitanja može da izdvoji podatke promenljive. Na mom primeru morate da unesete 4 karaktera u svako polje, da biste dobili ispravan izlaz, ali ne predlažem ovo kao opšte rešenje. Ovo je kasnije opisano.

Ovde je test1.for koji pretpostavlja korisnika koji sarađuje:
character*19 a write(*,100) 100 format('Content-type: text/html'//) read(*,*) a write(*,*) '<html>' write(*,*) 'Here is what test1.cgi sees:<br>' write(*,'(a72)') a write(*,*) '<p>' write(*,*) 'First box:',a(6:9),'<br>' write(*,*) 'Second box:',a(16:19),'</html>' stop end
Ovo treba da bude kompajlirano:
f77 test1.for -o test1.cgi
u test1.cgi ( .cgi tip fajla se zahteva od strane Apache-a), ali nisu potrebne nikakve posebne biblioteke: Ne možete da koristite pisanje slobodnog formata za Content-type, jer bi pisanje trebalo da se započne u koloni 1. Dvostruka kosa crta je obavezna, inače ćete samo dobiti grešku servera ("Premature end of headers" u dnevniku), isto i ako uopšte ne obezbedite zaglavlje. Nezgodno, poruke o grešci idu u error_log dnevnik.

Pošto smo koristili text box-ove u primeru, program je prilično specijalizovan! Kasnije ću diskutovati o boljem metodu za prosleđivanje pogotka dužine promenljive. Postoji mogućnost da će browser predstaviti vrednosti u nekom drugom redosledu - postoji opcija "tabindex" da bi se ovo sprečilo, ali meni još nije bila potrebna sa poslednjim verzijama Safari-a, Explorer-a i Firefox-a, browesr-ima koje sam testirao.

Upload fajlova


Takođe je potrebno da dozvolimo korisnicima da upload-uju ASCII tekstualni fajl. Fajlovi su prosleđeni kao MIME prilozi standardnog ulaza, što je i dalje prilično jednostavno. Ovde je prikazan html kod primera:
<html> <form method="POST" action="./test2.cgi" enctype="multipart/form-data"> <input name="userfile" type="file" value=""><br> <input type="submit" value=" Submit"> </form></html>
Browser snabdeva server fajlom kao MIME prilog. Ovde je primer Fortran koda, koji vraća kopiju zaglavlja i fajla browser-u zbog prikaza.
character*72 a write(*,100) 100 format("Content-type: text/html"//) write(*,*)'<html>' do 10 i=1,20 read (*,'(a72)',end=99) a write(*,'(i2,1x,a72,a4)') i,a,"<br>" 10 continue 99 continue write(*,*) "</html>" stop end
Pripremio sam test fajl za upload, koji se sastoji od tri linije, "line 1", "line 2" i "line 3". Ovde je prikazan vraćen rezultat, koji je pripremljen od strane browser-a za CGI program:
1 -----------------------------6535751115256 2 Content-Disposition: form-data; name="userfile"; filename="New Text Docu 3 Content-Type: text/plain 4 5 line 1 6 line 2 7 line 3 8 -----------------------------6535751115256--
Prvi red utvrđuje separator string fajla, zatim sledi nekoliko linija zaglavlja u kojima se opisuje šta se prenosi, onda prazan red koji signalizira kraj zaglavlja, zatim sam fajl, i na kraju ponovo separator fajla (plus još 2 crtice). Bafer od 72 ulazna karaktera nije bio dovoljno dugačak da sadrži drugu liniju zaglavlja sa imenom fajla, tako da je skraćen, i čitanje je nastavljeno nakon novog reda.

Ovde postoji neprijatan problem koji nije očigledan iz prikaza testa navedenog iznad. Browser šalje fajl sa linijom koja se završava skupom crlf ili (heksadecimalni) 0d0a, dok je naš server Unix, koji koristi jedan karakter (0a). F77 ne odbacuje 0d prilikom čitanja, tako da će se svaki red završiti sa 0d. Čitanje null linije u karakternoj promenljivoj daje Vam pravilan 0d ispunjen razmacima. U praksi sam utvrdio da je kod isečen:
5 read(*,*) a if(a(1:1).ge.'!') goto 5
Ovaj deo koda će preskočiti neprazne linije, jer je ASCII kod veći od bilo kog praznog prostora i manji od bilo kog ispisujućeg karaktera. Sa standardnim f77 neće biti moguće čitanje binarnih fajlova - u ovom trenutku to nam ne smeta.

Ovo sam testirao na FreeBSD sistemu sa Explorer-om i Firefox-om, i sa f77 i g95. Dopisnik ističe da će se gFortran “ugušiti” kada bude upitan da pročita "a" stavku formata, koja se proteže duž kraja linije. Umesto kopiranja dostupnih karaktera na kraj linije, nastavlja da učitava na sledeći red. Ovo bi moglo da kompajler učini nepodobnim za ovu namenu.

Dužine promenljive tekstualnih polja


Potrebno je da pročitamo parametar dužine promenljive polja. Trik je da se koristi "multi-part/form-data" MIME tip, da bi se odvojila tekstualna i numerička polja na zasebne linije, a zatim da se koristiti Fortran čitanje slobodnog formata za linije podataka (izostavljajući zaglavlja). Ovaj tip forme takođe omogućava upload fajlova. Primer:
<html> Please fill in the blanks. <form method="POST" action="./test2.cgi" enctype="multipart/form-data"> <input name="val1" type="text" maxlength="40"> <input name="val2" type="text" maxlength="40"> <br> <input name="userfile" type="file" value=""><br> <input type="submit" value=" Submit"> </form></html>
Ovom metodom svaki parametar je prosleđen standardnom ulazu kao poseban MIME deo, isto kao i fajl za upload. Evo šta se prosleđuje Fortran-u (sa pripremljenim brojevima linija):
1 ------------0xKhTmLbOuNdArY 2 Content-Disposition: form-data; name="val1" 3 4 123.999 5 ------------0xKhTmLbOuNdArY 6 Content-Disposition: form-data; name="val2" 7 8 abcd 9 ------------0xKhTmLbOuNdArY 10 Content-Disposition: form-data; name="userfile"; filename="test.txt" 11 Content-Type: text/plain 12 13 line 1 14 line 2 15 line 3 16 17 ------------0xKhTmLbOuNdArY--
Ovde je prikazano šta Fortran odgovora web stranici:
character*72 a data x/-9999./,nrec/0/ write(*,100) 100 format("Content-type: text/html"//) write(*,*) "<html>Here are the values seen by fortran:<br>" 5 read(*,'(a72)') a if(a(1:1).gt.'!') goto 5 read(*,*,err=6) x 6 read(*,*) a if(a(1:1).gt.'!') goto 6 read(*,'(a20)') a write(*,*) 'x=',x,'<br>' write(*,*) 'a=',a,'<br>' write(*,*) 'Here is the file with line numbers added:<br>' 7 read(*,*) a if(a(1:1).gt.'!') goto 7 8 continue read(*,'(a72)',end=99) a nrec= nrec+1 if(a(1:10).ne.'----------') goto 8 write(*,'(i4,1x,a72,a4)') nrec,a,'<br>' 99 continue write(*,*) '</html>' stop end
Do sada su sva moja polja bila numerička i f77 čitanje slobodnog formata posmatra 0d kao validan separator numeričkih polja. Čitanje karaktera će zahtevati brisanje poslednje nepraznine, jer će to uvek biti 0d.

Komentari, sugestije i linkovi su veoma dobrodošli, pišite mi na adresu navedenu ispod. Posebno sam zainteresovan u kojoj meri su ove tehnike specifične za browser, server ili kompajler, ili u suprotnom ograničene. Takođe, očekujem da možda postoji neki način da se izbegnu problemi završnih linija, za koji ja ne znam - ako znate, nadam se da ćete me obavestiti.

Čuo samo od Clive Page-a da na njegovom sistemu web stranica se ne šalje browser-u sve dok se Fortran program ne završi: Pokušao sam sve te stvari - zatvaranje izlaza, flashing, itd. Isprobao sam 3 kompajlera (g95, gfortran i Nag) i svi mogu da zatvore standardni izlaz, koliko ja znam. Prilično sam siguran da CGI izlaz nije deklarisan da bude kompletiran, sve dok se proces ne završi. Dakle, čak i ako ste poslali stranicu, a možda očekujete da bude i završena, korisnik vidi da browser prikazuje zauzeto stanje, i tako sve dok se CGI proces (i bilo koji podprocesi) konačno ne izvrši. To može biti funkcija našeg web servera (Apache). Ovo nije bilo moje iskustvo, niti se bilo ko od nas razume u moguće razlike između sistemima.

Drugi dopisnik izveštava da njegov Intel kompajler za čitanje izjava nije u stanju da pročita standardni ulaz sa Microsoft-ovog web servera. Međutim, getc funkcija mu radi.

Nedavno sam radio sa ovim i pronašao da content-type linija ne pokazuje naziv polja. Nisam siguran zašto je to tako. Takođe, primetio sam da se nečekirani checkbox-ovi uopšte ne pojavljuju u standardnom ulazu - što čini checkbox-ove neupotrebljivim. Radiobox-ovi rade.

Online verzija echo.for-a je dostupna na linku http://www.nber.org/sys-admin/fortran-cgi/echo.cgi (ne vruće link) gde možete da je koristite za svrhe testiranja. Samo promenite href tag u svojoj web stranici da pokazuje na tu stranicu i naš server će vam odgovoriti, nezavisno da li browser šalje stranicu. Nešto poput obrnutog "show source-a".

Daniel Feenberg
Nacionalni biro za ekonomska istraživanja
617-588-0343
feenberg isat nber dotte org



Published (Last edited): 16-09-2012 , source: http://www.nber.org/sys-admin/fortran-cgi/