Monday, November 08, 2010 at 12:04 AM.
system.verbs.builtins.mainResponder.parseMultipart
on parseMultipart (adrparamtable) { <<Change Notes <<1/17/99; 1:39:20 PM by DW <<Thanks to Kurt Egger for prodding me to do this code, and to Jeff Willden for a great example to work with. I rewrote the code to make better use of Frontier, to perform better and have a flatter interface for the application. <<Our goal is to fill the postArgs table with info from the request <<12/02/1999; 5:18:51 PM by AR <<Disabled debugging code: No longer write to scratchpad.headers. <<08/28/01; 12:31:27 AM by JES <<Added support for <select multiple> form elements, per feedback from Seth Dillingham. local (boundaryString); bundle { //get the boundary string that separates each form element local (s = adrparamtable^.requestHeaders.["Content-Type"]); <<multipart/form-data; boundary=---------------------------7cf1873b3e070a boundaryString = string.popLeading (string.nthField (s, '=', 2), '-')}; local (body); bundle { //initialize body, pop off leading dashes followed by boundary string body = string (adrparamtable^.requestBody); body = string.popLeading (body, '-'); body = string.delete (body, 1, sizeof (boundaryString))}; local (adrtable = @adrparamtable^.postArgs); new (tabletype, adrtable); //fill this table with info from the request loop { //get each form element, delimited by the boundary string local (ix = string.patternMatch (boundaryString, body)); if ix == 0 { //no more encoded elements break}; local (s = string.popTrailing (string.mid (body, 1, ix - 1), '-')); bundle { //digest the element local (headers, elementBody, contentDisposition, argName); if not (s beginswith "\r\n") { s = "\r\n" + s}; elementBody = string.httpResultSplit (s, @headers); if elementBody endswith "\r\n" { elementBody = string.delete (elementBody, sizeof (elementBody) - 1, 2)}; headers.data = elementBody; contentDisposition = headers.["Content-Disposition"]; delete (@headers.["Content-Disposition"]); <<name="file"; filename="D:\frontierStartupCommands.txt" loop { s = string.nthField (contentDisposition, ';', 1); if s == "" { break}; contentDisposition = string.delete (contentDisposition, 1, sizeof (s) + 1); if s contains '=' { local (name = string.trimWhitespace (string.urlDecode (string.nthField (s, '=', 1)))); local (value = string.trimWhitespace (string.urlDecode (string.nthField (s, '=', 2)))); value = string.mid (value, 2, sizeof (value) - 2); //pop off enclosing double-quotes if string.lower (name) == "name" { argName = value} else { <<bundle //08/28/01 JES: original code <<headers.[name] = value if defined (headers.[name]) { //08/28/01 JES: support <select multiple> form elements if typeOf (headers.[name]) != listType { headers.[name] = {headers.[name]}}; headers.[name] = headers.[name] + {value}} else { headers.[name] = value}}}}; <<scratchpad.headers = headers if sizeof (headers) == 1 { if defined (adrtable^.[argName]) { //08/28/01 JES: support <select multiple> form elements if typeOf (adrtable^.[argName]) != listType { adrtable^.[argName] = {adrtable^.[argName]}}; adrtable^.[argName] = adrtable^.[argName] + {elementBody}} else { adrtable^.[argName] = elementBody}} else { adrtable^.[argName] = headers}}; body = string.delete (body, 1, ix + sizeof (boundaryString)); body = string.popLeading (body, '\n')}}; bundle { //test code parseMultipart (@scratchpad.offparams)}
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.