En infödd Fortran-77 CGI-gränssnitt

Original: http://www.nber.org/sys-admin/fortran-cgi/

Vi vill passera inparametrar och ladda upp en fil från en webbläsare till en f77 fortran program på en Apache webbserver, men kunde inte hitta mycket användbar information om detta. Vårt mål är att använda några bibliotek, ingen Perl, och ingenting utöver standard f77 precis som den kommer med FreeBSD. Det finns vissa begränsningar på grund av bristen på allmän i F77 I / O, men det gör det vi behöver ganska rättframt och på bara några rader kod.

Parameteröverföring

Här är ett exempel på en sida som frågar efter två värden, passerar dem till en fortran program som skriver en HTML svar:
Vänligen fyll varje låda med 4 tecken ..

De “POST” metod för parameteröverföring har valts eftersom den överför data till den körbara filen genom standard in. Alternativet “GET” metod använder miljövariabler, som inte kan nås från standard Fortran-77. Texten skickas till test1.cgi är en avgjort fortran icke vänliga sträng som:
& val1 = abcd & val2 = 1234
Detta är inte lätt att tolka i Fortran sedan kolumn placeringen av värdena kommer att glida över sträng enligt längderna av namn och värden – men eftersom du styr längden på variabelnamn på HTML-sidan, kan du styra kolumnen platser för data i det särskilda fallet att de rörliga innehållet fast längd, vilket är fallet för val, kryssrutor och alternativknappar. I de fall en enkel fast läsning formatet kan extrahera variabeldata. Till mitt exempel måste du ange 4 tecken i varje ruta för att få rätt utgång men jag tror inte att föreslå detta som en generell lösning. Detta beskrivs senare.

Här är test1.for som antar ett kooperativ användar :.
tecknet * 19 en skrivning (*, 100) 100-format (“Content-Type: text / html ‘//) läsa (*, *) en skrivning (*, *)'” write (*, *) ‘här är vad test1.cgi ser: “write (*,” (A72) ‘) en skrivning (*, *)’

‘write (*, *)’ Första rutan: “, en (6: 9), ‘
“write (*, *)” Andra rutan: “, en (16:19),’ ‘banslutets
Det måste sammanställas:
f77 test1.for -o test1.cgi
in test1.cgi (den .cgi filetype krävs av Apache), men behöver inte några speciella bibliotek: Du kan inte använda fritt format skriver för Content-typen eftersom det måste börja i kolumn 1. Den dubbla snedstreck är krävs, annars kommer du bara få ett serverfel (“för tidigt slut på rubriker” i loggen), som du kommer om du ger ingen rubrik alls. Olämpligt, felmeddelanden går till error_log.

Eftersom vi använde textrutor i exemplet, är programmet ganska specialiserade! I “ll diskutera en bättre metod för att passera längd svider variabla nedan Det finns möjlighet att webbläsaren kommer att presentera värdena i någon annan ordning -. Det finns ett alternativ” tabIndex “för att förhindra detta, men jag har inte behövt det ännu med senaste versionerna av Safari, MSIE och Firefox, de enda webbläsare som jag har testat.

Ladda upp filer

Vi måste också låta användare ladda upp en ASCII-textfil. Filerna skickas som MIME-bilagor till standard in men är fortfarande ganska enkel. Här är html för ett exempel:

Den första raden etablerar filen separatorn strängen, sedan flera huvudrader descrbe vad som sänds, sedan en tom rad för att signalera slutet av rubriker, då själva filen, och sedan filen separatorn igen (plus ytterligare 2 streck). De 72 tecken inbuffert var inte tillräckligt lång för att hålla den 2: a rubrikraden med filnamnet, så det var stympade och läsning återupptogs efter newline.

Det finns en nusisance problem här som inte är uppenbart från att köra testprogrammet ovan. Webbläsaren skickar filen med en linje som avslutas konvention CRLF eller (hex) 0d0a, medan vår server är Unix, som använder en enda tecken (0a). F77 inte kassera 0d när man läser, så varje rad avslutas med 0d. Läsa en null linje i en karaktär variabel ger dig en 0d rättighet fylld med mellanslag. I praktiken har jag funnit att kodavsnittet:
5 read (*, *) a om (a (1:. ‘! “1) .ge) goto 5
hoppar icke-tomma rader eftersom ASCII bang är större än alla blank och mindre än någon annan utskrivbara tecken. Med standard F77 kommer det inte att vara möjligt att läsa binära filer – som inte bry oss för tillfället.

Jag har testat detta på våra FreeBSD system med MSIE och Firefox, med F77 och G95. En korrespondent påpekar att gfortran kommer kvävas när de ombads att läsa en “en” post-format som sträcker bortom slutet av linjen. Istället för att kopiera de tillgängliga tecknen fram till slutet av raden det fortsätter att läsa på nästa rad. Detta skulle göra att kompilatorn olämpligt för detta ändamål.
Variabel längd textfält

Vi behöver läsa variabla parameterlängd fält. Tricket är att använda “multi-delen / form-data” MIME-typ, för att separera texten och numeriska fält på separata rader, och sedan använda en fortran fritt format läsa på datalinjerna (hoppa rubrikerna). Denna typ formulär medger även att ladda upp filer. Ett exempel:
Fyll i tomrummen.

Med denna metod varje parameter skickas som en separat MIME del till standard input, så är filen för uppladdning. Här är vad som överföres till fortran (med prepended radnummer):
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”; filnamn = “test.txt” 11 Content-Type: text / plain 12 13 linje 1 14 linje 2 15 rad 3 16 17 ———— 0xKhTmLbOuNdArY–
Här är fortran att svara på den webbsidan:
tecknet * 72 en data x / -9999 ./, nrec / 0 / write (*, 100) 100-format (“Content-Type: text / html” //) write (*, *) “Här är de värden ses av fortran:

“5 read (*,” (A72) ‘) a om (a (1:.’! “1) .gt) goto 5 read (*, *, err = 6) x 6 läs (*, *) a om (a (1:. ‘! “1) .gt) goto 6 read (*,” (A20)’) en skrivning (*, *) ‘x =’, x, ‘

‘write (*, *)’ a = ‘, en,’

“write (*, *) ‘Här är filen till radnummer:

‘ 7 read (*, *) a om (a (1: 1) .gt. ‘!’) goto 7 8 fortsätter läsa (*, “(A72), end = 99) en nrec = nrec + 1 om (a (1:10) .ne”. ———- “) goto 8 write (*,” (i4,1x, A72, a4) ‘) nrec, en,’

“99 fortsätter write (*, *) ‘ “stopp änden

Hittills har alla mina fält varit numeriska, och f77 fritt format läst gör avseende 0d som en giltig avgränsare mellan numeriska fält. Karaktär läser kommer att kräva att ta bort den sista icke-tomt, som det alltid kommer att 0D.

Kommentarer, förslag och länkar är mycket välkomna, skriv till mig på adressen nedan. Jag är särskilt intresserad av i vilken utsträckning dessa tekniker är webbläsare, server, eller kompilator specifik, eller på annat sätt begränsad. Dessutom förväntar jag mig att det kan finnas något sätt att undvika linje som avslutas problem som jag inte känner till – om du vet, jag hoppas du kommer att informera mig.

Jag har hört från Clive sidan som på sitt system webbsidan inte skickas till webbläsaren tills Fortran program avslutas: Jag har provat alla dessa saker – stänga produktionen, spola det, etc. Jag har provat 3 kompilatorer (G95, gfortran och Nag) och alla kan stänga standard ut så långt jag kan säga. Jag är ganska säker på att CGI utgången inte förklaras vara klar tills processen avslutas. Så även om du skickar och kan förvänta sidan vara klar, ser användaren webbläsaren visar en upptagen tillstånd, höger tills CGI processen (och eventuella delprocesser) äntligen avsluta. Det kan vara en funktion av vår webbserver (Apache). Detta har inte varit min erfarenhet, inte heller kan någon av oss förstår vad skillnaden i system kan vara.

En annan korrespondent rapporterar att hans Intel kompilator läst uttalandet inte kan läsa standard in från Microsoft webbserver. Däremot ser getc funktionen fungerar för honom.

Nyligen har jag arbetat med detta och fann Content-Type linjen inte längre visar fältnamnet. Jag är inte säker på varför det är så. Också, jag märker att okontrollerade kryssrutor inte dyker upp i standard input alls – vilket gör kryssrutor oanvändbar. Radiolådor utföra arbete.

En onlineversion av echo.for finns på http://www.nber.org/sys-admin/fortran-cgi/echo.cgi (inte en het länk) där du kan använda den för teständamål. Bara ändra href i din webbsida för att peka på den sidan och och vår server kommer att eka tillbaka till dig oavsett webbläsaren skickar det. Ungefär som en omvänd “show källa”.

Daniel Feenberg
National Bureau of Economic Research
617-588-0343
feenberg ISAT NBER dotte org