Page 1 of 1

formCGI "POST" example

PostPosted: Sat Nov 02, 2002 2:09 am
by CaveGuy
;; cgi-post-test.lsp
;; modified formcgi.lsp from GET Method
;; to use POST method.
;;

(define (cgiexpand instr mode , test temp)
(set 'temp "")
(dolist (tmp (parse instr "%"))
(set 'test (substring tmp 0 2))
(set 'temp (concat temp (concat
(cond
((= "0D" test) (if mode "\r" ""))
((= "0A" test) (if mode "\n" "<br>"))
((= "21" test) "!")
((= "22" test) "\"")
((= "23" test) "#")
((= "24" test) "$")
((= "26" test) "&")
((= "27" test) "`")
((= "28" test) "(")
((= "29" test) ")")
((= "2C" test) ",")
((= "2D" test) "-")
((= "2F" test) "/")
((= "3A" test) ":")
((= "3B" test) ";")
((= "3C" test) "<")
((= "3D" test) "=")
((= "3E" test) ">")
((= "3F" test) "?")
((= "40" test) "@")
((= "5B" test) "[")
((= "5C" test) "\\")
((= "5D" test) "]")
((= "5E" test) "^")
((= "60" test) "'")
((= "7E" test) "~")
((= "7B" test) "{")
((= "7C" test) "|")
((= "7D" test) "}")
(true test))(substring tmp 2)))))
(replace "+" temp " ")
temp)
#
(define (cgigetargs input mode , outout x y z)
(if input
(begin
(set 'output '())
(replace "-" input "%2D")
(dolist (elmnt (parse input "&"))
(replace "=" elmnt " ")
(set 'output
(cons
(list (cgiexpand (first (parse elmnt)) mode)
(if (first (rest (parse elmnt)))
(cgiexpand (join (rest (parse elmnt))) mode) ""))) output)))
(reverse output))))
#
#
(print "Content-type: text/html\n\n")
(print "<h3>Form Variables</h3>\n")

(set 'input (read-line))
(print (cgigetargs input T))
#
(print "<p>Input = " input "<p>\n")
#
# command line arguments
(print "Command line = " (main-args) "<p>\n")

#
# print environment variables
(print "<h3>Environment Variables</h3>\n")
(dolist (env (environ)) (print env "<br>"))
(print "\n\n")

(exit)

#

PostPosted: Sun Nov 03, 2002 12:39 am
by Lutz
Nice trick with 'parse' to split the input at the right places where % characters are, and the 'cond' swhitch pretty much documents what the function does.

But as Larry Wall would say "there is more than one way to do it". This is what I am using:
Code: Select all
;; cgi.lsp - basic CGI routines for use in newLISP CGI propcessing
;;
;; include this at the beginning of cgi programs wriiten in newLISP
;;
;;

;; url-translate translates + into spaces and %nn hesxdigits into
;; characters
;;
(define (url-translate s , lst pos)
   (replace "+" s " ")
   (while (set 'pos (find "%[[:xdigit:]][[:xdigit:]]" s 0))
    (push (slice s 0 pos) lst)
    (push (char (integer (append "0x" (slice s (+ pos 1) 2)))) lst)
    (set 's (slice s (+ pos 3))))
   (push s lst)
   (join (reverse lst)))


;; get-vars returns all parameter value pairs in an association list
;; i.e.: ( ("name" "johndoe") ("password" "secret") )
;;
(define (get-vars input , name value vars var-value)
    (set 'vars (parse input "&"))
    (dolist (elmnt vars)
        (begin
            (set 'name (first (parse elmnt "=")))
            (set 'value (last (parse elmnt "=")))   
       (push (list name (url-translate value)) var-value)))
    var-value)


;; get QUERY_STRING parameters from GET method if present
;; this relies on an environment variable created by the webserver,
;; works on Apache, don't know about Win IIS
;;
(set 'params (getenv "QUERY_STRING"))
(if params
   (set 'params (get-vars params)))


;; get stdin POST method parameters if present
;;
(set 'inline (read-line))
(if inline
   (set 'params (get-vars inline)))
 

;; parameters can now be accessed using:
;;
;;   (assoc "name" params) => "johndoe"
;;


;; eof


The [:xdigit:] in the 'find' is just a POSIX character class, one could also use: [0-9a-fA-F] instead. The 'slice' is the new polymorphic function in 7.0 serving as the old 'substring' or 'sublist', polymorph like 'append'.

When running this file at the beginning of any cgi process all parameters are accessible in the 'params' associative array, no matter if they come from a GET or POST request.

Lutz

PostPosted: Sun Nov 03, 2002 2:05 am
by CaveGuy
I dont know about IIS but it works with Website PRO.
I like your solution, it is more elegant, I tend to brute force that sort of thing :)