<P>The <I>Common Gateway Interface</I> (CGI) allows you to write programs which pretend to be ordinary Web pages, but when a client requests them they are executed and the output from the program is sent instead. By using CGI programs you can provide interactive facilities for the users accessing your server. You may have seen access counters on WWW pages which display a small graphic showing how many times the page has been accessed - this is an example of a CGI program.</P>
<P>The CGI program is either a normal program (BASIC, Absolute, Utility) or a script (Obey, Command, Perl) kept in a special directory called <I>cgi-bin</I>. Once invoked the program generates output that the client can use, such as an HTML page or a GIF image. In the case of the access counter program mentioned above, the output is a GIF image.</P>
<P>CGI programs are usually referenced from a normal, static, Web pages, acting as a utility to the master page. For example, when you fill out a form on a Web page and you click on the 'Submit' button, your browser will ask the server for a URL like this :</P>
<P>This means that the CGI program specified by the URL "http://bronze.netplex.net/cgi-bin/form" will be invoked with the parameters "name=Zaphod+Beeblebrox". The '?' character separates the URL of the program and the parameters to be passed to the program. Several named parameters can be passed by separating them with the '&' symbol. For example : </P>
<P>Once invoked, the program will read its parameters and then generate its output which the server will send to the client. This particular type of retrieval is known as the <I>GET method</I>.</P>
<P>The other method used is <I>POST</I>, this is different to GET in that instead of appending the parameters to the URL, it sends them as an additional 'packet' of data (officially called an 'entity') accompanying the request. This has the advantage of allowing much larger amounts of data to be passed, since URLs are limited to a fixed number of characters. POSTs are the preferred method of submitting form data.</P>
<P>In the case of the access counter program mentioned above, the parameters passed to it will be an ID for the user's Web page. The counter program will look up the ID in its database, find the number of times the counter has been requested, increment it, and then generate a GIF file of the number of requests.</P>
<P>HTTP - the service that Web servers provide - is a request-response mechanism. A request is made, so the server generates a response. When a request is made for a CGI program, the server must run it under special conditions so that it is able to send the entire output of the program to the client.</P>
<P>When a program is executing under the CGI, the usual methods of input and output - the keyboard and the screen - are redirected to a pair of disc files. Everything that is input comes from a file on disc containing any data the client has sent to us. Everything that is output is sent to another file on disc which gets sent to the client when the program finishes.</P>
<P>Information on the current request is passed to CGI programs by means of system variables. There are a number of these which Netplex uses, a full list of which is included later on in this document.</P>
<P>There's not much more to it than that, at least for 'simple' CGI programs. However, as of version 0.21, Netplex contains support allowing CGI programs to be multitasking programs. This is more complicated as the program's input and output can no longer be completely taken over by Netplex, since other programs will be running at the same time.</P>
<P>Netplex has to provide a couple of support functions in order to allow CGI programs to multitask. The first is a feature of the server itself, which detects a flag in a system variable indicating that a CGI program wishes to multitask. The second is provided by the CGI support library, which allows the redirection state to be controlled. (This is also essential if you need to run other programs from your CGI program).</P>
<P>A multitasking CGI program will initialise, inform Netplex that it wishes to multitask and then turn off its redirection. The redirection files remain available for use, so all the program has to do in order to process is to read from and write to these files. When the program is about to exit, it turns redirection back on so that the server can start off from where it finished.</P>
<P>Writing CGI programs for use with Netplex is fairly easy, as BASIC can be used to implement them quickly. To start with an example, here's a Web-enabled Hello World program :</P>
<P>The first two PRINT statements are part of the header that is sent to the client. The first line tells the client that the document is HTML text and the second, empty line, terminates the header. Both lines are terminated by 'CHR$(13);CHR$(10);' as the usual PRINT line ending is inapropriate for header fields which must be terminated by CR,LF. The other lines are a simple HTML 'page' which will be displayed in the browser.</P>
<P>As far as things go, this program isn't very interesting - it doesn't actually do anything <I>different</I> every time you run it, which is the point of the CGI system. An easy modification to make it produce different output every time is to replace "Hello World!" with TIME$, which returns the current time :</P>
<P>Now, when the program is fetched, it will return the current time.</P>
<P>To learn more about CGI programming, you should examine the <A HREF="#examples">examples</A> given below.</P>
<H3>The CGI Library</H3>
<P>A BASIC library containing routines for use in CGI programs is provided. Note that the library is not provided simply to make the job of programming CGI easier, it contains support code which is essential to ensure the correct operation of the server when dealing with CGI programs. If you are thinking of programming for Netplex in other languages then you should implement an equivalent of the CGILibrary.</P>
<P>To use the CGILibrary, you should use the following instructions at the start of your program :</P>
<P><PRE>
LIBRARY "<Netplex$Dir>.CGILibrary"
PROCcgi_init
</P></PRE>
<P>This will set up an error handler, dimension a 256-byte block of memory called misc% and will set the variables cgi_in% and cgi_out% to the handles of the input and output data streams respectively.</P>
<P>You should call the routine PROCcgi_closedown at the end of your program.</P>
<P>The library provides the following routines :</P>
<DD>Given the Content-Type and Content-Length, this routine generates an appropriate response header. Content_type$ is given as 'image/gif', 'text/html', etc. Content_length% is the amount of data you are going to be sending, or -1 if you don't know.
<DT><B>PROCcgi_statusline(code%, phrase$)</B>
<DD>If you need to, you may generate an entire HTTP response yourself, including headers. cgi_statusline outputs the initial HTTP status line, which informs the recipient of the version of HTTP in use, the response status code and a short phrase indicating the server's response. You must call cgi_statusline before anything else that will cause output.
<DT><B>PROCcgi_headerline(name$, value$)</B>
<DD>This routine takes care of outputting HTTP headers with the correct line endings. Name$ is the name of the header field and value$ is its value, so cgi_headerline("Cookie","name=cookie_monster") will generate the header line "Cookie: name=cookie_monster". If name$ is an empty string, then cgi_headerline will output an empty line so that the header will be terminated.
<DT><B>PROCcgi_error</B>
<DD>This is automatically called when an error occurs. It cleans up any temporary files and outputs an HTML page describing the error to the client. The error message is also recorded in the log file.
<DT><B>FNcgi_nextelement</B>
<DD>Returns the next parameter passed to the program (POST only).
<DT><B>FNcgi_nextelementdecoded</B>
<DD>As above, but translates all of the escape codes first, by calling FNcgi_decodeelement.
<DT><B>FNcgi_decodeelement(e$)</B>
<DD>Translates all the escape characters (e.g. '%7e') in e$, and returns the translated string.
<DT><B>PROCcgi_redirect(on%)</B>
<DD>Updates the cgi_in% and cgi_out% variables. If on% is FALSE, then redirection is turned off which is necessary with multitasking CGI programs.
<DT><B>PROCcgi_polling(on%)</B>
<DD>Sets or unsets (depending on on%) a system variable ("CGI$Active_...") which lets Netplex know that the CGI program intends to multitask. If you intend to call Wimp_Poll in your program, you <B>must</B> call PROCcgi_polling(TRUE) before you do, and call PROCcgi_polling(FALSE) before the end of your program.</P>
<DT><B>FNmime(filetype%)</B>
<DD>Converts a filetype to a MIME Content-Type.
<DT><B>FNstring_readtoctrl(RETURN p%)</B>
<DD>Returns the string pointed to by p%, and updates p% to point to the first unread character.
<DT><B>FNcase_lower(s$)</B>
<DD>Returns the given string, in lower case.
<DT><B>FNcase_upper(s$)</B>
<DD>Returns the given string, in upper case.
<DT><B>PROCsystem_setliteral(var$, val$)</B>
<DD>Sets the system variable var$ as string val$.
<DT><B>FNsystem_getvar(var$)</B>
<DD>Returns the system variable var$ as a string.
<DT><B>FNsystem_unset(var$)</B>
<DD>Unsets the system variable var$.
</DL>
<H3>CGI System Variables</H3>
<P>Netplex passes information to CGI programs via a set of system variables, which use the prefixes 'CGI$' and 'HTTP$'. Note that this is different to CGI on non-RISC OS servers which have different rules regarding system variables. For example, CGI$ServerSoftware is used rather than SERVER_SOFTWARE. This means that anyone porting CGI software or scripts from other platforms must take this into account, and adjust all references to system variables.</P>
<P>Only some of the following variables may be set, depending on the method the client used and the information it passed.</P>
<H5>Static Variables</H5>
<I>Variables which are constant for the duration of the server.</I>
<DL>
<DT>CGI$ServerSoftware
<DD>Contains the name and version of the server software, e.g. 'Netplex/0.09 (05 Oct 1996)'.
<DT>CGI$ServerName
<DD>Is the fully qualified name of the server. At startup, Netplex will attempt to resolve this from the Inet$LocalIP variable.
<DT>CGI$GatewayInterface
<DD>Always set to "GGI/1.1".
<DT>CGI$ServerPort
<DD>Set to the port that the server is operating on.
</DL>
<H5>Dynamic Variables</H5>
<I>Variables which change according to the request.</I>
<DL>
<DT>CGI$ServerProtocol
<DD>'HTTP/1.1', 'HTTP/1.0' or 'HTTP/0.9' depending on the request received.
<DT>CGI$RequestMethod
<DD>This is set to the request method that was used to retrieve the file, e.g. GET or POST.
<DT>CGI$PathInfo
<DD>If you specify the URL http://mercury.netplex.net/cgi-bin/imagemap/dthomas then if the program imagemap exists in the cgi-bin directory, PathInfo will be set to 'dthomas'.
<DT>CGI$PathTranslated
<DD>This is the same as above but is prefixed with the path of the Web page directory. With the above example it would be something like, 'ADFS::IDEDisc4.$.Internet.WWW.dthomas'.
<DT>CGI$ScriptFilename
<DD>The full RISC OS filename of the program. For example 'ADFS::IDEDisc4.$.Internet.WWW.cgi-bin.process'.
<DT>CGI$ScriptName
<DD>The URL path of the program. For example '/cgi-bin/process'.
<DT>CGI$QueryString
<DD>The data passed in the URL, which followed the '?'. Used by GET requests to pass parameters to CGI programs.
<DT>CGI$RemoteHost
<DD>The name of the client machine, or the dotted-IP address if unknown.
<DT>CGI$RemoteAddr
<DD>The dotted-IP address of the client machine.
<DT>CGI$AuthType
<DD>If Client Authentication is in use then this will be set to 'Basic'.
<DT>CGI$AuthUser
<DD>If Client Authentication is in use then this will be set to the username of the client 'logged in'.
<DT>CGI$ContentType
<DD>The type of data that has been submitted to the program. (Applies to POST only).
<DT>CGI$ContentLength
<DD>The length of the data that that has been submitted to the program. (Applies to POST only).
<DT>CGI$ConnectionNumber
<DD>The current internal connection number that the program is operating as. Used for ...
<DT>CGI$Active_<I>n</I>
<DD>This is set by the program to inform the server that the program is multitasking and will be making calls to Wimp_Poll. Once unset, the server will attempt to send the program's output to the client. (<I>n</I> is an internal connection number).
</DL>
<H5>HTTP Header Fields</H5>
<I>The header fields, as submitted by the client.</I>
<DL>
<DD>It depends entirely on the client as to what you will find set in the HTTP variables.
</DL>
<P>There is also another system variable, although not strictly linked to CGI programs, which is useful to have. It is Netplex$WebPagesDir which gives the name of the root Web page directory.</P>
<H3>Notes</H3>
<UL>
<LI>Netplex checks the requested URL for '/cgi-bin/' and will invoke the program <B>only</B> if it is inside a 'cgi-bin' directory <B>and</B> is of type Command, Utility, BASIC, Absolute, Obey or Perl, otherwise it will be served as a file.
<LI>CGI directories do not need to be in the root Web page directory, e.g. you could have http://iron.netplex.net/users/cgi-bin/ which would still work OK. You can have multiple cgi-bin directories if you want.
<LI>In order for CGI$PathInfo to be correct, you <B>must not</B> use subdirectories within the cgi-bin directories.
<LI>The first line of CGI output is parsed, if it begins 'HTTP/1' then it is assumed that the CGI program has generated the entire header itself and Netplex will not attach any header fields of its own.
<LI>Perl is supported, as long as it is <B>not</B> set up to run in a TaskWindow. Perl files are detected by the file having a filetype of &102.
<LI>Absolute files (filetype &FF8) are checked to see if they have an APCS-like header, if they do then they are invoked using Unix-like redirection operators.
<LI>In a multitasking program, the CGI system variables are only guaranteed to be present, and valid, up until the first time you call Wimp_Poll. This is because other multitasking programs may get started when you release control to Wimp_Poll.
</UL>
<HR WIDTH="50%">
<A NAME="examples"><H2>Examples</H2></A>
<P>These programs will not work if you're reading the help files directly.</P>
<P><DL>
<DT><B><A HREF="cgi-bin/time">Time</A></B>
<DD>A CGI program which when retrieved displays the time.
<DD>A CGI program which when retrieved displays the query string that was passed to the program. In this case the query string is 'This+is+the+query+example'.
<DT><B><A HREF="form">Form</A></B>
<DD>An HTML page containing a Form which when submitted is sent to a CGI program called 'form' which displays the results. This uses the POST method rather than GET.
<DT><B><A HREF="cgi-bin/tasks">Tasks</A></B>
<DD>Dynamically builds an HTML page of information about all running tasks on your machine.
<DT><B><A HREF="cgi-bin/info">Info</A></B>
<DD>Provides information on the system variables used by Netplex to inform CGI programs of their parameters.
<DT><B><A HREF="cgi-bin/dir">Dir</A></B>
<DD>An advanced version of the Query program which uses self-references to enable the user to traverse a directory structure and serve files. It defaults to using 'ADFS::4.$', which may not be applicable to your system. It will only list Public-readable files.
<BR>(Note: ArcWeb fouls up with this program due to its over-zealous URL verifying).
<DD>An example of a <B>multitasking</B> CGI program. Monitors the desktop for five seconds and then returns an figure indicating how fast the desktop is operating (in polls per second).
</DL></P>
<P><B>Note :</B> These programs are provided purely for demonstration purposes. You should not allow open access to your machine with these programs present - particularly Dir as it allows unrestricted access to any filing system on your machine.</P>