www.cgi- CGI utility
Provides a few basic functions useful to write a CGI script.
In order to write CGI script easily, you may want to use
other modules, such as
rfc.uri (see URI parsing and construction),
text.html-lite (see Simple HTML document construction) and
text.tree (see Lazy text construction).
Note: it seems that there is no active formal specification for CGI. See http://w3c.org/CGI/ for more information.
Normally, httpd passes a cgi program various information
via environment variables.
Most procedures in
www.cgi refer to them (meta-variables).
However, it is sometimes inconvenient to require environment variable access
while you’re developing cgi-related programs.
With this parameter, you can overrides the information of meta-variables.
Metavariables should be a list of two-element lists. Car of each inner list names the variable, and its cadr gives the value of the variable by string.
For example, the following code overrides
QUERY_STRING meta-variables during execution of
my-cgi-procedure. (See Parameters,
for the details of
(parameterize ((cgi-metavariables '(("REQUEST_METHOD" "GET") ("QUERY_STRING" "x=foo")))) (my-cgi-procedure))
Returns a value of cgi metavariable name.
This function first searches the parameter
and if the named variable is not found, calls
CGI scripts may want to use
of directly calling
sys-getenv; doing so makes reuse of
the script easier.
Parses query string and returns associative list of parameters.
When a keyword argument query-string is given, it is used
as a source query string. Otherwise, the function checks the
REQUEST_METHOD and obtain the query string
depending on the value (either from stdin or from the
If such a metavariable is not defined and
the current input port is a terminal, the function prompts the user
to type parameters; it is useful for interactive debugging.
POST, this procedure can handle
multipart/form-data as the enctype. The latter is usually
used if the form has file-uploading capability.
When the post data is sent by
each content of the part is treated as a value of the parameter.
That is, the content of uploaded file will be seen as one big
chunk of a string. The other information, such as the original file
name, is discarded. If it is not desirable to read entire file
into a string, you can customize the behavior by the part-handler
argument. The details are explained in the "Handling file uploads"
When a true value is given to merge-cookies, the cookie
values obtained from the metavariable
are appended to the result.
Note that the query parameter may have multiple values,
cdr of each element in the result is a list, not an atom.
If no value is given to the parameter,
#t is placed as its value.
See the following example:
(cgi-parse-parameters :query-string "foo=123&bar=%22%3f%3f%22&bar=zz&buzz") ⇒ (("foo" "123") ("bar "\"??\"" "zz") ("buzz" #t))
A convenient function to obtain a value of the parameter name from
parsed query string params, which is the value
cgi-parse-parameters returns. Name should be a string.
Unless true value is given to list, the returned value is a scalar value. If more than one value is associated to name, only the first value is returned. If list is true, the returned value is always a list, even name has only one value.
After the value is retrieved, you can apply a procedure to convert the string value to the appropriate type by giving a procedure to the convert argument. The procedure must take one string argument. If list is true, the convert procedure is applied to each values.
If the parameter name doesn’t appear in the query,
a value given to the keyword argument default is returned;
the default value of default
#f if list is false, or
Creates a text tree (see Lazy text construction) for the HTTP header of the reply message. The most simple form is like this:
(tree->string (cgi-header)) ⇒ "Content-type: text/html\r\n\r\n"
You can specify alternative content-type by the keyword argument
content-type. If you want to set cookies to the client,
specify a list of cookie strings to the keyword argument cookies.
You can use
construct-cookie-string (see HTTP cookie handling)
to build such a list of cookie strings.
The keyword argument location may be used to generate
Location: header to redirect the client to the specified URI.
You can also specify the
Status: header by the keyword argument
status. A typical way to redirect the client is as follows:
(cgi-header :status "302 Moved Temporarily" :location target-uri)
The value of this parameter specifies the character encoding scheme (CES)
used for CGI output by
cgi-main defined below.
The default value is Gauche’s native encoding.
If the parameter is set other than the native encoding,
converts the output
(see Character code conversion).
A convenient wrapper function for CGI script.
This function calls
cgi-parse-parameters, then calls
proc with the result of
The keyword argument merge-cookies is passed to
proc has to return a tree of strings
(see Lazy text construction), including the HTTP header.
cgi-main outputs the returned tree to the current output port
write-tree, then returns zero.
If an error is signaled in proc, it is caught and an HTML
page reporting the error is generated. You can customize the
error page by providing a procedure to the on-error keyword argument.
The procedure takes an
<condition> object (see Conditions),
and has to return a tree of string for the error reporting HTML
page, including an HTTP header.
When output the result,
cgi-main refers to
the value of the parameter
and converts the character encoding if necessary.
The output behavior of
cgi-main can be customized
by a keyword argument output-proc; if it is given,
the text tree (either the normal return value of proc,
or an error page constructed by the error handler) is passed
to the procedure given to output-proc. The procedure
is responsible to format and output a text to the current
output port, including character conversions, if necessary.
The keyword argument part-handlers are simply passed to
cgi-parse-parameters, by which you can customize
how the file uploads should be handled. See the "Handling file
uploads" section below for the details.
If you specify to use temporary file(s) by it,
makes sure to clean up them whenever proc exits,
even by error. See
to utilize this feature for other purpose.
Before calling proc,
cgi-main changes the buffering mode
of the current error port to
in Common port operations for the details about the buffering mode).
This makes the error output easier for web servers to capture.
The following example shows the parameters given to the CGI program.
#!/usr/local/bin/gosh (use text.html-lite) (use www.cgi) (define (main args) (cgi-main (lambda (params) `(,(cgi-header) ,(html-doctype) ,(html:html (html:head (html:title "Example")) (html:body (html:table :border 1 (html:tr (html:th "Name") (html:th "Value")) (map (lambda (p) (html:tr (html:td (html-escape-string (car p))) (html:td (html-escape-string (x->string (cdr p)))))) params)))) ))))
This is supposed to be called inside proc of
It registers filename as a temporary file, which should be
unlinked when proc exits. It is a convenient way to ensure
that your cgi script won’t leave garbages even if it throws an error.
It is OK in proc to unlink or rename filename after
calling this procedure.
Keeps a list of filenames registered by
As explained in
cgi-parse-parameters above, file uploads
are handled transparently by default, taking the file content
as the value of the parameter. Sometimes you might want to change this
behavior, for the file might be quite big and you don’t want
to keep around a huge chunk of a string in memory. It is possible to
customize handling of file uploads of
cgi-main by part-handlers argument.
(The argument is only effective for the form data submitted by
The part-handlers argument is, if given, a list of lists;
each inner list is a form of
(name-pattern action kv-list …).
Each uploaded file with a matching parameter name with name-pattern is
handled according to action. (Here, a parameter name
is the ’name’ attribute given to the
input element in the
submitted form, not the name of the uploaded file).
Name-pattern must be either a list of string (matches one of them),
a regexp, or
#t (matches anything).
Action must be either one of the followings:
Default action, i.e. the content of the uploaded file is turned into a string and becomes the value of the parameter.
The uploaded content is discarded.
The uploaded content is saved in a temporary file. The value of the parameter is the pathname of the temporary file.
For this action, you can write an entry like
(name-pattern file prefix), to specify the
prefix of the pathname of the temporary file. For example, if you
("image" file "/var/mycgi/incoming/img"),
the file uploaded as
"image" parameter will be stored as
something like /var/mycgi/incoming/img49g2Ua.
The application should move the temporary file to appropriate
location; if you’re using
cgi-main, the temporary files
created by this action will be unlinked when
file, but the value of the parameter is a list of
temporary filename and the filename passed by the client.
It is useful if you want to use client’s filename (but do not
blindly assume the client sends a valid pathname; for example,
you shouldn’t use it to rename the uploaded file without
In this case, procedure is called to handle the uploaded
contents. It is called with four arguments:
(procedure name filename part-info iport).
Name is the name of the parameter. Filename is
the name of the original file (pathname in the client).
Part-info is a
<mime-part> object that keeps information
about this mime part, and iport is where the body can be
For the details about these arguments,
see MIME message handling; you might be able to
use procedures provided by
rfc.mime, such as
to construct your own procedure.
If you create a temporary file in procedure, you can call
cgi-add-temporary-file to make sure it is removed even if
an error occurs during cgi processing.
If kv-list is given after action, it must be a keyword-value list and further modifies action. The following keywords are supported.
Valid only if action is either
Specifies the prefix of the temporary file. If you give
:prefix "/tmp/foo", for example, the file is saved
as something like /tmp/fooxAgjeQ.
Valid only if action is either
Specifies the mode of the temporary file in unix-style integer. By default
Note that the parameters that are not file uploads are not the subject of part-handlers; such parameter values are always turned into a string.
Here’s a short example. Suppose you have a form like this:
<form enctype="multipart/form-data" method="POST" action="mycgi.cgi"> <input type="file" name="imagefile" /> <input type="text" name="description" /> <input type="hidden" name="mode" value="normal" /> </form>
If you use
cgi-parse-parameters in mycgi.cgi
without part-handlers argument,
you’ll get something like the following as the result.
(The actual values depend on how the web client filled the form).
(("imagefile" #*".....(image file content as a string)....") ("description" "my image") ("mode" "normal"))
If you pass
'(("imagefile" file :prefix "/tmp/mycgi"))
you might get something like the following, with the
content of uploaded file saved in /tmp/mycgi7gq0B
(("imagefile" "/tmp/mycgi7gq0B") ("description" "my image") ("mode" "normal"))
If you use a symbol
file+name instead of
you’ll get something like
("/tmp/mycgi7gq0B" "logo.jpg") as
the value of
"logo.jpg" is the
client-side filename. (Note: the client can send any string
as the name of the file, so never assume it is a valid