Prev Up Next

testcgi.scm does not take any input from the user. A more focused script would take an argument environment variable from the user, and output the setting of that variable and none else. For this, we need a mechanism for feeding arguments to CGI scripts. The form tag of HTML provides this capability. Here is a sample HTML page for this purpose:

<html>
<head>
<title>Form for checking environment variables</title>
</head>
<body>

<form method=get 
      action="http://www.foo.org/cgi-bin/testcgi2.scm">
Enter environment variable: <input type=text name=envvar size=30>
<p>

<input type=submit>
</form>

</body>
</html>

The user enters the desired environment variable (eg, GATEWAY_INTERFACE) in the textbox and clicks the submit button. This causes all the information in the form -- here, the setting of the parameter envvar to the value GATEWAY_INTERFACE -- to be collected and sent to the CGI script identified by the form, viz, testcgi2.scm. The information can be sent in one of two ways: (1) if the form's method=get (the default), the information is sent via the environment variable called QUERY_STRING; (2) if the form's method=post, the information is available to the CGI script at the latter's standard input port (stdin). Our form uses QUERY_STRING.

It is testcgi2.scm's responsibility to extract the information from QUERY_STRING, and output the answer page accordingly.

The information to the CGI script, whether arriving via an environment variable or through stdin, is formatted as a sequence of parameter/argument pairs. The pairs are separated from each other by the & character. Within a pair, the parameter occurs first and is separated from the argument by the = character. In this case, there is only one parameter/argument pair, viz, envvar=GATEWAY_INTERFACE.

The script testcgi2.scm:

#!/bin/sh
":";exec /usr/local/bin/mzscheme -r $0 "$@"

(display "content-type: text/plain") (newline)
(newline)

;string-index returns the leftmost index in string s
;that has character c

(define string-index
  (lambda (s c)
    (let ((n (string-length s)))
      (let loop ((i 0))
        (cond ((>= i n) #f)
              ((char=? (string-ref s i) c) i)
              (else (loop (+ i 1))))))))

;split breaks string s into substrings separated by character c

(define split
  (lambda (c s)
    (let loop ((s s))
      (if (string=? s "") '()
          (let ((i (string-index s c)))
            (if i (cons (substring s 0 i)
                        (loop (substring s (+ i 1)
                                         (string-length s))))
                (list s)))))))

(define args
  (map (lambda (par-arg)
         (split #\= par-arg))
       (split #\& (getenv "QUERY_STRING"))))

(define envvar (cadr (assoc "envvar" args)))

(display envvar)
(display " = ")
(display (getenv envvar))

(newline)

Note the use of a helper procedure split to split the QUERY_STRING into parameter/argument pairs along the & character, and then splitting parameter and argument along the = character. (If we had used the post method rather than get, we would have needed to extract the parameters and arguments from the standard input.)

The <input type=text> and <input type=submit> are but two of the many different input tags possible in an HTML form. Consult NCS for the full repertoire.

Prev Up Next