[REBOL] [ANN] 'decode-multipart/form-data object!
From: ryan::christiansen::intellisol::com at: 2-May-2001 14:03
The following function will decode multipart/form-data as retrieved using
POST from a web form. It will return an object as you would expect from
decode-cgi, but the object will also include values 'filename and
'file-mime-type. The object will include the contents of the file you
uploaded using an <INPUT TYPE="file" NAME="name"> tag, placing the contents
of the file in binary form in object-name/name (where "name" is the value
of the NAME attribute in the INPUT tag.) The function *should* work for
uploading multiple files.
HOWEVER...
This function seems to only work well with uploading files approximately
8KB or less and so it works well with thumbnail-sized images.
Postcard-sized or photograph-sized images are generally too large. I can't
understand why this function is having problems with files larger than
approximately 8KB. If anyone has a good idea about this, please let me
know.
You can test this function at this URL:
http://www.fargonews.com/post-data.html
The function is written as 'form-data, the child of the object!
decode-multipart. I hope to add more multipart-family functions to the
object in the future.
The code for the function follows...
-Ryan
decode-multipart: make object! [
form-data: func [
][
content-length: 20 + load system/options/cgi/content-length
post-data: make string! content-length
read-io system/ports/input post-data content-length
post-data: make binary! post-data
parse/all post-data [to "----" copy text thru "^/" (boundary: copy
text)]
cd-block: []
parse/all post-data [
any [thru boundary copy text [to boundary | to end] (text: make
binary! text append cd-block text)]]
cd-input: []
foreach cd cd-block [
either find cd "filename" [
parse/all cd [thru {name="} copy text to {"} (append
cd-input text)]
parse/all cd [thru {filename="} copy text to {"}
(file-path-string: copy text)]
file-path-block: parse/all file-path-string {\/"}
filename: last file-path-block
parse/all cd [thru {Content-Type: } copy text to {^M^/}
(file-mime-type: copy text)]
; parse/all cd [thru {^M^/^M^/} copy text to {^M^/} (text:
make binary! text append cd-input text)]
parse/all cd [thru {^M^/^M^/} copy text [to boundary | to
end] (text: make binary! text append cd-input text)]
][
parse/all cd [thru {name="} copy text to {"} (append cd-input
text)]
parse/all cd [thru {^M^/^M^/} copy text to {^M^/} (append
cd-input text)]
]
]
cd-input: head cd-input
object-data: make object! []
for x 1 (length? cd-input) 2 [
variable: first cd-input
cd-input: next cd-input
value: first cd-input
either binary? value [
make-object-data: reform [rejoin [{object-data: make
object-data [} (variable) {: } (value) {]}]]
][
make-object-data: reform [rejoin [{object-data: make
object-data [} (variable) {: ^{} (value) {^}]}]]
]
do make-object-data
cd-input: next cd-input
]
make-object-data: reform [rejoin [{object-data: make object-data
[filename: ^{} (filename) {^}]}]]
do make-object-data
make-object-data: reform [rejoin [{object-data: make object-data
[file-mime-type: ^{} (file-mime-type) {^}]}]]
do make-object-data
object-data
]
]
Ryan C. Christiansen
Web Developer
Intellisol International
4733 Amber Valley Parkway
Fargo, ND 58104
701-235-3390 ext. 6671
FAX: 701-235-9940
http://www.intellisol.com
Global Leader in People Performance Software
_____________________________________
Confidentiality Notice
This message may contain privileged and confidential information. If you
think, for any reason, that this message may have been addressed to you in
error, you must not disseminate, copy or take any action in reliance on it,
and we would ask you to notify us immediately by return email to
[ryan--christiansen--intellisol--com]