(require "cgitool") (cgi:let (parameter ...) body ...) (cgi:parse-query-string &optional string) (cgi:get-parameter-value name alist &key :default :error :multivalue) (cgi:parse-cookie &optional string) (cgi:write-header &key :content-type :cookies :location) *cgi:error-page-html-options* (cgi:error fmt args ...) (cgi:error-page fmt args ...)
"html-classes"
Cgitool is a collection of procedures useful to write cgi script in Scheme. It supports:
See examples below to get an idea of how to write CGI scripts with this tool. About the protocol of cookie handling, see RFC2109.
- High level CGI writing macro: cgi:let.
- URL query parameter handling: cgi:url-unquote, cgi:parse-query-string, and cgi:get-parameter-value.
- HTTP message header and Cookie handling: cgi:write-header, cgi:parse-cookie.
- Common CGI error handling: cgi:error, cgi:error-page.
- (cgi:let (parameter-spec ...) body ...) : Macro
This macro is ultimately convenient way to write a CGI script. It retrieves a query-string parameter and "cookies" from environment variable QUERY_STRING and HTTP_COOKIE, respectively, and bound it to local variables according to parameter-spec, then executes body.
parameter-spec can be a symbol or a list.
- If it is a symbol except &queries or &cookies, cgi:let first looks for a parameter named as the symbol, and binds its value to given symbol. If named parameter is not found, cgi:error is called.
- If it is the symbol &queries, the assoc-list which cgi:parse-query-string returns is bound to the symbol.
- If it is the symbol &cookies, the assoc-list which cgi:parse-cookie returns is bound to the symbol.
- If it is a list, it must be formed like (symbol keyword value ...). Symbol is bound to the value of parameter retrieved. Other options specifies the way to retrieve parameter. Possible options are:
- :name name
- Specifies a parameter name other than symbol.
- :source source
- Specifies the source of the value, either :query or :cookie. If omitted, :query is assumed.
- :convert proc
- Passed to cgi:get-parameter-value.
- :default value
- Passed to cgi:get-parameter-value.
- :error proc
- Passed to cgi:get-parameter-value.
- :multvalue boolean
- Passed to cgi:get-parameter-value.
- *cgi:error-page-html-options* : Variable
A list of init-keywords and values, which will be used to create <html-page> object for error page. See schtml for details.
Example: '(:page-title "CGI error" :author-name "shiro")
- (cgi:error format . args) : Procedure
Generate CGI header string and html error page (using cgi:error-page) to stdout, and exits. Convenient way to exit the CGI script with error.
Arguments format and args are passed to format and used as a contents of the error page.
- (cgi:error-page format . args) : Procedure
Generate error page (<html-page> object).
Arguments format and args are passed to format and used as a contents of the error page.
- (cgi:parse-query-string &optional string) : Procedure
Parse query string string and return alist of result. When string is omitted, the value of environment variable QUERY_STRING is used if it is set, or just return '() if it is not set. If provided string is illegal for quoted query string, this procedure generates a html error page and exits.
This procedure calls cgi:url-unquote.
- (cgi:get-parameter-value name alist &key :default :error :multivalue :convert) : Procedure
Given alist, an alist of parameters which cgi:parse-query-string or cgi:parse-cookie returns, this procedure looks for name and returns its associated value. Name must be a symbol.
If name is not found in alist, the action depends on the other keyword arguments like this:
- If a keyword argument :default is specified, the value is returned.
- Otherwise, if a keyword argument :error is specified, call it as a procedure with one argument name.
- Otherwise, generates html error page and exits.
If keyword argument :multivalue is true, the procedure returns list of value(s). Otherwise, the procedure returns a string, concatenating all the value(s) with whitespace inbetween.
If keyword argument :convert is specified, it must be a procedure taking one string argument and returning converted value to suitable type. After a value is retrieved, the procedure is applied to it to perform type conversion.
- (cgi:write-header &key :content-type :cookies :location) : Procedure
Write out CGI header string. Keyword argument :content-type must be a string and is used for content type. The default is "text/html".
Keyword argument :location specifies location header of http, to redirect user's request to new location. This option supercedes content-type option.
Keyword argument :cookies specifies "cookies" to be sent to the client. It is an assoc-list and each element must be the following form:
(NAME VALUE [keyword arg ...])Keyword-value pairs are intended for per-cookie attribute values as defined in RFC2109 (new specification). It also supports "old" cookie format in original Netscape proposal. To make two standard coexist, VALUEs are not quoted.Following attribute specification (keyword-value pair) are recognized. If the attribute is only available either new spec or old spec, it is marked as "(new)" or "(old)". If you mix new-spec-only attribute and old-spec-only attribute, the result will be unknown. Note that if you want to use new specification, you must specify "Version" attribute explicitly (it should be 1).
:comment STRING Comment attribute. (new) :domain STRING Domain attribute. :max-age INTEGER Max-Age attribute. (new) :path STRING Path attribute. :secure BOOLEAN Secure attribute. :version INTEGER Version attribute. (new) :expires DATE Expires attribute. (old) If DATE is integer, it must be a seconds from Jan 1, 1970 0:0:0 GMT. If DATE is a string, it must be a formatted date string ("Wdy, DD-Mon-YY HH:MM:SS GMT").- (cgi:parse-cookie &optional string) : Procedure
Parse encoded cookie and returns assoc-list. If string is omitted, environment variable HTTP_COOKIE is used.
The "new" format as of RFC2109 can be handled, although all additional attributes (attributes starts with "$") will be ignored.
This CGI script just gets parameter "name" and prints out a greeting.#!/sqhnl/bin/snow -f (require "cgitool") (cgi:let (name) (cgi:write-header) (write-html (html-page :page-title "Greeting" :author-name "shiro" :author-email "shiro" :contents (format #f "Hello, ~a." name)))) (exit 0)
This CGI script accepts parameter "year" and "month", and returns calender using unix "cal" command.#!/sqhnl/bin/snow -f (require "posix") (require "cgitool") ;; Default month and year (define *this-year-and-month* (let* ((tmvec (posix-tm->vector (posix-localtime (posix-time)))) (yy (+ (vector-ref tmvec 5) 1900)) (mm (+ (vector-ref tmvec 4) 1))) (if (< yy 1970) ;; year 2000 problem... (cons (+ yy 100) mm) (cons yy mm)))) ;; Make sure parameter gives correct string (define (convert-year str) (or (string->number str) (car *this-year-and-month*))) (define (convert-month str) (or (string->number str) (cdr *this-year-and-month*))) ;; Process request (cgi:let ((year :default "" :convert convert-year) (month :default "" :convert convert-month)) (let ((cal (apply string-append (with-input-from-file (format #f "| cal ~s ~a" month year) (lambda () (let loop ((line (read-line))) (if (eof-object? line) '() (list* line "\n" (loop (read-line)))))) )))) (cgi:write-header) (write-html (html-page :page-title "Calendar" :author-name "shiro" :author-email "shiro" :contents (html-text :preformatted? #t :string cal)))) ) ;; All done. (exit 0)