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

[REBOL] [Fwd: POST CGI testing]

From: joel::neely::fedex::com at: 20-Nov-2000 11:04

Hi, all... I've spent WAAAAYYYY too much time on this. However, I hope that by documenting my experiences (and frustrations!) I can benefit the next REBOLite that has to walk this path. I ran a series of tests using the HTML form previously posted, and the cgi script given at the end of this note. During the tests, I added a couple of variations, and the code to display the REBOL version number, but those don't appear in my sample output until later on. If you want to cut to the solution, look at test case #15 and the code that appears at the end of this message. When I get a chance, I'll provide a condensed version of the feedback issues that resulted from this exploration (cases 2, 3, 7, 9, etc..) The first eight test cases submit the form with its default data content (short data, that fits within the apparent buffer limitation). Test case #1: ==================== test: input request-method: POST content-length: 53 content: area=Hello&field=Goodbye&submit=Submit&secret=whisper length?: 53 ==================== Remarks: Correct output. Test case #2: ==================== test: system/ports/input request-method: POST content-length: 53 content: area=Hello&field=Goodbye&submit=Submit&secret=whisper length?: 1 ==================== Remarks: Correct content, but notice strange length? value. (???) Test case #3: ==================== test: console port request-method: POST content-length: 53 ==================== Remarks: Browser reports "Document: Done." and cgi process terminates, but notice that the last part of the output is missing. Perhaps the cgi process went sideways? Test case #4: ==================== test: read-io request-method: POST content-length: 53 content: area=Hello&field=Goodbye&submit=Submit&secret=whisper length?: 53 ==================== Remarks: Correct output. Test case #5: ==================== test: read-io loop request-method: POST content-length: 53 ==================== Remarks: Browser stalls, and cgi process never terminates. The relevant portion of top output shows the following interesting state of affairs: 5298 httpd 14 0 5900 5900 596 R 0 91.3 9.3 1:29 testcgi.r.cg 3504 httpd 0 0 416 0 0 SW 0 0.0 0.0 0:00 httpd 3505 httpd 0 0 872 740 640 S 0 0.0 1.1 0:00 httpd 3506 httpd 0 0 416 0 0 SW 0 0.0 0.0 0:00 httpd 3507 httpd 0 0 372 0 0 SW 0 0.0 0.0 0:00 httpd 3508 httpd 0 0 372 0 0 SW 0 0.0 0.0 0:00 httpd 3509 httpd 0 0 872 740 640 S 0 0.0 1.1 0:00 httpd 3510 httpd 0 0 420 0 0 SW 0 0.0 0.0 0:00 httpd 3511 httpd 0 0 372 0 0 SW 0 0.0 0.0 0:00 httpd 3512 httpd 0 0 372 0 0 SW 0 0.0 0.0 0:00 httpd 3513 httpd 0 0 372 0 0 SW 0 0.0 0.0 0:00 httpd 3812 httpd 0 0 424 0 0 SW 0 0.0 0.0 0:00 httpd 5299 httpd 0 0 376 376 328 S 0 0.0 0.5 0:00 testcgi.r.cg Note that there are TWO testcgi.r.cgi processes (the names were truncated by the width of the terminal window) -- one of which is a busy beaver and the other of which is doing nothing. Pressing the "Stop" button on the browser takes it out of "65 bytes read (stalled)" state, but leaves the cgi processes running. If I kill the lower-numbered process (SIG 15) they both die. Test case #6: ==================== test: read-io loop 2 request-method: POST content-length: 53 content: area=Hello&field=Goodbye&submit=Submit&secret=whisper length?: 53 ==================== Remarks: Correct output. Test case #7: ==================== test: input? loop request-method: POST content-length: 53 ==================== Remarks: Premature termination again. Browser reports "Document: Done." and cgi process terminates, but last part of output is simply missing. Test case #8: ==================== test: noise not matched request-method: POST content-length: 53 content: input=default length?: 13 ==================== Remarks: For the sake of completeness, here's what happens if the test selector fails to match any of the actual input choices...j The second set of test cases submit the form with long data content, created by pasting a large number of copies of the same line into the textarea: Test case #9: ==================== test: input request-method: POST content-length: 4608 content: area=123456789012345678901...012345678901 length?: 4094 ==================== Remarks: The received data are truncated (the ellipsis in the the string from the textarea was inserted by me for this email -- you don't want to see 4K of digits ;-). Notice that the length of the content is the curious number 4094 and that the content stops in the textarea value (the other fields are completely missing, as they follow the textarea). Also note that there was a line break every 70 characters in the textarea data -- cgi encoded as "%0D%0A" -- but my little snippet above isn't long enough to contain one of those occurrences. Test case #10: ==================== test: system/ports/input request-method: POST content-length: 4608 content: area=12345678901...0123456789012345678901 length?: 1 ==================== Remarks: Despite the peculiar reported length of the content string, that string is actually truncated to the same length as the previous case. Notice that the data end with the same fragmentary value for the textarea and the other input fields are missing. Test case #11: ==================== test: console port request-method: POST content-length: 4608 ==================== Remarks: As before (with short data) the browser reports "Document: Done." and the cgi process goes away. However, the remaining output is missing. Test case #12: ==================== test: read-io request-method: POST content-length: 4608 content: area=123456789012345678901...01234567890123 length?: 4096 ==================== Remarks: Once again, the input data string is truncated, but to a slightly longer size than before (a round number ?!?!?!). Test case #13: ==================== test: read-io loop request-method: POST content-length: 4608 ==================== Remarks: As in the first set of test cases, the browser stalls and the cgi process pair hangs around until killed. This time, just for variety, I killed the cgi processes first, after which the browser displayed "Document: Done." Test case #14: ==================== REBOL version: 2.3.0.4.2 test: read-io loop 2 request-method: POST content-length: 4608 content: rea=12345...90%0D%0A&field=Goodbye&submit=Submit&secret=whisper length?: 8704 ==================== Remarks: AHA!!! Two useful lessons: 1) The read-io loop appears to work! 2) Read-io apparently appends to its argument instead of overwriting it. Notice that 8704 = 4096 + 4608. With those lessons in mind, let's try a variation on this theme. Test case #15: ==================== REBOL version: 2.3.0.4.2 test: read-io loop 2a request-method: POST content-length: 4608 content: area=123456789...01234567890%0D%0A&field=Goodbye&submit=Submit&secret=whisper length?: 4608 ==================== Remarks: SUCCESS AT LAST! Additional warnings: The R/CUG 2.3 sent me down a couple of blind alleys, as documented in the test cases below. I'm including these for completeness and as a public feedback item on the manual. Test cases #16a and #16b: ==================== REBOL version: 2.3.0.4.2 test: console port 2 request-method: POST content-length: 4608 ** Script Error: open has no refinement called nowait. ** Where: port: open/binary/nowait console:// while [found? wait [port 1]] ==================== REBOL version: 2.3.0.4.2 test: console port 2 request-method: POST content-length: 4608 ** Script Error: open has no refinement called no-wait. ** Where: port: open/binary/no-wait console:// while [found? wait [port 1]] ==================== Remarks: Gabriele suggested I open a console, possibly with the /no-wait refinement. R/CUG 2.3 page 13-4 listed /nowait as a refinement to the open function, but (as you can see above) that doesn't seem to be valid, either with or without the hyphen. Test case: ==================== REBOL version: 2.3.0.4.2 test: foreach system/ports/input request-method: POST content-length: 4608 content: area=12345678901...012345678901 length?: 4095 ==================== Remarks: R/CUG 2.3 page 12-56 contains an example script entitled "Show POST data" which loops over system/ports/input using a data buffer with a 10000 byte capacity. "Self," I said to myself, "that must be the clue you've been missing!" So Self tried it, and got the disappointing result above. Still truncated! TEST SCRIPT FOLLOWS: All of the various attempts to obtain input are contained within the function named read-post-input and selected by the test variable which controls the switch in that function. ================================================================================ #!/usr/local/bin/rebol -cs REBOL [] print [ {Content-type: text/plain^/^/REBOL version: } system/version ] clen: to-integer system/options/cgi/content-length reqm: system/options/cgi/request-method test: "foreach system/ports/input" print [ {^/test: } test {^/request-method: } reqm {^/content-length: } clen ] read-post-input: func [/local ct cs port] [ ct: make string! clen cs: make string! clen switch/default test [ "input" [ cs: input ] "system/ports/input" [ cs: copy system/ports/input ] "console port" [ port: open/binary console:// while [found? wait [port 1]] [ insert tail cs copy port ] close port ] "read-io" [ read-io system/ports/input cs clen ] "read-io loop" [ read-io system/ports/input ct clen while [0 < length? ct] [ append cs ct read-io system/ports/input ct clen ] ] "read-io loop 2" [ read-io system/ports/input ct clen while [clen > length? cs] [ append cs ct read-io system/ports/input ct clen ] ] "input? loop" [ while [input?] [ ct: input append cs ct ] ] "read-io loop 2a" [ until [ read-io system/ports/input cs clen clen = length? cs ] ] "console port 2" [ port: open/binary/no-wait console:// while [found? wait [port 1]] [ insert tail cs copy port ] close port ] "foreach system/ports/input" [ foreach ct copy system/ports/input [ repend cs [ct newline] ] ] ][ cs: "input=default" ] return cs ] cont: any [ if reqm = "get" [ system/options/cgi/query-string ] if reqm = "post" [ read-post-input ] input ] print [ newline {^/content: } cont {^/length?: } length? head cont newline ] ================================================================================ -jn-