Una interfaz nativa Fortran-77 CGI

Wir wollen Eingabeparameter übergeben und eine Datei von einem Webbrowser auf ein f77 fortran-Programm auf einem Apache-Webserver hochladen, konnten aber keine brauchbaren Informationen dazu finden. Unser Ziel ist es, keine Bibliotheken, kein Perl und nichts außer dem Standard f77 zu verwenden, wie es mit FreeBSD kommt. Es gibt einige Einschränkungen aufgrund der fehlenden Allgemeingültigkeit in f77 I / O, aber es tut was wir brauchen, ganz einfach und in nur wenigen Codezeilen.

Parameterübergabe

Hier ist ein Beispiel für eine Seite, die nach zwei Werten fragt und sie an ein Fortran-Programm weiterleitet, das eine HTML-Antwort schreibt:

<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”>

</html>

Die “POST” -Methode der Parameterübergabe wird gewählt, weil sie Daten über die Standardeingabe an die ausführbare Datei überträgt. Die alternative “GET” -Methode verwendet Umgebungsvariablen, auf die Standard Fortran-77 nicht zugreifen kann. Der Text, der an test1.cgi übergeben wird, befindet sich in einer eindeutig für Fortran nicht geeigneten Zeichenfolge wie:

& val1 = abcd & val2 = 1234

Dies ist nicht leicht in fortran zu analysieren, da die Spaltenpositionen der Werte entsprechend der Länge der Namen und Werte über die Zeichenfolge verschoben werden. Da Sie jedoch die Länge der Variablennamen auf der HTML-Seite steuern, können Sie die Spalte steuern Speicherorte der Daten im Spezialfall, dass die Variableninhalte feste Länge haben, was bei Selektionen, Checkboxen und Optionsfeldern der Fall ist. In diesen Fällen kann ein einfaches Lesen im festen Format die variablen Daten extrahieren. Für mein Beispiel müssen Sie in jedes Feld 4 Zeichen eingeben, um die korrekte Ausgabe zu erhalten, aber ich schlage dies nicht als allgemeine Lösung vor. Das wird später beschrieben.

Hier ist test1.for was einen kooperativen Benutzer annimmt.

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

Es muss kompiliert werden:

f77 test1.für -o test1.cgi

in test1.cgi (der .cgi-Dateityp wird von Apache benötigt), benötigt jedoch keine speziellen Bibliotheken: Sie können keine Free-Format-Schreibvorgänge für den Inhaltstyp verwenden, da dies in Spalte 1 beginnen muss. Der doppelte Schrägstrich ist erforderlich, sonst erhalten Sie nur einen Serverfehler (“Vorzeitiges Ende der Header” im Protokoll), wie Sie es tun werden, wenn Sie überhaupt keinen Header bereitstellen. Ungünstigerweise gehen Fehlermeldungen zu error_log.

Da wir im Beispiel Textfelder verwendet haben, ist das Programm eher spezialisiert! Ich werde diskutieren eine bessere Methode für die Weitergabe von Variablen Länge Stiche. Es besteht die Möglichkeit, dass der Browser die Werte in einer anderen Reihenfolge präsentiert – es gibt eine Option “Tabindex”, um dies zu verhindern, aber ich habe es noch nicht mit benötigt Aktuelle Versionen von Safari, MSIE und Firefox, die einzigen Browser, die ich getestet habe.

Hochladen von Dateien

Außerdem müssen Benutzer eine ASCII-Textdatei hochladen können. Dateien werden als MIME-Anhänge an die Standardeingabe übergeben, sind aber immer noch recht einfach. Hier ist der HTML-Code für ein Beispiel:

Hochladen von Dateien

Außerdem müssen Benutzer eine ASCII-Textdatei hochladen können. Dateien werden als MIME-Anhänge an die Standardeingabe übergeben, sind aber immer noch recht einfach. Hier ist der HTML-Code für ein Beispiel:

<html>

<Form method=”POST” action=”./test2.cgi” ENCTYPE=”multipart/form-data”>

<input name=”userfile” type=”file” value=””><br>

<Input Type=”submit” value=” Submit”>

</html>

Der Browser liefert die Datei als MIME-Anhang an den Server. Hier ist der Fortran-Code für das Beispiel, es kopiert die Header und die Datei zurück zum Browser für die Anzeige.

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

Ich habe eine Testdatei für das Hochladen vorbereitet, bestehend aus drei Zeilen “Zeile 1”, “Zeile 2” und “Zeile 3”. Hier ist das Ergebnis, das vom Browser für das CGI-Programm erstellt wurde:

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–

In der ersten Zeile werden die Dateitrennzeichenfolge, dann mehrere Headerzeilen, die übertragen werden, gefolgt von einer Leerzeile, um das Ende der Header anzuzeigen, gefolgt von der Datei selbst und dem Dateitrennzeichen (plus 2 Bindestrichen). Der 72-Zeichen-Eingabepuffer war nicht lang genug, um die zweite Kopfzeile mit dem Dateinamen zu halten, so dass dieser abgeschnitten und das Lesen nach dem Zeilenende fortgesetzt wurde.

Es gibt hier ein Nusisance-Problem, das beim Ausführen des obigen Testprogramms nicht offensichtlich ist. Der Browser sendet die Datei mit einer Zeilenendekonvention crlf oder (hex) 0d0a, während unser Server Unix ist, der ein einzelnes Zeichen (0a) verwendet. f77 verwirft die 0d beim Lesen nicht, so dass jede Zeile mit 0d endet. Wenn Sie eine Nullzeile in eine Zeichenvariable einlesen, erhalten Sie ein 0d-Recht, das mit Leerzeichen gefüllt ist. In der Praxis habe ich festgestellt, dass das Code-Snippet:

5      read(*,*) a

if(a(1:1).ge.’!’) goto 5

Überspringt nicht leere Zeilen, da ASCII-Zeichen größer als alle Leerzeichen und weniger als alle anderen druckbaren Zeichen sind. Mit dem Standard f77 wird es nicht möglich sein, Binärdateien zu lesen – das stört uns im Moment nicht.

Ich habe das auf unseren FreeBSD-Systemen mit MSIE und Firefox mit f77 und g95 getestet. Ein Korrespondent weist darauf hin, dass Gfortran ersticken wird, wenn man darum bittet, ein “a” -Format zu lesen, das sich über das Zeilenende hinaus erstreckt. Anstatt die verfügbaren Zeichen bis zum Zeilenende zu kopieren, liest es weiter in die nächste Zeile. Dies würde diesen Compiler für diesen Zweck ungeeignet machen.

Textfelder mit variabler Länge

Wir müssen Parameterfelder mit variabler Länge lesen. Der Trick besteht darin, den MIME-Typ “multi-part / form-data” zu verwenden, um die Text- und numerischen Felder in separate Zeilen zu trennen und dann einen Fortran-Free-Format-Read auf den Datenzeilen zu verwenden (Header überspringen). Dieser Formulartyp ermöglicht auch das Hochladen von Dateien. Ein Beispiel:

<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”>

</html>

Bei dieser Methode wird jeder Parameter als separater MIME-Teil an die Standardeingabe übergeben, ebenso wie die Datei zum Hochladen. Hier ist, was an den Fortran weitergegeben wird (mit vorangestellten Zeilennummern):

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–

Hier ist der Fortran, um auf diese Webseite zu antworten:

Bis jetzt waren alle meine Felder numerisch, und das gelesene f77-freie Format betrachtet 0d als ein gültiges Trennzeichen zwischen numerischen Feldern. Das Lesen von Zeichen erfordert das Löschen des letzten Nicht-Leerzeichens, da es immer 0d ist.

Kommentare, Vorschläge und Links sind sehr willkommen, bitte schreiben Sie mir an die unten stehende Adresse. Ich bin besonders daran interessiert, inwieweit diese Techniken browser-, server- oder compilerspezifisch sind oder anderweitig begrenzt sind. Ich erwarte auch, dass es einen Weg gibt, die Probleme mit der Zeilenendung zu vermeiden, die mir nicht bewusst sind – wenn Sie das wissen, hoffe ich, dass Sie mich informieren werden.

Russell Hyer hat ein Beispiel zum Lesen von Variablen aus der Linux-Umgebung gesendet, das jedoch eine nicht standardisierte (aber gebräuchliche) “getenv” -Systemfunktion erfordert.

Ich habe von Clive Page gehört, dass auf seinem System die Webseite nicht an den Browser gesendet wird, bis das Fortran-Programm endet:

Ich habe all diese Dinge versucht – Schließen der Ausgabe, Spülen, etc. Ich habe 3 Compiler (G95, Gfortran und Nag) ausprobiert und alle können die Standardausgabe schließen, soweit ich das beurteilen kann. Ich bin ziemlich sicher, dass die CGI-Ausgabe nicht als abgeschlossen erklärt wird, bis der Prozess beendet wird. Selbst wenn Sie die Nachricht senden und möglicherweise damit rechnen, dass die Seite beendet wird, sieht der Benutzer, dass der Browser eine Besetztzustandsbedingung aufweist, bis der CGI-Prozess (und alle Subprozesse) schließlich beendet werden. Das kann eine Funktion unseres Webservers (Apache) sein.

Das ist weder meine Erfahrung, noch können wir beide verstehen, was der Unterschied in den Systemen sein könnte.

Ein anderer Korrespondent berichtet, dass seine Intel-Compiler-Leseanweisung die Standardeingabe vom Microsoft-Webserver nicht lesen kann. Die getc-Funktion funktioniert jedoch für ihn.

Kürzlich habe ich damit gearbeitet und festgestellt, dass die Inhaltstypzeile nicht mehr den Feldnamen anzeigt. Ich bin mir nicht sicher, warum das so ist. Außerdem bemerke ich, dass nicht markierte Kontrollkästchen in der Standardeingabe überhaupt nicht angezeigt werden, wodurch Kontrollkästchen unbrauchbar werden. Radioboxen funktionieren.

Eine Online-Version von echo.for ist verfügbar unter (kein Hotlink), wo Sie es für Testzwecke verwenden können. Ändern Sie einfach den href in Ihrer Webseite, um auf diese Seite zu zeigen und unser Server wird Ihnen zurücksenden, egal was der Browser sendet. So ähnlich wie eine umgekehrte “Quelle zeigen”.

Daniel Feenberg

Nationales Büro für Wirtschaftsforschung

617-588-0343

feenberg isat nber dotte org

Daniel Feenberg

Nationales Büro für Wirtschaftsforschung

617-588-0343

feenberg isat nber dotte org

Link to original source:http://www.nber.org/sys-admin/fortran-cgi/