View in color | View documentation | License |
Download script | History | Other scripts by: sunanda |
7-Sep 23:54 UTC
[0.241] 13.563k
[0.241] 13.563k
safe-cgi-data-read.rREBOL [
Title: "Safe CGI data retriever"
Date: 21-may-2006
File: %safe-cgi-data-read.r
Author: "Sunanda"
Version: 0.0.2
Purpose: {
Safely retrieves CGI GET or POST data
into a REBOL object.
}
library: [
level: 'intermediate
platform: 'all
type: [function how-to tool]
domain: [cgi other-net]
tested-under: [Windows UNIX]
support: none
license: 'mit
see-also: none
]
History: [
0.0.1 21-may-2006 "Sunanda" "first release"
0.0.2 22-jun-2011 "Sunanda" "tweak by Peter Wood to allow running from console"
]
]
safe-cgi-data-read: func [ "Safe way to read CGI parameter data"
/template template-obj [object!] "Default values"
/keep-blocks "Do not collapse blocks to strings"
/no-trim "Do not trim whitespace"
/refresh "Do not use cached data"
/local
cgi-string
cgi-block
cgi-object
read-cgi
temp
][
;; -----------------------------
;; Inner function -- copied from
;; http://www.rebol.com/docs/words/wread-io.html
;; ---------------------------------------------
read-cgi: func [
;Read CGI data. Return data as string or NONE.
/local data buffer
][
switch system/options/cgi/request-method [
"POST" [
data: make string! 1020
buffer: make string! 16380
while [positive? read-io system/ports/input buffer 16380][
append data buffer
clear buffer
]
]
"GET" [data: system/options/cgi/query-string]
#[none] [data: system/script/args] ;; 0.0.2 -- Peter Wood's tweak
]
data
]
;; -------------------------
;; mainline code starts here
;; -------------------------
;; -----------------------------------
;; Read CGI -- unless we had it cached
;; already from a previous invocation
;; -----------------------------------
cgi-string: ""
if refresh [clear cgi-string]
if cgi-string = "" [temp: read-cgi if string? temp [append cgi-string temp]]
;; ------------------------------------------
;; preprocess to fix bad ampersands and SELF=
;; ------------------------------------------
insert cgi-string "&" ;; insert to make life easier
while [find cgi-string "&&"] [replace/all cgi-string "&&" "&"]
replace cgi-string "&self=" "&__self="
cgi-string: copy next cgi-string ;; drop the inserted ampersand
;; ------------------------------
;; create a block with decode-cgi
;; ------------------------------
;; This may fail if the parameters
;; are badly formed -- like
;; "&=1"
;; decode-cgi may also return NONE
;; or a zero-length string if is no
;; cgi data to read
cgi-block: copy []
attempt [cgi-block: decode-cgi cgi-string]
if not block? cgi-block [cgi-block: copy []]
;; ---------------------------------------
;; Post-process the resulting data fields:
;; ---------------------------------------
;; -- changing blocks to strings, if requested
;; -- trimming whitespace, if requested
for n 2 length? cgi-block 2 [
temp: cgi-block/:n
if all [not keep-blocks
block? temp][
temp: form temp
]
if all [string? temp not no-trim] [trim/lines temp]
poke cgi-block n temp
]
;; ----------------------------
;; Heft into object, and return
;; ----------------------------
if not template [return make object! cgi-block]
return construct/with cgi-block template-obj
] Notes
|