First take the popular step to make sure that the first 20 characters you send from your CGI are exactly
Content-type: text/html
followed by two (nb two) line feed characters -- 0xA 0xA, not carriage return characters (0xD 0xD). Or, in code:
printf("Content-type: text/html%c%c",10,10);
This next putative fix is obscure. If you're running under *nix, it seems that your executable in ~/public_html/cgi-bin cannot have write privileges enabled for group or for all. It seems this executable will always fail:
-rwxrwxr-x 1 pwilson pwilson 6218 Apr 15 18:38 this-fails*
while this one will work:
-rwxr-xr-x 1 pwilson pwilson 6218 Apr 16 06:53 this-works*
It seems that Apache will refuse to run a writeable object.
And from a Usenet group: "I recently saw a similar problem, where the server was refusing to run a script because the DIRECTORY it was in was world-writeable (how the directory became world writable is another question....)." [go there]
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.
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.
| 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:
So the display's a kind of formatted dump that reveals how individual browsers interpret and realize the specs.
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"> </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:
[ 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. |
get with image buttonThe 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 URLA 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 buttonA 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 URLThe 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>
|
||
| W3C, htmlhelp, Korpela |
| [ To come: legal attributes, cautions, styling ] |
| 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. |