Compilers Tutorials/Papers Libs/Sources Newsgroups FAQ Forums/Lists
GNU Modula-2 Modula-2 CGI Tutorial Howto Setup a Fine Modula-2 Environment Programming with Modula-2 Misc. Modula-2 Related Pages Not-English Modula-2 Pages Downloads Please Sign My Guestbook Code Search
I've stopped writing this thing. There are quite a lot of good tutorials for CGI programming in different languages available wich can easily be used to learn the techniques. I'll leave this here as it may still be useful to someone (It also has been there before these pages were called "Modula-2 Pages"). Maybe I'll write on one day.
If you want to have a look at the output of simple Modula-2 CGI programs wich can be written after learning from this tutorial click here.
As you may know, CGI is most times recognized as an interface used by scripting-languages. Perl and PHP are the most common used languages in this context. If you have lots of time and even more fun learning new computer languages, go on and have a look at those dialects. They offer more than enough power and flexibility for nearly every task you'd like to manage. Reality seems to bite some who take this look. Perl is a thinking-expensive language, PHP also, although it uses a different approach. Most people familiar to Pascal are simply distracted from these languages when first trying to alter or write such thing. The Turbo-Pascal-World - resulting in the Delphi-World - has chosen its language 'cause of easyness. Exactly thats the point covered by this tutorial: Get the power of Niklaus Wirth's language-familiy and use the CGI. By the way: You can use nearly every compiler available to write CGI-programs. If you learn from this tutorial without using a Modula-2 compiler, just check your prefered compiler for two things - (1) is it able to read environment variables and (2) can it handle standard in- and output? Without these abilities you are doomed, otherwise just go on.
Well - why Modula-2? Simple question: There are some small, command-line driven compilers for this dialect that are even free. Every Pascal-programmer is able to understand Modula-2, and (as you may have guessed) I simply like the language. This tutorial uses the XDS-Modula-2 compiler, wich is available for linux and windows. In comparison to commercial C++ or Ada compilers XDS produces really small executables.
Before I begin to explain the basics of CGI, you should also download a free www-server to test your first programming approaches without uploading them to the web. As there are a lot of things possibly running out of control 'cause of small mistakes I RECOMMEND you do such an installation. It does not do any harm to your existing internet-setup(s). And by the way: If you think of a server as an incredible huge program - have a look. And it's even not as small as it can get.
Here are a few links to download free server-software:
If you are using a cable-modem and are not sure about running Xitami or Apache (providers do not like people setting up http-servers), do the following: If you do not have one, install a firewall, e.g. ZoneAlarm. After installing, start the firewall and your http-server. The firewall gives you the power to give only those rights to programs that you want them to have. Using ZoneAlarm, just open the expanded main-window and goto the programs-section. your server should be listed here. disallow it to connect to the internet and to act as a server, but give it permission to act as a server for the LAN. That's it: you have a local CGI-testing-machine.
Now we'll jump into it by having a look at a very simple program, that does absolutely nothing except reading one of the predefined CGI-environment variables. It does not process any information sent to the server by a user. The variable used here is called GATEWAY_INTERFACE and holds the version number of the CGI used by your server (If you want to have a look at a list of predefined CGI-variables, follow this link). The code is not beautiful Modula, but it shows a few things very well.
MODULE test_cgi;
FROM InOut IMPORT WriteString;
FROM ProgEnv IMPORT String; (* line 3 *)
TYPE aString = ARRAY [0 .. 255] OF CHAR;
PROCEDURE ReadEnvVar;
VAR Value: aString;
BEGIN
WriteString("Content-type: text/html");
WriteLn;WriteLn;
WriteString("<table border=1 width=80% align=center cellpadding=4>");
String("GATEWAY_INTERFACE",Wert);
WriteString("<tr><td>GATEWAY_INTERFACE:</td>");
WriteString("<td>");
WriteString(Wert);WriteString("</td></tr>");
WriteString("</table>");
END ReadEnvVar;
BEGIN
WriteString("<html><body><h3 align=center>cgi compiled with XDS Modula-2</h3>");
ReadEnvVar;
WriteString("</body></html>");
END test_cgi.
First have a look at line 3: the imported procedure String is essential to programming the CGI. The corresponding procedures for other compilers are:
The other imported procedure "WriteString" should be well known - it sends data to your standard output. Don't tell me how dumb the code above is: it does not have to be beautiful to show the basic concept...
After compiling the program, you have to put in in the cgi-directory of your server. Call it via your browser by typing the full path to it: with my testing-environment, this adress looks like this:
http://127.0.0.1:1080/cgi-bin/test_cgi.exe
As this program does not make any sense, we'll move on and have a look at processing user-input from a html-form. The easy example below uses "method get" to send a simple string to the cgi-program. This method puts the user-input in the environment-variable "QUERY_STRING". You can read the contents of this var as shown above. But first we'll have to write this simple html-file:
<html><head><title>simple input</title></head><body>
<form action="http://127.0.0.1:1080/cgi-bin/user_dta.exe" method="get">
your input:<input name="eingabe" type="text" size="30" maxlength="30">
</form></body></html>
This provides a simple input-field and tells the browser to send the user-input to the program located at http://127.0.0.1/cgi-bin/ - this may differ on your machine, it depends on how you set up your server (In this case the server runs on my local machine and uses port 1080).
Now we have to write the code for the called program "user_dta.exe" (or for example "user_dta.cgi" under Linux). Again, you only need to import String and WriteString, the program simply returns the user input in a dynamically generated super-simple html-page:
MODULE user_dta;
FROM InOut IMPORT WriteString;
FROM ProgEnv IMPORT String;
TYPE aString = ARRAY [0 .. 255] OF CHAR;
PROCEDURE OutputData;
VAR UserInput: aString;
BEGIN
String("QUERY_STRING",UserInput);
WriteString("<p align=center>here's your unprocessed input: ");
WriteString(UserInput);WriteString("</p>");
END OutputData;
BEGIN
WriteString("Content-type: text/html");
WriteLn;WriteLn;
WriteString("<html><body><h3 align=center>cgi compiled with XDS-Modula-2</h3>");
OutputData;
WriteString("</body></html>");
END user_dta.
That's it. You can do whatever you want with the data sent to you.
What about modules? What's happened to the great features of Modula-2? Why should I use it with the Common Gateway Interface? Let's move on. If you're already bored by the simplicity of the examples above, read on. We now have to do some more simple work after wich we'll write a more complex routine to do the URL-decoding. After that we'll concentrate on putting together some bigger reusable modules. One for html-output, one for applying CSS to our dynamically generated pages, another one for cgi-specific routines.
For a start I think it's quite a good idea to create our first package. As you may know you have to create two files: one for the specification, another one for the implementation. Let's call these two files 'M2_CGI.def' and 'M2_CGI.mod'.
The Specification with the declaration of a first procedure:
DEFINITION MODULE M2_CGI;
PROCEDURE CGI_Header;
END M2_CGI.
And the implementation-part:
IMPLEMENTATION MODULE M2_CGI;
PROCEDURE CGI_Header;
WriteString("Content-type: text/html");
WriteLn;WriteLn;
END CGI_Header;
END M2_CGI.
You already know the procedure we just defined and 'implemented' - it outputs just a short header to the client (usually your browser), so the client knows what information will follow - here this is output of type text/html. You have to call this procedure every time before doing anything else from a CGI-program. Would be slightly illogical to write another procedure before this one...