formCGI "POST" example

Q&A's, tips, howto's
Locked
CaveGuy
Posts: 112
Joined: Sun Oct 13, 2002 3:00 pm
Location: Columbus Ohio
Contact:

formCGI "POST" example

Post 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)

#
Bob the Caveguy aka Lord High Fixer.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post 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

CaveGuy
Posts: 112
Joined: Sun Oct 13, 2002 3:00 pm
Location: Columbus Ohio
Contact:

Post 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 :)
Bob the Caveguy aka Lord High Fixer.

Locked