Oleg Kiselyov's CGI query string parsing routines.





(require-extension cgi-util)


cgi-util is a chicken port of Oleg Kiselyav's CGI query string parsing library found at

The following is adopted from Oleg's source documentation.

procedure: (CGI:url-unquote STRING)

Parse the string of URL parameters, the "QUERY_STRING"

That is, convert a string likeparm1=val1&parm2=val2+val%253+val4&%7Eparm3=&parm4 into an assoc list

	'((parm4) (~parm3 "")
         (parm2 "val2" "val%3" "val4")
         (parm1 "val1"))

Parsing is done by a finite state machine, that takes into account the current state (looking for a parm, looking for a value, looking for a continuation of parm/value after %xx quoted-char), the action-prefix ('=', '+', '&' or '/') and the token that follows the action prefix (that is, a set of characters through the next action-prefix or the end-of-string). At the very beginning, the action-prefix is assumed '&'. Note, we assume '/' separator to; act exactly like '&' (so we can use the present function to parse both SCRIPT_PATH and QUERY_STRINGs)


(CGI:url-unquote "aaa")
(CGI:url-unquote "aaa=")
(CGI:url-unquote "aaa=&bbb=b1&ccc=c1+c2&ddd")
(CGI:url-unquote "aaa=/bbb=b1/ccc=c1+c2/ddd")
(CGI:url-unquote "%7eaaa=/%25b%25bb=b%201/c%20c%7E=c1+c2/ddd%21")

Also note that we skip empty string tokens, such as the leading space before val1 and the extra space between val1 and val2 in the following string:


That means that leading spaces from parameter values are trimmed.

procedure: (CGI:lookup NAME TYPE [DEFAULT-VALUE])

Lookup a NAME among CGI variables. NAME is a symbol. Convert the result to the TYPE. If the NAME is not CGI-bound and the DEFAULT-VALUE is specified, return the DEFAULT-VALUE. Otherwise, signal an error. An error is signalled also when the conversion to the TYPE fails. TYPE is a symbol, one of the following: token, tokens, string, io, int, number

If the QUERY_STRING or a POST message contain param= we assume that CGI parameter 'param is not specified. That is, in QUERY_STRING, "param=" is equivalent to the empty string.

If the QUERY_STRING or a POST message contain param then

      (CGI:lookup 'param 'token) returns #f.
      (CGI:lookup 'param 'tokens) returns '()
      (CGI:lookup 'param 'string) returns ""
      (CGI:lookup 'param 'io) returns '("")
      (CGI:lookup 'param 'int) and (CGI:lookup 'param 'number) fail.

If the QUERY_STRING says param=val then

     (CGI:lookup 'param 'token) returns "val"
     (CGI:lookup 'param 'tokens) returns '("val")
     (CGI:lookup 'param 'string) returns "val"
     (CGI:lookup 'param 'io) returns '("val")
     (CGI:lookup 'param 'int) and (CGI:lookup 'param 'number) 
      try to convert "val" to a number or an integer, and raise the exception
      upon the failure.

If the QUERY_STRING says param=val1+val2or


(as 'param may be mentioned several times, for example, if it's a name of a check-box or a multiple-choice option) then

     (CGI:lookup 'param 'token) returns "val1"
     (CGI:lookup 'param 'tokens) returns '("val1" "val2")
     (CGI:lookup 'param 'string) returns "val1 val2"
     (CGI:lookup 'param 'io) returns '("val" " " "val2")
     (CGI:lookup 'param 'int) and (CGI:lookup 'param 'number) fail.

There are special 'predefined' names that can be looked up:

'query-string the return value is the query-string as a string
'query-parms an assoc list of query parameters, or '()
'self-url (demand-env-var "SCRIPT_NAME")

for them, the TYPE argument must be 'token

procedure: (CGI:get-remote-user-name)

Get the name of the authenticated remote user, or '*' If the name of the remote user is set, the web server has already verified the user's credentials. This also means that the remote user name does not contain any funny and dangerous characters like quotes and newlines.

procedure: (CGI:get-query-string)

Returns the raw query string. Works with GET and POST requests.

procedure: (CGI:exception-handler EXN)

Use in handle-exceptions or other exception handling routines to display an error page.