Pete Wilson : Consultant Software Engineer

Lowell MA   978.454.4547   pete at pwilson dot net    April 2008

 Home/Resume  
 Sample code 
 Experimental 
 SNMP 
 CGI notes 
 CSS notes 
 Standards 
 Books 
  Virus Alerts  

DHTML and CGI links

Apache CGI how-to, an outstanding doc.

CGI newsgroup on Google -- active, responsive, and helpful.

Newsgroup FAQ tells only how to post.

CGI working group mailing list home page. Don't even bother, it's comatose.

Harvey Mudd College CS Dept. Cookbookish overview of how to get a CGI script to actually run.

Summary: CGI parameters

What exactly does a browser deliver to my CGI code? How? Where? CGI parameters are obscure:
  1. GET and POST pass parameter strings in three possible ways
  2. Different browsers deliver different parameter strings
  3. IE6 follows its own rules

We examine parameter passing and demonstrate by example.

The examples call the C-language CGI script cgi-inp, a C script that deals direct at a low level and sidesteps any interpreter like PHP or Perl.

Goals

  1. Show in fine detail the parameter strings the CGI script sees and how it sees them
  2. Invoke the C-language script from GET and POST in many ordinary, vanilla ways
  3. Reveal HTML-CGI interaction by complete, correct description and practical example

Non-goals

Jettison many otherwise-worthy goals that might cloud, confuse, or distract:
  1. Subordinate appearance and presentation to organization and example
  2. Favor completeness over common use, practice, and sense
  3. Ignore methods other than GET and POST
  4. Forget scripts written in other than the C language
  5. Disdain client-side scripts

Organization

The material's laid out to examine the elements and attributes:
anchor and link button image submit reset

Every example link in this section invokes a CGI script called "cgi-inp." That code obsesses to show every single microscopic detail of every single parameter string it receives in each invocation, on this wise:

  1. HTTP_USER_AGENT
  2. argc and all *argv[]
  3. REQUEST_METHOD
  4. pointer to QUERY_STRING and its length
  5. QUERY_STRING and STDIN in four forms:
    1. as delivered char-for-char
    2. as a legible string
    3. as extracted tokens
    4. as the browser renders it
  6. CONTENT_LENGTH and total characters on STDIN

So the display's a kind of formatted dump that reveals how individual browsers interpret and realize the specs.

The anchor and link elements

Text links plain and decorated

To start in the most obvious way: the first examples below show how a plain old text link can invoke a script. Further: a text link can take a background image and further examples below show how that works. This image will be the background: background image in examples

In this test, I want to see if a link with a background image works differently from a plain-text link. In particular, I want to know if anything about the image shows up on the script side of the interface. Answer: it does not.

html try these
A straightforward, ordinary <a href="cgi-bin/cgi-inpn" title="plain-text link example">test new stuff only</a> with no background and no parameter. A straightforward, ordinary test new stuff only with no background and no parameter.
An undecorated <a href="cgi-bin/cgi-inpn?plain" title="plain-text link with query string">test new stuff only</a> with no background but with an encoded parameter this time. An undecorated test new stuff only with no background but with an encoded parameter this time.
A link with a background image |<a style= "background-image: url(show-me.gif)" href="cgi-bin/cgi-inp?the weakest link!"></a>| but no clickable area: it's between the vertical bars. A link with a background image || but no clickable area: it's between the vertical bars.
A clickable link with an image behind it <a style="background-image: url(show-me.gif)" href="cgi-bin/cgi-inp?link w/bg" title="link is blank chars with background image"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </a> that's revealed through the blanks that overlay it. A clickable link with an image behind it            that's revealed through the blanks that overlay it.
And a clickable link with an image <a style="background-image: url(show-me.gif)" href="cgi-bin/cgi-inp?link w/bg" title="link of non-blanks with background image"> xxxxxxxxxx </a> that's obscured by the overlaying characters. And a clickable link with an image xxxxxxxxxx that's obscured by the overlaying characters.

Text-link conclusions:

  1. REQUEST_METHOD == GET on entry always
  2. a parameter needs to be encoded in the link if the CGI script wants to discriminate among links, thus: <a href="cgi-bin/cgi-inp?query string"> link text </a>
  3. different from the "button" links on this page, text links deliver argv[] and argc on the interface
  4. a parameter string encoded in the link is delivered to the CGI script both in QUERY_STRING and in argv[]

The button element

[ To come, maybe: button description or reference pointer; attributes; traps and trip-ups; styling ]

get method with button:

A string as param = val is delivered to the CGI script as the NUL-terminated string pointed by the environment variable QUERY_STRING. To find the string and its length:

   char * qs;
   int qlen;
   qs = getenv("QUERY_STRING");
   if (NULL != qs)   /* NULL means there is/was no query string */
   {
     qlen = strlen(qs);
   }

post method with button:

A string as param = val appears on STDIN. The length of the string is explicit in the environment variable CONTENT_LENGTH; and implicit in reading STDIN until EOF:

   int ch, clen, n = 0;
   char stdin_line[128];
   char * qs;
   qs = getenv("QUERY_STRING");
   if (NULL != qs)
   {
     clen = atoi(getenv("CONTENT_LENGTH"));
     while ((ch = getchar()) != EOF) 
     {
       if (n < sizeof(stdin_line)-1) {
         stdin_line[n]   = (char)ch;
         stdin_line[n+1] = '\0';
     }
     ++n;
   }   /* clen must equal n here, else error */

param val
The string value that you gave to the button's name attribute, thus
<button  name="go!"..> yields param = the string "go!"

IE6.0:

If the button carries a label, then the label string itself, verbatim, including any markup in the label string. If the button carries an image, then the entire <img...> string that describes the image, including src, alt, title, and everything else, and all of that enclosed in "< >." Otherwise, if the button carries label nor image, then an empty string is delivered.

Mozilla, Netscape6.2.2, Opera6.05:

The string you assigned to the button's value attribute. There are perhaps other variations in other user agents.

Examples: buttons that carry text labels

Examples of methods "get" and "post". A few interesting things:
  1. I can apply markup to labels on buttons and IE6.0 honors and renders that markup along with label text.
  2. Before delivering label text on the interface, IE6.0 takes the trouble to rearrange markup tokens; to de-XHTMLize them; and to map some to upper case.
  3. Different browsers seem to render label strings in peculiar ways: IE6.0 ignores newline in label strings; other browsers treat newline as if it were <br />.
Try these out to see what your browser actually delivers to a CGI script. Your browser back button returns you here.

<form method="get" 
 action="/cgi-bin/cgi-inp">
 <input name="txt-in:" 
  size="5" type="text" 
  value="get this" />
 <button 
  name="go!" 
  value=
   "get button val" 
  type="submit">
  label<br /> with 
  deprecated
  <font color="red">
   markup</font>
 </button>
</form>
    

<form method="post" 
 action="/cgi-bin/cgi-inp">
 <input name="txt-in:" 
  size="5" type="text" 
  value="post this" />
 <button 
  name="b-name" 
  value=
   "some <i>italic</i> val" 
  type="submit">
  your 
   <b>post-button
   </b> 
   label
 </button>
</form>
    

Examples: buttons that carry images

Examples of methods "get" and "post" to show that the behavior of a decorated button closely resembles the behavior of a labeled button, in contrast to an image that you might use instead of a button: such images are in the next section. Try these out to see what's actually delivered to the CGI script. Your browser back button will bring you back here.

<form method="get" 
 action="/cgi-bin/cgi-inp">
  <button 
   name="Weeza!" 
   value="Weeza pic" 
   type="submit">
   <img src="broglie.jpg" 
    title="title: Ingres"
    alt="alt: Louise de Broglie" />
  </button>
</form>
    

<form method="post" 
 action="/cgi-bin/cgi-inp">
  <button 
   name="Vermeer" 
   value="button-value" 
   type="submit">
   <img src="pearl-girl.jpg" 
    title="title: VermeerGwP"
    alt="alt: Girl with Turban" />
  </button>
</form>
    


The image attribute

Image-attribute references
  1. W3C, Forms in HTML documents: 17.4 The input element
  2. Web Design Group, INPUT - Form Input
  3. Alan Flavell, INPUT TYPE=IMAGE for text users?
  4. Jukka Korpela, About image buttons in HTML forms and multi-line texts in normal submit buttons
[ To come: legal attributes: what we can say further about "image." cautions: the gotcha's "image" gets us. styling ]

get with image button

The string value of the image "name" attribute is delivered twice in QUERY_STRING, once with the selected image x-coordinate, once with the selected image y-coordinate.

<form 
 method="get" 
 action="/cgi-bin/cgi-inp">
 <input 
  type="image" 
  src="show-me.gif" 
  value="left" 
  name="push-me" />
</form>
    

get with image button, query string coded in URL

A query string is explicitly coded in the "action" attribute but, with get, that query string is discarded before it ever gets to the CGI script. The string value of the image's name attribute is delivered twice in QUERY_STRING, once with the selected image x-coordinate, once with the selected image y-coordinate.

<form method="get" 
 action=
  "/cgi-bin/cgi-inp?q=GET query;">
 <input 
  type="image" 
  src="show-me.gif" 
  value="left" 
  name="the show-me image" />
</form>
    

post with image button

A string of length CONTENT_LENGTH is passed on STDIN. That string is exactly the string passed in QUERY_STRING of method="get:" the string value of the image's name attribute is delivered twice on stdin, once with the selected image x-coordinate, once with the selected image y-coordinate.

<form 
 method="post" 
 action="/cgi-bin/cgi-inp">
 <input name="txt-in:" 
  size="5" type="text" 
  value="post me" />
 <input 
  type="image" 
  src="show-me.gif" 
  value="left" 
  name="image-button" />
</form>
    

post with image button, query string coded in URL

The string coded in the URL (emboldened below) is passed in QUERY_STRING; and a string of length CONTENT_LENGTH is passed on stdin. That string is exactly the string passed in QUERY_STRING of method="get:" the string value of the image "name" attribute is delivered twice on stdin, once with the selected image x-coordinate, once with the selected image y-coordinate.

<form 
 method="post" 
 action=
  "/cgi-bin/cgi-inp?qs=POST-query;">
 <input name="txt-in:" 
  size="5" type="text" 
  value="post me" />
 <input 
  type="image" 
  src="show-me.gif" 
  value="left" 
  name="show-me-image" />
</form>
    



The submit element

submit references
W3C, htmlhelp, Korpela
[ To come: legal attributes, cautions, styling ]


The reset element

reset references W3C, htmlhelp, Korpela

 notes and cautions:

We can give the user several submit buttons in a single form. But every reset button in the form clears every text-input control. Maybe we need individual resets, one for each input field. Here's one workaround.