Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

How to file upload via http?

 [1/8] from: jason:cunliffe:verizon at: 21-Aug-2002 23:45


Does anyone have an example of a rebol server-side script to handle file upload via http ? For example, an HTML page with a form: <form method="post" action="savefile.r" enctype="multipart/form-data" /> <p>Select an image or script file to upload </p> <fieldset> <legend>File to upload:<br /></legend> <input type="hidden" name="MAX_SIZE" value="50000" /><br/> <input type="file" name="FILE_NAME" size="50" /><br/> <input type="submit" value="UPLOAD FILE" /><br/> </fieldset> </form> What should %savefile.r look like? thanks ./Jason

 [2/8] from: gchiu:compkarori at: 22-Aug-2002 17:09


>What should %savefile.r look like?
I can't recall if I've made any changes to this, but I recall testing it and I think it worked for me. #!/path/to/rebol -cs REBOL [ Title: "multipart POST" Date: 15-Sep-1999 Version: 1.2 File: %POST.r Author: "Andrew Grossman (modified by: Luis Rodriguez J -.29-April-2000)" Email: [grossdog--dartmouth--edu] Owner: "REBOL Technologies" Purpose: { To decode multipart encoded POST requests, including file uploads. } Usage: { Call this file in your CGI scriptand do decode-multi with a file argument of the directory where uploaded files will go and a logic argument to set whether files will be given the field they were uploaded as as a name. Files are saved and variables are decoded and set. } Notes: { Fixed problem recognizing EOF. Functionality is now rock solid. Function calls won't change, so this is certainly useable. See the comment in the decode-multi function if you need mime types. Tested with MSIE and Netscape for Mac. } category: ['web 'cgi 'utility] ] print "Content-Type: text/html^/^/" print {<HTML><BODY>} decode-multi: func [ file-dir [file!] {Directory in which to put uploaded files} save-as-field [logic!] {save files as field name or uploaded filename} /local str boundary done name file done2 content ] [ if equal? system/options/cgi/request-method "POST" [ either not parse system/options/cgi/content-type ["multipart/form-data" skip thru {boundary=} skip some {-} copy boundary to end] ; not multipart [str: make string! input do decode-cgi str] [ print "Decoding multipart data" str: make string! input done: false while [not done] [ name: make string! "" str: make string! input either equal? "" str [done: true] [ either parse/all str [skip thru {name="} copy name to {"} skip thru {filename="} copy file to {"} skip to end] [ str: make string! input if not equal? str "" [str: make string! input] comment {if you need mime put "parse/all str ["Content-Type:" skip copy mime to end]" into the preceding if block.} done2: false content: make string! "" while [not done2] [ content-length: to-integer system/options/cgi/content-length str: make string! content-length read-io system/ports/input str content-length either d: find/reverse tail str boundary [ e: find/reverse tail copy/part str (index? d) {^/} content: copy/part str (index? e) - 2 done2: true] [ append content str ] ] write/binary %content.bin str if not none? file [ either save-as-field [name: dehex name write/binary file-dir/:name content] [ file: dehex file write/binary file-dir/:file content ] ] ] [ parse str [skip thru {name="} copy name to {"}] str: make string! input str: dehex make string! input set to-word name str str: make string! input ] ] ] ] ] ] ; of If Post decode-multi %. true print "Form Processed" print {</BODY></HTML>} -- Graham Chiu

 [3/8] from: jason:cunliffe:verizon at: 22-Aug-2002 4:55


Thanks Graham Yes multipart %post.r script looks like the business.. It's _almost_ working. But I keep getting this error -> Decoding multipart data ** Access Error: Cannot open /web/turbulence/www/Works/trees/vanilla/content.bin ** Where: decode-multi ** Near: write/binary %content.bin str if not I think somthing to do with the MIME types. There's a comment in the script for changing an 'if' statement, but I don't grok it yet. Any ideas? ./Jason

 [4/8] from: gchiu:compkarori at: 23-Aug-2002 9:09


>Yes multipart %post.r script looks like the business.. >It's _almost_ working. But I keep getting this error -> > >Decoding multipart data ** Access Error: Cannot open >/web/turbulence/www/Works/trees/vanilla/content.bin ** >Where: decode-multi ** >Near: write/binary %content.bin str if not
Hi Jason, You sure it's not a permissions problem? Perhaps stick in a line to write a few bytes to another file in the same directory to see what happens... -- Graham Chiu

 [5/8] from: andreas:bolka:gmx at: 22-Aug-2002 23:04


Thursday, August 22, 2002, 5:45:09 AM, Jason wrote:
> Does anyone have an example of a rebol server-side script to handle file upload > via http ?
I've a 'decode-multipart-form-data avail (as I guess that you are interested in this becaus of vanillla, this will be distributed with vanilla 0.5.2) I guess for a simple savefile CGI this will be a bit harder to use than %POST.r, but I think decode-multipart-form-data is a cleaner approach - let me know what you think! Here it is: -- snip -- REBOL [ Title: "decode-multipart-form-data" Authors: [ "Andreas Bolka" ] Contributors: [ ] Date: 2002-06-18 Version: 1.1 Purpose: { Decodes POST-data encoded as "multipart/form-data" as defined by RFC 2388. The output is compatible to 'decode-cgi wherever possible. So the output contains a list of set-word's and values, one pair for each data field. example: [ field1: "foo" field2: "bar" ] If the content type of one part of the form-data is not equal to text/plain, then the value of the respective mime-part is an object! with the following attribs: filename, type, content. example: [ field1: "foo" field2: make object! [ filename: "user.xml" type: "text/xml" content: "<?xml version='1.0'><user />" ] ] } ] decode-multipart-form-data: func [ p-content-type p-post-data /local list ct pd bd delim-beg delim-end mime-part ] [ list: copy [] if not found? find p-content-type "multipart/form-data" [ return list ] ct: copy p-content-type pd: copy p-post-data bd: join "--" copy find/tail ct "boundary=" delim-beg: join crlf crlf delim-end: rejoin [ crlf bd ] mime-part: [ ( ct-dispo: content: none ct-type: "text/plain" ) thru bd thru "content-disposition: " copy ct-dispo to crlf opt [ thru "content-type: " copy ct-type to crlf ] thru delim-beg copy content to delim-end ( handle-mime-part ct-dispo ct-type content ) ] handle-mime-part: func [ p-ct-dispo p-ct-type p-content /local fieldname ] [ p-ct-dispo: parse p-ct-dispo {;="} fieldname: select p-ct-dispo "name" append list to-set-word fieldname either found? find p-ct-type "text/plain" [ append list content ] [ append list make object! [ filename: select p-ct-dispo "filename" type: copy p-ct-type content: either none? p-content [ none ] [ copy p-content ] ] ] ] use [ ct-dispo ct-type content ] [ parse/all pd [ some mime-part ] ] list ] -- snap -- -- Best regards, Andreas mailto:[andreas--bolka--gmx--net]

 [6/8] from: jason::cunliffe::verizon::net at: 22-Aug-2002 18:34


Hi Graham Yes - I needed to flip permission bit on the directory it was in :) thanks ./Jason

 [7/8] from: jason:cunliffe:verizon at: 22-Aug-2002 18:38


Andreas Thanks for the new multiform data code. It must dinner time because my brain is getting slow.. Can you help me understand how to use it? thanks ./Jason

 [8/8] from: andreas:bolka:gmx at: 23-Aug-2002 17:40


Friday, August 23, 2002, 12:38:09 AM, Jason wrote:
> Can you help me understand how to use it?
-- snip -- ; first you fetch the post-data (the HTTP POST entity body, ; to be correct) as always len: load any [ system/options/cgi/content-length "0"] post-data: make string! (len + 10) while [len > 0][ len: len - read-io system/ports/input post-data len ] ; then this POST-data can be handed over to decode-multipart-form-data ; (if it is encoded according to the mime multipart RFC's as ; indicated by a content type beeing multipart/form-data) tmp-post: either found? find any [ system/options/cgi/content-type "" ] "multipart/form-data" [ decode-multipart-form-data system/options/cgi/content-type post-data ] [ decode-cgi post-data ] -- snap -- after that you'll have a decode-cgi like structure in tmp-post which is described in full detail in the headers of the script i posted before: -- snip -- Purpose: { Decodes POST-data encoded as "multipart/form-data" as defined by RFC 2388. The output is compatible to 'decode-cgi wherever possible. So the output contains a list of set-word's and values, one pair for each data field. example: [ field1: "foo" field2: "bar" ] If the content type of one part of the form-data is not equal to text/plain, then the value of the respective mime-part is an object! with the following attribs: filename, type, content. example: [ field1: "foo" field2: make object! [ filename: "user.xml" type: "text/xml" content: "<?xml version='1.0'><user />" ] ] } -- snap -- -- Best regards, Andreas mailto:[andreas--bolka--gmx--net]