dynamic documents and forms
Sometimes it is not enough to redisplay all your finished documents over and over again. Maybe you want to insert 'fresh' data while requesting the file. In the easiest case this is, for instance, the displaying of the current time (but this is much esier to achieve), but it can also be a database request.
To realize that, the web server provides the Common Gateway Interface (CGI).
what is CGI
The Common Gateway Interface (CGI) is an interface between the www-server and applicable programs. Basically, it defines how the information is passed to the program. In general every applicable program can be requested via the CGI. Given that, scripts are much easier to develop and debug. All following explainations regard only those.
Documents in a specific directory (in general /cgi-bin) will be automatically recognoized as applicable programs by the server.
How does it work?
The server defines a set of environment variables and invokes the program. Variables for simple applications are:
REQUEST_METHOD In the GET method all arguments will be delivered via the QUERY_STRING variable. POST delivers data of the standard input.
CONTENT_LENGTH only with POST; length of the data stream in byte. QUERY_STRING arguments, which are added to the script url with a question mark (?); in the GET request the browser will handle this automatically, in the POST method further arguments could be delivered this way.
No matter which tansfer method is chosen, only numbers, letters and the signs * - . _ will be transferred unencrypted. All other signs will be URL encoded. That is to say instead of one sign, a % followed by a hexadecimal value of the sign will be transferred. The only exception is the space character, which will be replaced by a +. For instance 'Olaf Großmann' will be transformed to 'Olaf+Gro%DFmann'.
CGIWRAP
As briefly mentioned before, the server expects CGI programs only in a specific directory (/cgi-bin). Of course, regular users don't have writing access to this. In order to enable own CGI-scripts, the program cgiwrap is installed.
Advices
- While the server's access to normal documents occurs under an anonymous login (in most cases nobody or www), cgiwrap uses the rights of the owner of the files. The advantage (and also a gain of security) is that script generated output files don't have to be writable for the 'world' anymore, but just for their owners.
- Against all assertions in the Man-Page , cgiwrap also works with the GET method without any tricks, when the form http://rcswww.urz.tu-dresden.de/cgi-bin/cgiwrap/<USER>/<SCRIPTNAME>
is used. - If nothing is going to work, cgiwrapd will give further help.
own scripts
Enough of the appetizers; let's get to the real meat of our topic! The following rules should give you a proper introduction:
Which Interpreter
During a script call, the system cannot be sure how - that is to say with which interpreter (Bourne-/Korn-Shell, Perl) - to execute it. Thus, the 'magic' first line is really important. A Bourne-Shell script strictly starts with:
#!/bin/sh |
A Perl script starts with:
#!/usr/bin/perl |
Alternatively you can use /bin/ksh for the Korn-Shell, /bin/bash for the Bash-Shell or /bin/csh for the C-Shell.
Parameter Passing
The passed paramters are possibly URL-encoded and will be passed either in the variable QUERY_STRING or in the standard input, depending on the used method (GET or POST). The easiest way to handle that is to use the helping program cgiparse. The call cgiparse -form sets the variable FORM_<name>.
In a shell script, the call occurs with eval:
eval `/usr/local/bin/cgiparse -form` |
Hints:
- Don't forget to declare the complete path! The server just searches in a few sytem paths.
- With eval the output will be adopted in the script. Please don't forget the back quotes (`)!
- The possibility mentioned above to pass data via POST and simultaneously append further data to the URL via question mark doesn't work with cgiparse. If you need that, you can pass hidden fields with <input type="hidden">, or use another program for parsing the input.
The Output is ...
It is not mandatory, but a CGI script will normally deliver a HTML text as output. The server, however, doesn't know what he gets. Given that, a header has to be generated first. In the standard case
Content-Type: text/html
followed by a blank line (this is nessecary) is adequate.
In order to generate more complex headers (for instance, if you want to declare how long a file will be valid and stored by other servers) the program cgiutils should be suitable.
All Together
The following little script shows up the time. When the argument "LANG=de" is passed, the ouput will be in the german time format. Otherwise the english time format is default.
#!/bin/sh # # 1.adopt parameters eval `/usr/local/bin/cgiparse -form` # 2. HTTP header output, don' forget the blank line echo "Content-Type: text/html" echo # 3. HTML header echo "<html><body>" # 4. the actual program # time in german? if [ "$FORM_LANG" = "de" ]; then echo "<h2>Die aktuelle Zeit ist</h2>" LANG=De_DE export LANG else echo "<h2>The current time is</h2>" fi date # 5. don't forget the end of the html skeleton echo "</body></html>" |
The link has to be:
current time <a href="/cgi-bin/cgiwrap/petrick/getdate"> aktuelle Zeit <a href="/cgi-bin/cgiwrap/petrick/getdate?LANG=de">
caution with programs
Whereas scripts are executable on different operating systems, compiled programs are not. If one wants to use own programs (for instance written in Fortran or C), they have to be translated to the same system the web server is running and starting programs on. In our case that's Linux. To avoid problems with missing program libraries, the program should be translated into static binary (compiler option -static).
Forms
To create an interactive form, use the element <FORM>. The description of the different input fields (INPUT, SELECT, TEXTAREA) can be found at HTML-Reference.
Some advices regarding CGI programming:
- ACTION should always be specified. It usually references to a script in the own cgi-bin directory via cgiwrap.
- Password fields should be avoided if possible (the transmission is unencrypted).
- In a document only one <FORM> element can be declared.
Examples
Because of the last mentioned restriction, the examples are placed in seperate files.
It doesn't always have to be cgi scirpt...
For simple applications so called Server Side Includes (SSI) can be used. SSIs are special command lines, which are read by the HTTP server and adequately replaced.
The syntax is:
<!--# command parameter="value" parameter="value" ... --> |
Commands
config defines output format. Config is valid for the whole document or rather until the next config.
Parameters:
- errmsg thrown out text message, in the case of a parsing error.
- sizefmt output size format. Possible values are bytes and abbrev in KB respectively MB.
- timefmt output time format. The format string equals strftime(3).
echo shows an internal variable. The one and only possible parameter is var. exec executes a script. This is blocked by default on most servers (also on ours). fsize shows the filesize. Parameters are file and virtual (s. include). flastmod shows the date of the last file change. Parameters again: file and virtual. include includes another document.
Parameter:
- file relative document path. Caution!!! It doesn't work, if the containing directory (e.g. home) is not readable for the web server!
- virtual document URL (absolute oder relative) on the same server.
Variables
Following internal variables are available.
DATE_LOCAL local time
DATE_GMT Greenwhich time
LAST_MODIFIED date of the last file change.
DOCUMENT_NAME name of the current document
DOCUMENT_URI document URL
Additionally, the following variables are supported, too:
USER_NAME
DOCUMENT_PATH_INFO
QUERY_STRING_UNESCAPED
Examples
- When has the document been modifiend the last time?
Last updated:
<!--#echo var="LAST_MODIFIED" --> - Likewise, but in the german time format:
Last change at:
<!--#config timefmt="%d.%m.%Y" -->
<!--#echo var="LAST_MODIFIED" -->