Initial commit of newLISP.
[newlisp.git] / modules / cgi.lsp
blob881474063f87e692220e0e075690332349601717
1 ;; @module cgi.lsp
2 ;; @description Basic CGI processing tools for GET and POST requests
3 ;; @version v 2.2 - comments redone for automatic documentation
4 ;; @author Lutz Mueller, lutz@nuevatec.com
5 ;;
6 ;; This module defines basic CGI processing tools for processing
7 ;; CGI GET and POST requests and cookies.
8 ;;
9 ;; Include this file at the beginning of each file performing CGI processing:
10 ;; <pre>
11 ;; (load "/usr/share/newlisp/modules/cgi.lsp")
12 ;; </pre>
14 ;; <center><h2>Overview</h2></center>
15 ;; On loading 'cgi.lsp' will retrieve 'GET', 'POST' and cookie
16 ;; parameters via standard input and the environment variables:
17 ;; 'QUERY_STRING' and 'HTTP_COOKIE'. These environment variables are set
18 ;; by the webserver (tested with Apache 1.3). The webserver is receiving information
19 ;; back from 'cgi.lsp' via std I/O channels.
20 ;;
21 ;; After having loaded this file all parameters from either 'GET' or 'POST'
22 ;; method are stored as an association list and in 'CGI:params'
23 ;; and individual parameters can be accessed using 'CGI:get'.
25 ;; All cookies can be accessed in an association list 'CGI:cookies' and
26 ;; are accessed similar to the 'GET' and 'PUT' parameters using 'CGI:get-cookie'.
27 ;; A function 'CGI:set-cookie' is available for setting cookies.
29 ;; The function 'CGI:put-page' outputs a HTML page to the webserver after
30 ;; processing newLISP source embedded in '&lt;%' and '%&gt;' tags.
32 ;; 'CGI:params' and 'CGI:cookies' contain the empty list '()' when no
33 ;; parameters or cookies are present
35 ;; The function 'CGI:put-page' can be used to output web pages containing
36 ;; newLISP source embedded in &lt;%, %&gt; tags. Inside these tags are newLISP
37 ;; statements printing output/HTML to the webpage.
39 (context 'CGI)
41 ;; @syntax (CGI:put-page <str-file-name>)
42 ;; @return The page output to standard out.
44 ;; Processes an HTML page by evaluating newLISP source
45 ;; embedded into the HTML text between '&lt;%' and '%&gt;' tags.
46 ;; The newLISP source typically contains 'print' and 'println'
47 ;; statements to output strings to standard out.
49 ;; @example
50 ;; <html>
51 ;; <body>
52 ;; <% (set 'site "example.com") %>;
53 ;; <a href="http://<% (print site) %>"><% (print site) %></a>
54 ;; </body>
55 ;; </html>
56 ;;
57 ;; ; will output:
58 ;;
59 ;; <pre>
60 ;; <html>
61 ;; <body>
62 ;; <a href="http://example.com">example.com</a>
63 ;; </body>
64 ;; </html>
65 ;; </pre>
67 (define (put-page file-name , page start end)
68 (set 'page (read-file file-name))
69 (set 'start (find "<%" page))
70 (set 'end (find "%>" page))
71 (while (and start end)
72 (print (slice page 0 start))
73 (context MAIN)
74 (eval-string (slice page (+ start 2) (- end start 2)))
75 (context CGI)
76 (set 'page (slice page (+ end 2)))
77 (set 'start (find "<%" page))
78 (set 'end (find "%>" page)))
79 (print page))
81 ;; @syntax (CGI:url-translate <str-url-format>)
82 ;; @return An ASCII formatted string.
84 ;; Translates all URL formatted characters to ASCII. Translates '+' into spaces
85 ;; and '%nn' hexdigits into characters. 'nn' is a 2-nibble hex number.
87 ;; @example
88 ;; (CGI:url-translate "What+time+is+it%3f") => "What time is it?"
90 (define (url-translate str)
91 (replace "+" str " ")
92 (replace "%([0-9A-F][0-9A-F])" str (char (int (append "0x" $1))) 1))
95 ; This is not an user function, but used internally.
97 ; get-vars returns all parameter value pairs in an association list
98 ; i.e.: ( ("name" "johndoe") ("password" "secret") )
99 ; they can than be accessed using:
100 ; (assoc "name" params) => "johndoe"
101 ; where params is the return value from get-vars
103 (define (get-vars input , var value var-value)
104 (set 'vars (parse input "&"))
105 (dolist (elmnt vars)
106 (if (find "=" elmnt)
107 (begin
108 (set 'var (first (parse elmnt "=")))
109 (set 'value ((+ (find "=" elmnt) 1) elmnt)))
110 (begin
111 (set 'var elmnt)
112 (set 'value "")))
113 (push (list var (url-translate value)) var-value))
114 var-value)
117 ; get QUERY_STRING parameters from GET method if present
119 (set 'params (env "QUERY_STRING"))
120 (if (not params) (set 'params ""))
121 (if params
122 (set 'params (get-vars params)))
124 ; get stdin POST method parameters if present
126 (set 'inline (read-line))
127 (if inline
128 (set 'params (get-vars inline)))
130 (if (not params) (set 'params '()))
132 ; get cookies
134 (if (env "HTTP_COOKIE")
135 (dolist (elmnt (parse (env "HTTP_COOKIE") ";"))
136 (set 'var (trim (first (parse elmnt "="))))
137 ; (set 'value (trim (last (parse elmnt "="))))
138 (set 'value (slice elmnt (+ 1 (find "=" elmnt))))
139 (push (list var value) cookies))
140 (set 'cookies '()))
142 ;; @syntax (CGI:set-cookie <str-var> <str-value> <str-domain> <str-path>)
143 ;; @param <str-var> The cookie variable name as a string.
144 ;; @param <str-value> The cookie value as a string.
145 ;; @param <str-domain> The domain where to set the cookie.
146 ;; @param <str-path> The path for the domain.
147 ;; @return The string sent to standard out by 'CGI:set-cookie'.
149 ;; This function should be called immedeately before
150 ;; closing the header with '(print "Content-type: text/html\r\n\r\n")',
151 ;; which is typically the first statement in a CGI script written in
152 ;; newLISP after the '(load "cgi.lsp")' statement.
154 ;; @example
155 ;; (load "cgi.lsp")
157 ;; (CGI:set-cookie "password" "secret" "asite.com" "/somedir")
158 ;; (print "Content-type: text/html\r\n\r\n")
159 ;; ...
161 (define (set-cookie var value domain path)
162 (set 'value (string value))
163 (print (format "Set-Cookie: %s=%s; domain=.%s; path=%s;\n" var value domain path)))
166 ;; @syntax (CGI:get-cookie <str-key>)
167 ;; @param <str-key> The string for the cookie variable name.
168 ;; @return The string for the cookie value.
170 ;; @example
171 ;; (CGI:get-cookie "login") => "somebody"
173 (define (get-cookie keystr)
174 (lookup keystr cookies) )
176 ;; @syntax (CGI:get <str-key>)
177 ;; @param The name of the 'GET' or 'POST' variable as a string.
178 ;; @return The value string of the 'GET' or 'POST' variable.
180 (define (get keystr)
181 (lookup keystr params))
183 ;; @example
184 ;; (CGI:get "city") => "San Francisco"
187 (context 'MAIN)
188 ; eof ;