WebHosting Paid by #1Payday.Loans


   The ROCK Linux project has been discontinued in 2010. Here are the old data for the historical record!

CGI Made E-Z with cgi-postin Contents: * [1]Introduction * [2]Review of HTML Forms * [3]Review of Forms Handling under Gn * [4]Form Processing with cgi-postin * [5]Conclusion * [6]Appendix A: Links to Examples * [7]Appendix B: Perl Support _________________________________________________________________ Introduction Fill-out forms are a popular feature on the World-Wide Web. Gn, like any good Web server, supports them. This support comes through the Common Gateway Interface (CGI). CGI processors can be tedious to write. The most cumbersome part is retrieving and decoding the form data. The cgi-postin utility solves this problem. It lets you write CGI processors as sh(1) scripts, and not have to worry about the intricacies of the CGI interface. This note explains how to use cgi-postin to write CGI processors running under the gn HTTP server. We will review briefly how forms are created. We will discuss how the Web client and gn server coordinate to process a form. Finally, will construct a CGI processor based upon cgi-postin. The cgi-postin utility is freely available. It was written by Chip Rosenthal. The most recent version may be downloaded from [8]ftp.unicom.com:pub/gn-tools/cgi-postin.c. Review of HTML Forms Forms are created in HTML documents with tags such as:
. . .
The two attributes, METHOD and ACTION, say what to do with the form. The METHOD directs the client how to pass the form data back to the server. The ACTION is a URL to the processor that handles that data. There are two methods available: post and get. The get method transmits the form data within the URL. It requires cooperation from the HTTP server to extract the data. The post method transmits the form data in-band, and allows the CGI processor to load it (usually) from its standard input. Here, we are concerned only with the post method. That's because cgi-postin was designed for it. Otherwise, we would have called it cgi-getin:-). Lack of get support shouldn't be a problem; you probably want to use just the post method. If you have never created an HTML form, before you go any further, you should read the [9]Fill-Out Form Support for NCSA Mosaic tutorial. It describes the elements available to construct forms, and provides some very good examples. You will want to use the ``View Source'' feature of your Web browser to see how the examples are constructed. Review of Forms Handling under Gn There are two pieces to [10]a World-Wide Web form. There is [11]the HTML source to the form, and there is the backend CGI processor. The CGI processor receives the form data from the client, performs some actions, and returns some resulting document. In this section we will examine the interface between these two pieces, in preparation for the next section, where we will tackle the chore of writing a CGI processor. A submit button is placed on a form with something like: When the submit button is selected, the client performs several transformations on the data. We won't bother going into those details here. Normally, unmunging the form data is one of the most tedious parts of CGI processing. The cgi-postin utility does all that, so you don't have to worry about it. After the data has been munged, the client invokes the URL associated with the form. Again, this association was made in the original FORM tag. If, for example, we created the form with:
then the client would run ``https://hostname:port/CGI/gn-info/cgi-postin/example.cgi'' when the submit button is pressed. The client would also send along the (transmorgified) form data. Since this example uses METHOD="post", the data is passed in-band along with the request. The gn server receives the URL and calls the CGI processor. Gn knows it needs to run a CGI processor, not serve a regular document, by the CGI selector at the front of the path. Gn requires that the URL not only start with a CGI selector, but also end with a .cgi filetype. The example shown above has both, so gn would be happy with it. Gn will execute a CGI processor with the (transmorgified) form data attached to its standard input. The CGI processor will load in that data, take whatever actions are necessary, and emit a document that gn will return to the client. Gn constructs that document by taking all the output emitted by the processor, both its stdout and stderr, and slapping an HTTP header on the front. To provide maximum flexibility, gn allows the CGI processor to return any sort of document it wants, from ``text/plain'' to ``image/gif''. The very first piece of output from the processor must be a header that describes the following content. Here is a snippet of output from a CGI processor that returns an HTML document: Content-type: text/html . . . In this example, a ``Content-type'' header is produced, followed by a mandatory blank line. After that comes the document, in this case an HTML document. Again, it is the CGI processor that produces all of this output. Gn merely slaps an HTTP header on the front of it, and ships it all back to the client. Gn requires two cache entries to handle a Web form. That's because there are two files involved in the process: the HTML source and the CGI processor. Both files must be in the cache, even if one or both should not appear in the listing displayed to the client. (In fact, the CGI processor almost certainly should not be in the displayed listing.) This is required because the cache file not only describes the listing, but also grants the server authorization to access the document. The gn cache files usually are created by running a file called menu through the mkcache utility. Here are a couple of menu file entries that would allow a form to be processed correctly: Name=A Sample HTML Form Path=0/gn-info/cgi-postin/example.html Attribute=HttpOnly Name=the processor for this form Path=CGI/gn-info/cgi-postin/example.cgi Attribute=Invisible The first entry is for the HTML form, the second for the CGI processor. We specified the HttpOnly attribute to limit this file to Web clients. When a Gopher client connects to the server, this item will not appear in the file listing. We did that because CGI is a Web feature, and not available under Gopher. The second entry is for the CGI processor. Here, we used the Invisible attribute. This will prevent it from appearing on any listing, but will authorize gn to execute the processor. Form Processing with cgi-postin We are now ready to build a CGI form processor. We've discussed everything you need to know about forms processing - except for one teensy tiny little thing. You haven't a clue how that data gets from the client to your processor. Not to fear! The cgi-postin utility was written so you don't have to worry about that tricky but oh-so-important piece. The cgi-postin utility was designed to run from sh(1) shell scripts. It performs the following: * Retrieves the transmorgified form data, and ensures none got lost along the way (e.g. the ``Content-length'' is verified). * Unmunges the data stream, breaking it up into pieces (one per form element). It also reverses the data transformations performed by the client so you get back the original information, as entered by the user. * Inspects the data stream for certain ``unsafe'' constructions, allowing you to evaluate the final result without fear of breakage or security breach. * And finally emits a set of sh(1) commands to create a set of shell variables, one per form element, each one containing the user-specified value of the corresponding element. When cgi-postin encounters an error it does two things. First, it emits (upon its stderr) an HTTP document, complete with ``Content-type'' header, that describes what went wrong. Then it terminates with a non-zero exit status. In the even of an error, the CGI processor should return this document to the client and then terminate. The best part is that even though cgi-postin does a lot, it is easy to use. We recommend that you use it by starting your CGI processor with three lines similar to: [12]#!/bin/sh [13]exec 2>&1 [14]eval "`[15]${GN_ROOT?}/[16]cgi-bin/cgi-postin[17]`" [18]|| exit 1 If you'd like an explanation of any part of that example, just click on the part you want to know about. (Assuming, of course, you are reading this with a Web browser.) Let's return to [19]the sample form discussed earlier. That form has two text entry fields, called name and addr, and a set of radio buttons called fun. The [20]CGI processor for that form is a sh script that uses cgi-postin. After the call to cgi-postin, three new shell variables will have been created. They will be called (amazingly enough) name, addr, and fun. The name and addr variables will contain the text entered by the user. The fun variable will contain either yes or no, depending upon which radio button was selected. We have a [21]slightly different version of that form. Although it looks about the same as the first example, its backend CGI processor is totally different. This processor was designed to illustrate precisely what cgi-postin does with the form data. You might try it to get a better idea of the way form data is converted on the way to the server, and how cgi-postin handles it. Conclusion Fill-out forms are a popular feature on the World-Wide Web. Since Gn supports the Common Gateway Interface, Web forms can be provided by a gn server. There are two parts to a form: the HTML source and the CGI processor. Writing a CGI processor can be cumbersome because of all the data transformations required. The cgi-postin utility takes on that burden, making it easy to write CGI processors as sh(1) scripts. There are many nice features to cgi-postin, such as its ability to provide problem descriptions as HTTP documents. When this utility is used, the entire task of form data handling becomes two lines of shell script. This means that CGI processors are written quicker, with less effort, and less prone to bugs or security hazards. Appendix A: Links to Examples This is a list of the links to examples used in this document: * An example form. + [22]The form. + [23]Its HTML source. + [24]Its CGI Processor. * A form that illustrates how cgi-postin works. + [25]The form. + [26]Its HTML source. + [27]Its CGI Processor. * [28]Recommend calling sequence for cgi-postin Appendix B: Perl Support Current releases of cgi-postin have preliminary support for CGI processors written in perl. If executed as ``cgi-postin -p'' then the assignments will be emitted in perl syntax. This means the calling sequence should read something like: eval `/local/spool/web/cgi-bin/cgi-postin -p` || die; The author is not a perl programmer, and therefore would greatly appreciate any feedback on this new functionality. _________________________________________________________________ [29]Back to the gn info page. [30]Up to Unicom Systems home page. [31]Chip Rosenthal $Id: note.html,v 1.4 1998/08/11 09:08:00 chip Exp $ References 1. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#introduction 2. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#html 3. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#handling 4. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#processing 5. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#conclusion 6. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#examples 7. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/note.html#perl 8. ftp://ftp.unicom.com/pub/gn-tools/cgi-postin.c 9. https://www.ncsa.uiuc.edu/SDG/Software/Mosaic/Docs/fill-out-forms/overview.html 10. file://localhost/0h/gn-info/about-cgi-postin/example1.html 11. file://localhost/0/gn-info/about-cgi-postin/example1.html 12. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#hashbang 13. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#exec 14. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#eval 15. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#gnroot 16. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#path 17. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#eval 18. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html#exit 19. file://localhost/0h/gn-info/about-cgi-postin/example1.html 20. file://localhost/0/gn-info/about-cgi-postin/example1.cgi 21. file://localhost/0h/gn-info/about-cgi-postin/example2.html 22. file://localhost/0h/gn-info/about-cgi-postin/example1.html 23. file://localhost/0/gn-info/about-cgi-postin/example1.html 24. file://localhost/0/gn-info/about-cgi-postin/example1.cgi 25. file://localhost/0h/gn-info/about-cgi-postin/example2.html 26. file://localhost/0/gn-info/about-cgi-postin/example2.html 27. file://localhost/0/gn-info/about-cgi-postin/example2.cgi 28. file://localhost/hd1/pub/gopher/gn-info/about-cgi-postin/explain.html 29. file://localhost/gn-info 30. file://localhost/ 31. file://localhost/personal/chip.html .