Code:
$ pg mysrc/show_env mysrc/show_env_form|cat
::::::::::::::
mysrc/show_env
::::::::::::::
#!/bin/sh
echo 'HTTP/1.0 200 OK
Content-type: text/plain\r
\r
Environment of CGI:
'
set|cat -vt
if [ "$REQUEST_METHOD" = "POST" ]
then
echo "
For POST, the first line of stdin:
"
line|cat -vt
echo
fi
::::::::::::::
mysrc/show_env_form
::::::::::::::
#!/bin/bash
# All scripts should begin with this interpreter file line one for exec()!
# They must have executable file permission, or exec() pipes them to sh!
# The #! line can have one arg, useful for things like sed, which needs a '-f'.
# The real, final line executed is:
# /usr/bin/ksh <any_#!_line_arg> <script_file_name> <any_orig_cmd_line_args>
# Comments are our friends, as we, at least, are suppose to remember what we did
# and fix it quickly when it breaks!
# Use of the ksh in Solaris allows access to the <() construct,
# which allows the service to spin off several simultaneous child scripts
# but collect their output from pipes sequentially.
# Of course, the child script may stall if it writes the pipe too soon,
# but most UNIX appliations write their FILE * stdout
# without prematurely flushing its large default buffer.
cat <(
# Begin first <() child script!
# echo out initial boilerplate (not varying) text
# in single quotes for least shell expansion and to pass double quotes.
# CGI starts in the second line of http header out, so you can add http bits
# like content type, length, encoding, cookies, language, etc.
# The blank line terminates the http and starts the content.
# The carriage returns are important to some browsers at the http level.
# Once you get to the content, it is all just white space.
# UNIX likes just a line feed, Apple likes just the carriage return, and
# WinDOS likes both, just like the teletype, where one moved the paper feed
# and the other the print head carriage, and
# the carriage return is first because it was usually the larger, slower motion.
# HTML mostly ignores and hides white space, so make it easily readable.
# Sentences can be put on separate source lines for easy version control.
# A little indentation makes the tag control areas more obvious, and
# will not slow things down appreciably.
# The title should be a full or abbreviated version of the first heading.
# The title is used to bookmark, so make it terse and globally relevant,
# e.g., not "Home Page" but "David G. Pickett - Home Page".
# ISINDEX is a simple (crude) way to add form-like capability. This element
# is deprecated under the strict HTML 4 specification and should not be used.
# Use of values that do not have embedded symbols and blanks
# means no double-quoting of values is necessary
# and no URLdecode is needed to get original values back.
echo 'HTTP/1.0 200 OK
Content-type: text/html
Expires: Tue, 20 Aug 1996 14:25:27 GMT
<HTML>
<HEAD>
<TITLE>Forms That Call show_env</TITLE>
<META http-equiv="Expires" content="Tue, 20 Aug 1996 14:25:27 GMT">
<ISINDEX PROMPT="ISINDEX PROMPT" HREF=show_env>
</HEAD>
<BODY>
<H1>Forms That Call show_env to show how simple HTML and CGI work!</H1>
<HR>
<H2>Get (default action) form</H2>
<FORM ACTION=show_env>
<INPUT TYPE=HIDDEN NAME=name1 VALUE=value1>
Name: <input type=text size=10 maxlength=40 name=nm value="Your Name"><br>
Password: <input type="password" name="pw" value=1234><Br>
<INPUT TYPE=checkbox checked NAME=name2 VALUE=value2a> value2a<BR>
<INPUT TYPE=checkbox checked NAME=name2 VALUE=value2b> value2b<BR>
<INPUT TYPE=checkbox checked NAME=name2 VALUE="value2c&name2_1=value_2c_1"> value2c&name2_1=value_2c_1<BR>
<input type="radio" name="shade" value="dark">Dark<BR>
<input type="radio" name="shade" value="light" checked>Light<br>
<select multiple name=music size=4>
<option value="emo" selected>Emo</option>
<option value="metal/rock" >Metal/Rock</option>
<option value="hiphop" >Hip Hop</option>
<option value="ska" >Ska</option>
<option value="jazz" >Jazz</option>
<option value="country" >Country</option>
<option value="classical" >Classical</option>
<option value="alternative" >Alternative</option>
<option value="oldies" >Oldies</option>
<option value="techno" >Techno</option>
</select><br>
<textarea rows=5 cols=20 name=cmts>
Enter Comments Here
</textarea><br>
<INPUT TYPE=RESET>
<INPUT TYPE=SUBMIT NAME=name3a VALUE=Value3a>
<INPUT TYPE=SUBMIT NAME=name3b VALUE=Value3b>
</FORM>
<HR>
<H2>Get Hypertext ?name=value</H2>
<A HREF="show_env?name4=value4&name5=value5">Click me!</A>
<HR>
<H2>Get Hypertext ?value</H2>
<A HREF="show_env?value6">Click me!</A>
<HR>
<H2>POST Form</H2>
<FORM ACTION=show_env METHOD=POST>
<INPUT TYPE=HIDDEN NAME=name7 VALUE=value7>
<INPUT TYPE=HIDDEN NAME=name8 VALUE=value8>
<INPUT TYPE=checkbox checked NAME=name2 VALUE="value2c&name2_1=value_2c_1"> value2c&name2_1=value_2c_1<BR>
<INPUT TYPE=SUBMIT NAME=name9 VALUE=Value9>
</FORM>
<HR>
GET is assumed to be a simple inquiry, and can be repeated gratuitously to keep the cache or history fresh without user permission.
Use of an Expires: with a near or past value on an http line (or in a corrsponding http-equiv meta statement in the HEAD) can help force such refreshes.
Both are illustrated above.<P>
For POST, the browser assumes the submit changes the real world, and resists gratuitous additional posting of the request.
However, sometimes POST is used to not show the values in the URL, for reasons of size, appearance, and some small security.<P>
POST variables in the default URL-encode mode are presented on standard input, which is the http socket, not the URI which CGI puts into the environment.
Popular browsers present them on a line that always has a carriage return and line feed (preceded by a carriage return), but a few do not, they expect you to read the Content-length bytes and stop, so they are not friendly to the shell and other line oriented tools.<P>
POST in MIME multipart encoding allows you to have forms that upload file contents along with variables and the orignal file name, which may be a relative or absolute path.<P>
POST allows you to have forms that email the variables using a mailto: action URL.
While this is very minimalist (no http/web server required), it does not allow the user'"'"'s view of the page to change after submit, in confirmation of the submit, which is not user friendly.
The submitting email activity either occurs quickly and entirely in the background, encourging duplicate submission, or triggers an email dialog that the user must complete correctly for the submission to occur, which is less robust and more effort.
<HR>
<H2>This Service</H2>
<PRE>
'
# end first child script
) <(
# begin second child script (overkill as an example)
# To illustrate <PRE>, this service will present itself as readable text.
# Use of <PRE> allows plain, fixed pitch fonts, does no folding,
# and turns off space and linefeed presentation as a single space,
# but still allows HTML tags, e.g., below, the comments are made bold.
# However, you have to make 4 critical metacharacters into metastrings.
sed '
s/\&/\&/g
s/"/\"/g
s/</\</g
s/>/\>/g
s/^#.*/<B>&<\/B>/
' $(whence $0)
# end second child script
) <(
# begin third child script
# Show CGI Environmental variables
echo '<HR>
<H2>Current CGI Environmental variables</H2>'
sh -c set|cat -vt|sed '
s/\&/\&/g
s/"/\"/g
s/</\</g
s/>/\>/g
'
echo '
<HR>
<H2>Show what this service sends out (Beware recursion confusion!)</H2>
'
if [ "$zOnce" = "" ]
then
export zOnce=NO_RECURSION
# Except, of course, this, to avoid recursion
$0|cat -vt|sed '
s/\&/\&/g
s/"/\"/g
s/</\</g
s/>/\>/g
'
fi
# echo out final boilerplate like we did for starting boilerplate.
echo '
<HR>
</PRE>
</BODY>
</HTML>
'
# end final child script
)