From icon-group-sender Sat Feb 4 16:21:03 1995 Received: by cheltenham.cs.arizona.edu; Sat, 4 Feb 1995 16:20:37 MST Date: Sat, 4 Feb 95 17:23:24 CST From: goer@mithra-orinst.uchicago.edu (Richard L. Goerwitz) Message-Id: <9502042323.AA08253@mithra-orinst.uchicago.edu> To: icon-group@cs.arizona.edu Subject: Icon in CGI scripts Errors-To: icon-group-errors@cs.arizona.edu Status: R Several people have asked about use of Icon in HTTP-style CGI scripts. It seems to me that Icon is a good way of decoding the results of form requests. The problem that Icon cannot handle UTF-8 and/or Unicode is not really a problem, in that even when HTML starts using these as possible charset types, ISO 8859-1 will still be universally accepted, and UTF-8 es- sentially subsumes it (or does it only subsume ASCII - I for- get). In any case, Icon will work well. So here's a sample script that can serve as a template. Please post additions and ex- pansions or corrections.... Richard Goerwitz ============================================================== procedure main(a) local i, cl, n, name_tbl cl := integer(getenv("CONTENT_LENGTH")) name_tbl := table() # # output a minimal header, terminated by two newlines # write("Content-type: text/html\x0A\x0A") # # check that the request is correctly formatted; output # error message if it's not # getenv("REQUEST_METHOD") == "POST" | { writes("

error: METHOD must = \"POST\"

") exit(1) } getenv("CONTENT_TYPE") == "application/x-www-form-urlencoded" | { writes("

error: this script is for decoding form results only

") exit(1) } # # enter name=value lines as key/value pairs in name_tbl # while line := makeline(&input, "&", cl) do { line := unescape_url(map(line), "+", " ") line ? { n := tab(find("=")) move(1) if not (/name_tbl[n] := tab(0)) then { writes("

error: duplicate field name, ", n, "

") exit(1) } } } # # Output results. # writes("

Query Results

\x0A") writes("

You submitted the following name/value pairs:

\x0A") writes("\x0A") exit(0) end # # concatenate series' of non-ampersands into lines; stop # when you have read the number of characters in cl (arg # 3) # procedure makeline(f, stop_c, cl) local line, c static c_count initial c_count := 0 line := "" while c := reads(f) do { if (c_count +:= 1) > cl then break if c == stop_c then break line ||:= c } return "" ~== line end # # turn &xx (where xx are hex digits) into an integer; # output the character with that internal integer value # procedure unescape_url(url) local new_url new_url := "" url ? { while new_url ||:= tab(find("%")) & move(1) do new_url ||:= char(hex(move(2))) | tab(0) new_url ||:= tab(0) } return new_url end # # Bob Alexander's hex->integer code (overkill here) # procedure hex(s) local a,c a := 0 every c := !map(s) do a := ior(find(c,"0123456789abcdef") - 1, ishift(a,4)) | fail return a end # # procedure hexstring(i,n,lowercase) local s, hexchars, sign i := integer(i) | runerr(101, i) sign := "" if i = 0 then s := "0" else { if /n & i < 0 then { sign := "-" i := -i } hexchars := if \lowercase then "0123456789abcdef" else "0123456789ABCDEF" s := "" until i = (0 | -1) do { s := hexchars[iand(i,15) + 1] || s i := ishift(i,-4) } } if \n > *s then s := right(s,n,if i >= 0 then "0" else hexchars[16]) return sign || s end