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

html post

 [1/42] from: javierd:paralax:mx at: 6-Aug-2002 0:43


Hello. I am writting a cgi-script so a user could upload some files to my site from a web page. I take as start the "CGI Form Dumper" " from the library, altough i have to patch it a bit so it could work, i decidet to use post, since some files are big (up to 2 MB..) My problem is that the uploaded files seems to be corrupted. Text/files have the CR/LF changed altough the save specifies bynary. And save files seems to be some of bytes bigger... there could be a problem decoding the port, or maybe parsing it, but i can,t find the problem. another thing is that maybe i am using the wrong aproach... It could be simples to sue FTP, but for most of my users this sounds like greek...and asking to instal rebol and a script is too much... so i would apreciate any sugestion... mmmmh. a im a "weekend programmer.." so please be patient... Javier Delgado Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [2/42] from: g:santilli:tiscalinet:it at: 6-Aug-2002 11:10


Hi Javier, On Tuesday, August 6, 2002, 7:43:07 AM, you wrote: JD> My problem is that the uploaded files seems to be corrupted. Text/files JD> have the CR/LF changed altough the save specifies bynary. And save files JD> seems to be some of bytes bigger... I assume you are reading your data from the server via SYSTEM/PORTS/INPUT; this port is, by default, opened as STRING, not BINARY, and this is the reason for the conversion of line terminators (and thus corruption of binary files). A: set-modes system/ports/input [binary: true] at the start of your CGI script should be enough to solve your problem. (Maybe you'll need to switch it back to STRING mode for outputting data, but it should not be required if you pay attention to the line terminators you are sending.) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [3/42] from: javierd:paralax:mx at: 6-Aug-2002 21:50


At 11:10 a.m. 06/08/2002 +0200, you wrote:
>Hi Javier, >On Tuesday, August 6, 2002, 7:43:07 AM, you wrote:
<<quoted lines omitted: 5>>
>not BINARY, and this is the reason for the conversion of line >terminators (and thus corruption of binary files).
thanks i will try it. ia am using : str: make string! input do decode-cgi str I supose this is what one gets using voodo programing ( not undestanding the code...) Javier Delgdo Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [4/42] from: javierd:paralax:mx at: 7-Aug-2002 3:55


At 11:10 a.m. 06/08/2002 +0200, you wrote:
>I assume you are reading your data from the server via >SYSTEM/PORTS/INPUT; this port is, by default, opened as STRING, >not BINARY, and this is the reason for the conversion of line >terminators (and thus corruption of binary files). > > set-modes system/ports/input [binary: true]
if a set this, my script does not work, so I asume is not compatible with cgi-decode? should i read directly the imput string and parse it? Javier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [5/42] from: g:santilli:tiscalinet:it at: 7-Aug-2002 12:11


Hi Javier, On Wednesday, August 7, 2002, 4:50:12 AM, you wrote: JD> ia am using : JD> str: make string! input do decode-cgi str Are you sending the files in text/www-form-urlencoded format? If you're getting your data as multipart/form-data as I think you are, DECODE-CGI isn't able to process it AFAIK... Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [6/42] from: g:santilli:tiscalinet:it at: 7-Aug-2002 12:25


Hi Javier, On Wednesday, August 7, 2002, 10:55:12 AM, you wrote: JD> should i read directly the imput string and parse it? Yes, if you are sending files and not just data from the browser, because DECODE-CGI does not handle them. I think you will find the code to handle file uploads in the Script Library. (Maybe others can point you to the right script to look at.) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [7/42] from: javierd:paralax:mx at: 7-Aug-2002 11:42


At 12:11 p.m. 07/08/2002 +0200, you wrote:
>Are you sending the files in text/www-form-urlencoded format? If >you're getting your data as multipart/form-data as I think you >are, DECODE-CGI isn't able to process it AFAIK...
mmmh.. i am using: <form action="/cgi-bin/dump-post.cgi" method="post" enctype="multipart/form-data" name="upload"> I could not send files with other options.... it seems I need to read more what going on.... :-/ Javier Delgado Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [8/42] from: javierd:paralax:mx at: 7-Aug-2002 11:54


>Yes, if you are sending files and not just data from the browser, >because DECODE-CGI does not handle them. I think you will find the >code to handle file uploads in the Script Library. (Maybe others >can point you to the right script to look at.)
The "easier" code i found in the library use the decode-cgi function... and requires enctype="multipart/form-data" So, if i understand the process. i should set the port to binay, and read the data form the port? the code i found is: input-cgi: func [/stdin] [ stdin: make string! 15000 either system/options/cgi/request-method = "POST" [ read-io system/ports/input stdin 15000 return stdin ][ system/options/cgi/query-string ] ] Is this correct?. should I set the string to the maximum size i will expect?.. in this case about 2 MB... now, how is this data formated?, where i can found this info, so i could parse it..? I looks interesting... Javier Delgado Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [9/42] from: al:bri:xtra at: 8-Aug-2002 7:37


> input-cgi: func [/stdin] [ > stdin: make string! 15000 > either system/options/cgi/request-method = "POST" [ > read-io system/ports/input stdin 15000
An important point I rediscovered in writing my Rebol/Wiki script, is to make sure that the number in the call to read-io is one or two _*less*_ than the allocated size! In other words, like: stdin: make string! 15000 + 2 ; Required spare space for read-io! either system/options/cgi/request-method = "POST" [ read-io system/ports/input stdin 15000 The relevant code from my Rebol/Wiki is: if Post? [ use [Length] [ ; Extra length for use by Rebol's 'read-io. Query: make string! 2 + Length: to-integer Rebol/options/cgi/content-length read-io Rebol/ports/input Query Length Query ] ] And for writing binary data, from my Rebol/Wiki: Mime-Data: func [Mime [path!] Data [binary!]] [ print ["Content-Type:" :Mime newline] write-io system/ports/output Data length? Data quit ] and used like: Mime-Data 'application/pdf read/binary %MyAdobe.pdf Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [10/42] from: al:bri:xtra at: 8-Aug-2002 7:47


Javier, you might be interested in looking at my Rebol/Wiki. It's a CGI script, that reads POST-ed form data, as well as GET urls. It's attached. Andrew Martin ICQ: 26227169 http://valley.150m.com/ -><- ----- Original Message ----- From: "Javier Delgado" <[javierd--paralax--com--mx]> To: <[rebol-list--rebol--com]> Sent: Thursday, August 08, 2002 4:42 AM Subject: [REBOL] Re: html post
> At 12:11 p.m. 07/08/2002 +0200, you wrote: > >Are you sending the files in text/www-form-urlencoded format? If
<<quoted lines omitted: 9>>
> www.paralax.com.mx > Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d,
anaglifos
> tel 5373 3620 y 5363 4953 > Naucalpan de Juarez, Edo. Mex.
<<quoted lines omitted: 5>>
> [rebol-request--rebol--com] with "unsubscribe" in the > subject, without the quotes.
-- Attached file included as plaintext by Listar -- -- File: Wiki.r #! C:\Rebol\View\rebol.exe -cs Rebol [ Name: 'Wiki Title: "Wiki" File: %Wiki.r Author: "Andrew Martin" eMail: [Al--Bri--xtra--co--nz] Web: http://valley.150m.com Date: 6/August/2002 Version: 1.3.3 Purpose: {Wiki. Creates a Wiki using Rebol and the Xitami web server.} Category: [util net markup 5] Comments: { In %/Xitami/xitami.cfg -- the Xitami configuration file, in the [Mime] section, add: htc=text/plain to allow the %Calender.htc hypertext component to be sent. Caution: Hypertext components only work with MSIE! Also, change: js=application/x-javascript to: js=text/javascript so as to correctly set the MIME for JavaScript files. } Defects: { Need to fix up dates. Decide on Active Rebol Content: - Parrallel to Wiki? - Inside Wiki? - Part of Wiki? - Something else? } ] if not value? 'Values [ do %/C/Rebol/Values/Values.r ] Remote: %/C/Xitami/cgi-bin/ ; Change to suit Colenso IIS! Wiki_Folder: %/C/Rebol/Wiki/Files/ ; Where all the Wiki's .txt files are stored. Stylesheet: %Wiki.css if none? system/options/cgi/script-name [ foreach File read %. [ if found? find [ %.r %.jpg %.png %.gif %.css %.htc %.js ] extension? File [ write/binary Remote/:File read/binary File ] ] ] if none? Rebol/options/cgi/script-name [ browse http://localhost/cgi-bin/Wiki.r? quit ] See-Other: func [URL [url!]] [ print rejoin [ Rebol/options/cgi/server-protocol " Status: 303 See Other" newline "Location: " URL newline ] quit ] Envelope: func [Title [string!] Body [block!]] [ content-type 'text/html print newline print ML compose/deep [ <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> html [ head [ title (Title) link/rel/type/href "stylesheet" "text/css" (Stylesheet) script/type/language/src "text/javascript" "JavaScript" %Wiki.js "" ] body/onload/id "SetColumnHeight (HtmlElement)" "HtmlElement" [(Body)] ] ] quit ] Log: func [Value] [ write/append %Log.txt reform [now/time mold Value newline] Value ] Inspect: func [Value] [ Envelope "Inspect" compose/deep [ div/id "Center_Column" [ h1 "Inspect" p ["As of: " (now/time) ", the value is: "] pre [(mold Value)] ] ] ] Mime-Data: func [Mime [path!] Data [binary!]] [ print ["Content-Type:" :Mime newline] write-io system/ports/output Data length? Data quit ] Forbidden: {:*?"<>|/\.} ; A Wiki file name cannot contain any of these characters. Permitted: complement charset Forbidden Magic: #"*" Wiki: make object! [ Name: [some Permitted] set 'Wiki_Filename_Rule Filename: [Name opt [#"." Name]] Relative_Folder: [some [Name #"/"]] Absolute_Folder: [#"/" opt Relative_Folder] set 'Wiki_Folder_Rule Folder: [Absolute_Folder | Relative_Folder] set 'Wiki_File_Rule File: [opt Folder Filename | Folder] Files: sort recursive-read Wiki_Folder Rebols: make block! 10 use [Folder File] [ forall Files [ if all [ (%.r = extension? File: first Files) Folder: pick Files 2 (#"/" = last Folder) (= filename? File filename? Folder) ] [ remove/part Files 2 ] ] Files: head Files ] Folders: make block! length? Files foreach File Files [ if #"/" = last File [ append Folders File ] ] sort/compare Folders func [File1 [file!] File2 [file!]] [> length? File1 length? File2] ] Separator: charset "/-" Month_Rule: [1 2 digit | 3 12 alpha] Date_Rule: [ [1 2 digit Separator Month_Rule Separator [4 digit | 2 digit]] | [4 digit Separator Month_Rule Separator 1 2 digit] ] Deplus: func [String [string!]] [ replace/all dehex replace/all copy String #"+" #" " CRLF newline ] CGI: make object! [ Post?: "POST" = Rebol/options/cgi/request-method Get?: "GET" = Rebol/options/cgi/request-method Script-File: to-file Rebol/options/cgi/script-name Script-URL: join make url! compose [ http (join Rebol/options/cgi/server-name Rebol/options/cgi/script-name) ] #"?" Query: Rebol/options/cgi/query-string SubFolder_Rule: #" " ; A space will never arrive from browser as it's encoded to " ". if not empty? Wiki/Folders [ SubFolder_Rule: make block! 2 * length? Wiki/Folders foreach Folder Wiki/Folders [ repend SubFolder_Rule [ replace/all form Folder #" " " " '| ] ] remove back tail SubFolder_Rule ] Tuple_Rule: [ some [some Permitted #"|"] ] Decode: function [Args [any-string! none!]] [Block Folder Name Value Error] [ Block: make block! 10 either all [ string? Args not empty? Args parse/all Args [ [ some [ [[Magic | "%2A"] copy Name [Alpha some [AlphaDigit | #"-" | #"_"]]] [ (Value: none) #"=" [[copy Value to #"&" skip] | [copy Value to end]] ] ( append Block compose [ (to-set-word Name) (all [Value Deplus Value]) ] ) ] end ] | [ opt [ copy Folder [opt #"/" SubFolder_Rule] ( Folder: to-file deplus Folder ) ] opt [ copy Value Date_Rule ( Error: error? try [ Name: 'Date Value: load Value ] ) | copy Value Tuple_Rule ( Name: 'Tuple ) | copy Value Wiki_File_Rule ( Name: 'File Value: to-file deplus Value ) ] opt [#"?" (Name: 'Search)] end ( if all [ none? Value Folder ] [ Value: Folder Folder: none ] if none? Name [ Name: 'File ] if Folder [ append Block compose [ Folder: (Folder) ] ] append Block compose [ (to-set-word Name) (Value) ] ) ] ] not Error not empty? Block ] [ make object! Block ] [ none ] ] Object: Decode any [ if Get? [Query] if Post? [ use [Length] [ ; Extra length for use by Rebol's 'read-io. Query: make string! 2 + Length: to-integer Rebol/options/cgi/content-length read-io Rebol/ports/input Query Length Query ] ] ] all [ string? Query Query: Deplus Query ] ] Folder_Buttons: function [File [file! none!]] [Folders Stack Folder] [ if none? File [ return "" ] if all [ not empty? File #"/" != first File ] [ File: head insert File #"/" ] compose/deep [ div/id "Left_Column" [ form [ ( Folders: parse/all File "/" if all [ 1 = length? Folders empty? Folders/1 ] [ clear Folders ] Stack: make block! 6 * length? Folders for Index 1 -1 + length? Folders 1 [ Folder: Folders/:Index push Stack compose/deep [ input/type/value/onclick/title/class "button" (join Folder #"/") ( rejoin [ "window.location='" CGI/Script-URL copy/part File find/tail File join Folder #"/" {'} ] ) "Click to change Folder" "Folders" br ] ] Stack ) ] ] ] ] Command: CGI/Object if all [ none? Command string? CGI/Query not empty? CGI/Query ] [ See-Other CGI/Script-URL ] if none? Command [ Command: make object! [ File: %/ ] ] if in Command 'Date [ Command: make Command [ File: join to-file Command/Date %.txt ] ] Random_Page: make object! [ random/seed now Title: "Random" Command?: function [Command [object!]] [File] [ if all [ in Command 'Random Title = Command/Random not empty? Wiki/Files ] [ File: first random Wiki/Files See-Other rejoin [CGI/Script-URL File] ] ] GUI: does [ if not empty? Wiki/Files [ compose/deep [ form/id/name/method/action (Title) (Title) "GET" (CGI/Script-File) [ input/type/name/value "hidden" (join Magic Title) (Title) input/type/value/title "submit" (Title) "Click for a random page" ] ] ] ] ] Search: make object! [ Title: "Search" Command?: function [Command [object!]] [Query Results Text Index Heading] [ if in Command 'Search [ if none? Query: Command/Search [ See-Other CGI/Script-URL ] Query: to-string Query Results: make block! 100 append Results [ tr [ th "Results" th "Document" ] ] foreach File Wiki/Files [ if %.txt = Extension? File [ Text: read Wiki_Folder/:File if found? Index: find Text Query [ File: head clear Extension? File append Results compose/deep [ tr [ td [ (rejoin ["..." copy/part Index -35]) span/class "Hilight" (copy/part Index length? Query) (append copy/part at Index 1 + length? Query 35 "...") ] td [ a/href ( rejoin [CGI/Script-File #"?" #"/" File] ) (File) ] ] ] ] ] ] Envelope Heading: rejoin ["Search: " Query] compose/deep [ (Folder_Buttons %/.) div/id "Center_Column" [ h1 (Heading) table [(Results)] ] div/id "Commands" [ (Random_Page/GUI) (Search/GUI Query) ] ] ] ] GUI: func [Default [string!]] [ compose/deep [ form/id/name/method/action (Title) (Title) "GET" (CGI/Script-File) [ label [ (rejoin [Title #" " Rebol/script/header/title ": "]) input/type/name/value/title "text" (join Magic Title) (Default) "Enter your search phrase here." ] input/type/value/title "submit" (Title) "Click button to search for your phrase in every page." ] ] ] ] Save_Page: make object! [ Title: "Save" Command?: function [Command [object!]] [Folder Name File] [ if all [ in Command 'Folder Folder: Command/Folder in Command 'Name Name: Command/Name Name: to-file deplus Name in Command 'Text ] [ if not file? Folder [ Folder: to-file deplus Folder ] File: Folder/:Name any [ Extension? File File: Extension File %.txt ] See-Other rejoin [ CGI/Script-URL either none? Command/Text [ if exists? Wiki_Folder/:File [ delete Wiki_Folder/:File ] any [Folder? File %/] ] [ make-dir/deep Folder? Wiki_Folder/:File write Wiki_Folder/:File Command/Text head clear Extension? File ] ] ] ] GUI: func [Heading [string!] File [file!] Text [string!]] [ compose/deep [ form/id/name/method/action (Title) (Title) "POST" (CGI/Script-File) [ div/id "Center_Column" [ h1 (Heading) label [ "Folder: " input/type/name/value/title "text" (join Magic "Folder") (any [Folder? File %/]) "Folder where File is stored." ] label [ "Name: " input/type/name/value/title "text" (join Magic "Name") (form Filename? File) "Name of File." ] textarea/name/rows/cols/wrap/style (join Magic "Text") 25 80 "virtual" "width:100%;" (Text) ] div/id "Commands" [ input/type/value/title "submit" "Save" "Saves your changes" ] ] ] ] ] Edit_Page: make object! [ Title: "Edit" Command?: function [Command [object!]] [File Folder Heading] [ if all [ in Command 'Edit File: Command/Edit File: to-file deplus File exists? Wiki_Folder/:File ] [ Envelope Heading: rejoin [Title ": " Filename? File] compose/deep [ (Folder_Buttons File) (Save_Page/GUI Heading File read Wiki_Folder/:File) ] ] ] GUI: func [File [file!]] [ compose/deep [ form/id/name/method/action (Title) (Title) "GET" (CGI/Script-File) [ input/type/name/value "hidden" (join Magic Title) (File) input/type/value/title "submit" "Edit" "Click to edit this page" ] ] ] ] Hunt: function [File [file!]] [Bag Filename Extension] [ Bag: File if none? Folder? File [ Bag: none Filename: Filename? File Extension: Extension? File foreach WF Wiki/Files [ if all [ Filename = Filename? WF Extension = Extension? WF ] [ either none? Bag [ Bag: WF ][ either file? Bag [ Bag: reduce [Bag WF] ] [ append Bag WF ] ] ] ] ] Bag ] View_Page?: function [Command [object!]] [File Folder Page Title EditText] [ if all [ in Command 'File File: Command/File #"/" != last File ] [ all [ in Command 'Folder Folder: Command/Folder File: Folder/:File ] Page: File any [ Extension? Page Page: Extension Page %.txt ] if all [ %.txt = Extension? Page either Folder? Page [ exists? Wiki_Folder/:Page ] [ File: Hunt Page if all [ file? File Folder? File ] [ clear extension? File See-Other rejoin [CGI/Script-URL #"/" File] ] Page: File ] ] [ Title: form Filename? either file? Page [Page] [first Page] Envelope Title compose/deep either file? Page [ [ (Folder_Buttons Page) div/id "Center_Column" [ ( eText/Wiki/Base read Wiki_Folder/:Page rejoin [ CGI/Script-File #"?" ] ) ] div/id "Commands" [ (Random_Page/GUI) (Search/GUI Title) (Edit_Page/GUI Page) ] ] ] [ [ (Folder_Buttons %/.) div/id "Center_Column" [ h1 (Title) p/class "Initial" [ {The document named: "} (Title) {" is in several places. Please choose one:} ] ul [ ( Links: make block! 100 foreach Wiki_File Page [ if %.txt = Extension? Wiki_File [ Wiki_File: copy/part Wiki_File Extension? Wiki_File ] append Links compose/deep [ li [ a/href ( rejoin [ CGI/Script-File #"?" #"/" Wiki_File ] ) (join #"/" Wiki_File) ] ] ] Links ) ] ] div/id "Commands" [ (Random_Page/GUI) (Search/GUI Title) ] ] ] ] ] ] New_Page?: function [Command [object!]] [File Folder Title Heading] [ if all [ in Command 'File File: Command/File #"/" != last File ] [ all [ in Command 'Folder Folder: Command/Folder File: Folder/:File ] if not exists? Wiki_Folder/:File [ Title: form Filename? File Envelope Heading: join "New: " Title compose/deep [ (Folder_Buttons File) ( Save_Page/GUI Heading File rejoin [ Title newline head insert/dup copy "" #"*" length? Title newline ;either date? Name [weekday Name] [""] ; Fix Me! ] ) ] ] ] ] Delete_Folder: make object! [ Title: "Delete" Command?: function [Command [object!]] [Folder] [ if all [ in Command 'Delete Folder: Command/Delete Folder: to-file deplus Folder #"/" = last Folder exists? Wiki_Folder/:Folder empty? read Wiki_Folder/:Folder ] [ delete Wiki_Folder/:Folder See-Other rejoin [CGI/Script-URL any [Folder? Folder ""]] ] ] GUI: func [Folder [file!]] [ compose/deep [ form/id/name/method/action (Title) (Title) "GET" (CGI/Script-File) [

 [11/42] from: brett:codeconscious at: 8-Aug-2002 13:21


Hi Andrew, As far as I'm aware, READ-IO is meant to be used inside some sort of loop, ie. it is used multiple times until it exhausts the input. So as it stands, if I haven't misunderstood your code, your input-cgi function is creating an arbitrary maximum input capacity. Also IIRC, READ-IO an attracted an RT warning in the past that it should be avoided where possible because it is low level. In this case I'm pretty sure it can't be avoided - but hopefully some will up date my knowledge if I'm incorrect on this. :^) Regards, Brett.

 [12/42] from: al:bri:xtra at: 8-Aug-2002 16:42


Hi, Brett. You wrote:
> As far as I'm aware, READ-IO is meant to be used inside some sort of loop,
ie. it is used multiple times until it exhausts the input. I understood that to be the case as well. Unfortunately, I couldn't get that to work.
> So as it stands, if I haven't misunderstood your code, your input-cgi
function is creating an arbitrary maximum input capacity. For the example code, yes. In my Rebol/Wiki, where it works well, I use: Query: make string! 2 + Length: to-integer Rebol/options/cgi/content-length read-io Rebol/ports/input Query Length and so I know the length needed.
> Also IIRC, READ-IO an attracted an RT warning in the past that it should
be avoided where possible because it is low level. In this case I'm pretty sure it can't be avoided - but hopefully some will up date my knowledge if I'm incorrect on this. :^) Let's hope there's something better soon. It's not very nice script at the moment. Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [13/42] from: al:bri:xtra at: 8-Aug-2002 16:40


> Javier, you might be interested in looking at my Rebol/Wiki. It's a CGI
script, that reads POST-ed form data, as well as GET urls. It's attached. And if you want a better formatted copy, just email me for the latest version. Andrew Martin detabbed Rebolutionary... ICQ: 26227169 http://valley.150m.com/

 [14/42] from: javierd:paralax:mx at: 8-Aug-2002 1:12


At 07:47 a.m. 08/08/2002 +1200, you wrote:
>Javier, you might be interested in looking at my Rebol/Wiki. It's a CGI >script, that reads POST-ed form data, as well as GET urls. It's attached.
hey. thanks I will study it. probably i will get back sonn with a lot of questions... Javier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [15/42] from: brett:codeconscious at: 8-Aug-2002 17:39


Javier, http://www.rebol.org/cgi/index.htmlhas a POST.r which says it handles multipart/form-data. I haven't used it and I don't know if it works with current releases of REBOL, but it could be worth a look. Regards, Brett.

 [16/42] from: javierd:paralax:mx at: 8-Aug-2002 2:46


At 04:40 p.m. 08/08/2002 +1200, you wrote:
>And if you want a better formatted copy, just email me for the latest >version.
thanks, just, my first question... when the browser sends the data, the cgi script is executed as sonn as the data is received. or it has to wait untill all the data is received?. (i would like to implement son kind of progress meter... is it posible?. i don,t want my user to click several times the click button qhen sending a large file.... Javier Delgado Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [17/42] from: brett:codeconscious at: 8-Aug-2002 17:43


Hi Andrew,
> For the example code, yes. In my Rebol/Wiki, where it works well, I use: > > Query: make string! 2 + Length: to-integer > Rebol/options/cgi/content-length > read-io Rebol/ports/input Query Length > > and so I know the length needed.
Again, I seem to recall that there was a problem with relying on content-length, but if it is working for you then hey who am I to disagree! :^) Here is an excerpt from a script of mine that process standard input for the NoteTab editor. So it is not CGI, but very related. The relevent bit is the while loop condition that checks for the result of READ-IO which I think is the number of bytes read. I've no idea how this would react in a CGI environment, maybe if you have a webserver on your personal machine you could try it? You could probaby ignore my character manipulations (they are probably only relevent to my editor usage). standard-input: function [ "Returns a string that comes from standard input." ; May not be suitable for large input streams. ] [buf-size inp inp-buffer log] [ buf-size: 30000 inp-buffer: make string! buf-size inp: make string! buf-size while [ clear inp-buffer 0 < read-io system/ports/input inp-buffer buf-size ] [ replace/all inp-buffer "^M" "" ; Handles CR on windows systems. append inp inp-buffer ] inp if all [ 0 < length? inp equal? last inp to-char 26 ] [ remove/part at inp length? inp 1 ] inp ] Regards, Brett.

 [18/42] from: javierd:paralax:mx at: 8-Aug-2002 3:54


At 05:39 p.m. 08/08/2002 +1000, you wrote:
>Javier, > >http://www.rebol.org/cgi/index.htmlhas a POST.r which says it handles >multipart/form-data. I haven't used it and I don't know if it works with >current releases of REBOL, but it could be worth a look.
This is the script i took as a model. I has a couple of bugs, but the main problem is that it corrupts binary files.... for i have been reading here, i need a very diferent aproach to send files. :-/ JAvier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [19/42] from: petr:krenzelok:trz:cz at: 8-Aug-2002 11:40


Javier Delgado wrote:
> At 04:40 p.m. 08/08/2002 +1200, you wrote: > >> And if you want a better formatted copy, just email me for the latest >> version. > > thanks, just, my first question... > > when the browser sends the data, the cgi script is executed as sonn as > the data is received. or it has to wait untill all the data is received?.
Hallo all :-) ask fast, before I forget the answer once again :-) Well, you have to implement loop reading your data on server, if you use POST method ....
> (i would like to implement son kind of progress meter... is it posible?.
Why not to build client View app for such purpose?

 [20/42] from: petr:krenzelok:trz:cz at: 8-Aug-2002 12:02


Brett Handley wrote:
>Hi Andrew, >>For the example code, yes. In my Rebol/Wiki, where it works well, I use:
<<quoted lines omitted: 26>>
> clear inp-buffer > 0 < read-io system/ports/input inp-buffer buf-size
I am interested in this condition here. We try to do some intensive Ethernet + tcp testing here with our device. Is that condition correct? What if your input is not fast enought to feed you with data? It does not necessarily mean, that you received all data, does it? What about following? input-port: open/direct/no-wait system/ports/input while [wait input-port data: copy input port][append inp data] I think it meets follwoing conditions conditions: - is async the same way read-io is, or so I think ... - 'wait should wait for input, so you will not receive empty string, if no data available - 'none is gonna be returned, if port is closed, while on the other hand we have problem with: - how to properly leave the loop? Maybe using something like: end-seq: "some-spec-chars or newline" while [ wait input-port data: copy port all [ data not found? find head inp end-seq] ][ append inp data] just in case you would want to try alternative aproach using 'copy .... I just hope I am not all that wrong :-) Cheers, -pekr-

 [21/42] from: al:bri:xtra at: 8-Aug-2002 21:58


Javier wrote:
> when the browser sends the data, the cgi script is executed as sonn as the
data is received. or it has to wait untill all the data is received?. In my CGI Rebol/Wiki script, all the POST-ed form data is ready and waiting the instant the script needs it. That's because the value in Rebol/options/cgi/content-length is just a plain integer! There's nothing tricky going on behind the scenery.
> (i would like to implement son kind of progress meter... is it posible?. i
don't want my user to click several times the click button when sending a large file... When sending a large file, in my experience, the Rebol CGI script isn't started until all the file information is sent by the browser and received by the web server. I hope that helps! Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [22/42] from: g:santilli:tiscalinet:it at: 8-Aug-2002 12:13


Hi Andrew, On Thursday, August 8, 2002, 6:42:53 AM, you wrote: AM> and so I know the length needed. AFAIK READ-IO is not guaranteed to return the asked length; it returns UP TO the asked length of data, but does not wait for it to arrive if it is not there. (Anyone correct me if I don't recall correctly; I no more used READ-IO after the NO-WAIT mode has been introduced.) AM> Let's hope there's something better soon. It's not very nice script at the AM> moment. READ-IO is basically the same as COPY on a BINARY/NO-WAIT port, except for the need to allocate a properly sized buffer. So you can replace you code with something like: set-modes system/ports/input [binary: true no-wait: true] data: copy system/ports/input while [content-length > length? data] [ wait system/ports/input insert tail data copy system/ports/input ] (WARNING: not tested) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [23/42] from: al:bri:xtra at: 8-Aug-2002 22:09


Brett wrote:
> Again, I seem to recall that there was a problem with relying on
content-length, but if it is working for you then hey who am I to disagree! :^) It did take a while for me to realise the need for two extra character spaces. I had a aweful lot of .txt files that terminated with CR (instead of CRLF), or dropped the last character (that's how I noticed it). But I've been using the wiki software for weeks now on several computers and two type of web server and all's well. After all, as I understand it, the web server first receives all the data from the browser, then invokes the CGI (so setting content-length), collects the CGI output, adds appropriate headers, then supplies the browser. Each step is discrete and doesn't overlap as far as I know. I think the method you're describing is for occasions where Rebol is reading the data directly from a network rather than buffered by a web server. For example, a Rebol Web Server (not CGI script!) that's receiving multi-part form info from browser over a slow network, perhaps containing a file. Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [24/42] from: g:santilli:tiscalinet:it at: 8-Aug-2002 12:06


Hi Brett, On Thursday, August 8, 2002, 5:21:02 AM, you wrote: BH> Also IIRC, READ-IO an attracted an RT warning in the past that it should be BH> avoided where possible because it is low level. In this case I'm pretty sure BH> it can't be avoided - but hopefully some will up date my knowledge if I'm BH> incorrect on this. :^) Indeed, it was needed when SET-MODES didn't exist. Now that it is possible to set the input port to binary mode, you can get binary data with just the use of COPY (COPY/PART actually, unless you set it to NO-WAIT too; I think it is the best thing to do in the case of possible big input, so you can get it as fast as possible). Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [25/42] from: al:bri:xtra at: 8-Aug-2002 22:30


Here's a tutorial on CGI, which could be helpful: http://www.whizkidtech.net/cgi-bin/tutorial Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [26/42] from: g:santilli:tiscalinet:it at: 8-Aug-2002 12:25


Hi Javier, On Thursday, August 8, 2002, 9:46:24 AM, you wrote: JD> when the browser sends the data, the cgi script is executed as sonn as the JD> data is received. or it has to wait untill all the data is received?. It may depend on the server, but the script should be executed as soon as the server has discovered it is a CGI (so, as soon as it has received the full HTTP header and decoded it; for small POSTs, at this time it has probably received all the data too, but in your case it's likely that when the script is called not all the data has arrived, and you'll have to wait for it). JD> (i would like to implement son kind of progress meter... is it posible?. Not that it is easy to do in HTML. :-) But you can at least send a Please wait message as soon as the script executes. (Dunno if the browser will wait until it has sent all the data tough before displaying the result; you'll have to check with your target browsers.) (Maybe you can use the so-called server-push technique to do a progress meter; I'm not an expert of this, but IIRC it's just a matter of sending the correct content type --- multipart/something, I don't recall at the moment --- and then sending one page after the other following the MIME format.) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [27/42] from: brett:codeconscious at: 8-Aug-2002 20:59


I'm glad I ventured in - I'm learning (getting rid of old ideas). Javier, I've now tried out POST.r and it has a number of problems. I know that there is another file upload script floating around, but I can put my hands on it right now. Doesn't matter though the strucuture of the data should be straightforward (follows MIME spec.). Thanks Gabriele, Petr for the networking updates. My playing around required .. :^) Regards, Brett.

 [28/42] from: gchiu:compkarori at: 9-Aug-2002 0:36


I'm late into this thread, and outta touch being off list for a while... But I did write a multipart post script a few months ago that has been used to stress a web server to see how many simultaneous binary uploads it would take. From memory, I created a custom http header that had the content-type set to multipart/form-data, specified the boundary value, assembled the payload into the appropriate mime format, inserted the headers into the http port as text, used set-modes to change to binary, inserted the payload as binary, and then switched the port back to lines: true again. Ethereal was quite useful in getting it working. -- Graham Chiu

 [29/42] from: brett:codeconscious at: 8-Aug-2002 23:09


Hi Graham,
> But I did write a multipart post script a few months ago > that has been used to stress a web server to see how many > simultaneous binary uploads it would take.
That would be a handy script to test the responsiveness of the CGI script under various conditions like fast/slow/timeout connections. :^) Regards, Brett.

 [30/42] from: brett:codeconscious at: 8-Aug-2002 23:15


I wrote,
> My playing around required .. :^)
Well I've done my playing and got some promising results - YMMV. What I did is below the cut-line. It would need far more coding to get a production quality script. Regards, Brett. ---------------------8<-------------------------------- #!e:/program files/rebol/core/rebol -cs REBOL [ Title: "A sample HTML form decode script" Comment: { This script is an example only. There is no error handling, it is not properly tested and is missing lots of logic. In other words, do not use for production. Use it only on a local test server. And don't blame me :) } Author: {Brett Handley} Date: 8-Aug-2002 ] ;****************************************************** ; A MIME function I dug out of another script. ;****************************************************** ; This could possibly be a simpler parse expression - but since ; I already had it lying around here it is. mime-body-parts?: function [[catch] "The separate parts of multipart mime content." content [string! binary!] boundary [string!] line-terminator [string!] "The line terminator - either CRLF or newline." ] [ normal-delimiter close-delimiter prologue epilogue msg-part parse-result message-part-pattern return-block ] [ ; Get the parts return-block: make block! 2 normal-delimiter: rejoin [line-terminator "--" boundary] close-delimiter: rejoin [line-terminator "--" boundary "--"] message-part-pattern: [ line-terminator copy msg-part [to normal-delimiter | to close-delimiter] (append return-block msg-part) ] parse-result: parse/all content [ (epilogue: prologue: none) [ "--" boundary message-part-pattern | copy prologue to normal-delimiter ] some [ close-delimiter copy epilogue to end | normal-delimiter message-part-pattern ] end ] if not parse-result [throw make error! "Error: Assumption failed while parsing parts."] RETURN return-block ] ;****************************************************** ; Begin the HTML response ;****************************************************** print "Pragma: no-cache" print "Content-type: text/html^m^j" print {<META HTTP-EQUIV="Pragma" CONTENT="no-cache">} print {<META HTTP-EQUIV="Expires" CONTENT="0">} print "<HTML><BODY><PRE>" print join "<h3>TEST at " [now "</h3>"] print mold what-dir ;****************************************************** ; Determine content-type ;****************************************************** tmp: parse/all system/options/cgi/content-type ";" content-type: first tmp ;****************************************************** ; Get boundary ;****************************************************** repeat param next tmp [ if find param {boundary=} [ boundary: second parse/all trim/head/tail param "=" break ] ] ;****************************************************** ;Get Content - Using Gabriele's example ;****************************************************** content-length: to-integer system/options/cgi/content-length set-modes system/ports/input [binary: true no-wait: true] content: copy system/ports/input while [content-length > length? content] [ print "Wait for content..." wait system/ports/input insert tail content copy system/ports/input ] ;****************************************************** ; Seperate the parts of the multipart form and ; output a rebol representation of them. ; PARSE-HEADER is already built in to REBOL - whole ; content string ends up in CONTENT field of object. ; Converts content to binary unless it is text. Text is ; typically sent across networks using CRLF lineending, ; so here I replace it with REBOL's newline convention. ; Note that REPLACE might be slow. ;****************************************************** parts: mime-body-parts? content boundary CRLF repeat part parts [ result: copy [] msg: parse-header none part either all [ in msg 'content-type not find/match msg/content-type {text} found? content ] [msg/content: to-binary msg/content] [ msg/content: replace/all CRLF newline ] probe msg ] ;****************************************************** ; Finish off the output ;****************************************************** print "</PRE></BODY></HTML>" QUIT

 [31/42] from: g:santilli:tiscalinet:it at: 8-Aug-2002 12:34


Hi Andrew, On Thursday, August 8, 2002, 11:58:16 AM, you wrote: AM> When sending a large file, in my experience, the Rebol CGI script isn't AM> started until all the file information is sent by the browser and received AM> by the web server. This actually depends on the web server, I think. It is very reasonable to pass the control to the script as soon as possible, for the web server not to have to buffer and handle potentially very big data. Of course, if Javier is sure that his server is behaving as you describe, he can avoid using a loop; but since it is nothing this complicated, I think that being safe (and portable to other servers...) is not a bad idea. :-) Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [32/42] from: javierd:paralax:mx at: 8-Aug-2002 10:26


Gabriele.At 12:25 p.m. 08/08/2002 +0200, you wrote:
>data has arrived, and you'll have to wait for it). > >JD> (i would like to implement son kind of progress meter... is it posible?. > >Not that it is easy to do in HTML. :-) But you can at least send a >"Please wait" message as soon as the script executes.
I think that will be enough... at leat that will prevent that the user would send 10 copies of the same file... :-) Javier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [33/42] from: javierd:paralax:mx at: 8-Aug-2002 10:22


Gabriele. At 12:06 p.m. 08/08/2002 +0200, you wrote:
>Indeed, it was needed when SET-MODES didn't exist. Now that it is >possible to set the input port to binary mode, you can get binary >data with just the use of COPY (COPY/PART actually, unless you set >it to NO-WAIT too; I think it is the best thing to do in the case >of possible big input, so you can get it as fast as possible).
That is exactly what i am trying to do, i expected files up to 2 mb... i will try this, thanks Javier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [34/42] from: javierd:paralax:mx at: 8-Aug-2002 10:17


At 11:40 a.m. 08/08/2002 +0200, you wrote:
>ask fast, before I forget the answer once again :-) Well, you have to >implement loop reading your data on server, if you use POST method ....
Thanks for the sugestion i will do it. :-)
>>(i would like to implement son kind of progress meter... is it posible?. > >Why not to build client View app for such purpose?
I know that would be better, but i don,t want that the user had to donwload o install anything... part of the browser... but i am giving it a serirous thougth.... JAvier Delgado Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [35/42] from: javierd:paralax:mx at: 8-Aug-2002 10:19


Andrew Martin At 09:58 p.m. 08/08/2002 +1200, you wrote:
>When sending a large file, in my experience, the Rebol CGI script isn't >started until all the file information is sent by the browser and received >by the web server.
thanks a lot... finally i understand what i am doing :-) Javier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [36/42] from: javierd:paralax:mx at: 8-Aug-2002 10:32


Brett. At 08:59 p.m. 08/08/2002 +1000, you wrote:
>I'm glad I ventured in - I'm learning (getting rid of old ideas). > >Javier, I've now tried out POST.r and it has a number of problems. I know >that there is another file upload script floating around, but I can put my >hands on it right now. Doesn't matter though the strucuture of the data >should be straightforward (follows MIME spec.).
the other script i found is more an example of how to receive the data: input-cgi: func [/stdin] [ stdin: make string! 15000 either system/options/cgi/request-method = "POST" [ read-io system/ports/input stdin 15000 return stdin ][ system/options/cgi/query-string ] ] so far thas are the only two examples. There is another to simulate a a browser sending post data to a server... JAvier Paralax Multimedia www.paralax.com.mx Interactivos, kioscos, sites, web hosting, video 3d, animacion 3d, anaglifos tel 5373 3620 y 5363 4953 Naucalpan de Juarez, Edo. Mex. tambien visite: http://www.kaliman.com.mx http://www.paralax.com.mx/javier

 [37/42] from: g:santilli:tiscalinet:it at: 8-Aug-2002 15:48


Hi Andrew, On Thursday, August 8, 2002, 12:09:12 PM, you wrote: AM> first receives all the data from the browser, then invokes the CGI (so AM> setting content-length), collects the CGI output, adds appropriate headers, The Content-Length field is (and must be) supplied by the browser. AM> I think the method you're describing is for occasions where Rebol is reading AM> the data directly from a network rather than buffered by a web server. For What can I say, if I were writing a web server I'd pass the control to the CGI script as soon as possible. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [38/42] from: brett:codeconscious at: 9-Aug-2002 9:24


Resending a post (see below) as it looks to have gone lost in the ether. Brett.

 [39/42] from: brett:codeconscious at: 8-Aug-2002 23:17


Argh! I hate those last minute little changes that I think I've tested and in fact haven't. Please change the following line msg/content: replace/all CRLF newline to msg/content: replace/all msg/content CRLF newline Brett.

 [40/42] from: atruter:hih:au at: 12-Aug-2002 12:53


> msg/content: replace/all msg/content CRLF newline
Have I missed something here? Isn't: msg/content: replace/all msg/content CRLF newline the same as: replace/all msg/content CRLF newline On a side note, I find the first form useful to create copies of file names but with a different extension, as in: dat-file: replace copy jpg-file %.jpg %.dat Regards, Ashley

 [41/42] from: brett:codeconscious at: 12-Aug-2002 13:44


I don't think you've missed anything. My only defense is that it must have been late. :^) Regards, Brett.

 [42/42] from: anton:lexicon at: 12-Aug-2002 17:32


That could be just fine but fails for certain filenames, like this: %afile.jpg.htm Sometimes you see urls with an embedded url in them, too, so you could have two filename extensions in those. Anton.

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted