Monday, November 08, 2010 at 12:05 AM.
system.verbs.builtins.radio.webServer.parseMultipart
on parseMultipart (pta) {
<<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.
local (boundaryString);
bundle { //get the boundary string that separates each form element
local (s = pta^.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 (pta^.requestBody);
body = string.popLeading (body, '-');
body = string.delete (body, 1, sizeof (boundaryString))};
local (adrtable = @pta^.radioResponder.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 {
headers.[name] = value}}};
<<scratchpad.headers = headers
if sizeof (headers) == 1 {
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.multipartparamtable)
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.