| rev | 
   line source | 
| 
jbe/bsw@0
 | 
     1 #!/usr/bin/env lua
 | 
| 
jbe/bsw@0
 | 
     2 
 | 
| 
jbe/bsw@2
 | 
     3 local assert         = assert
 | 
| 
jbe/bsw@2
 | 
     4 local collectgarbage = collectgarbage
 | 
| 
jbe/bsw@2
 | 
     5 local error          = error
 | 
| 
jbe/bsw@2
 | 
     6 local getfenv        = getfenv
 | 
| 
jbe/bsw@2
 | 
     7 local getmetatable   = getmetatable
 | 
| 
jbe/bsw@2
 | 
     8 local ipairs         = ipairs
 | 
| 
jbe/bsw@2
 | 
     9 local next           = next
 | 
| 
jbe/bsw@2
 | 
    10 local pairs          = pairs
 | 
| 
jbe/bsw@2
 | 
    11 local pcall          = pcall
 | 
| 
jbe/bsw@2
 | 
    12 local print          = print
 | 
| 
jbe/bsw@2
 | 
    13 local rawequal       = rawequal
 | 
| 
jbe/bsw@2
 | 
    14 local rawget         = rawget
 | 
| 
jbe/bsw@2
 | 
    15 local rawset         = rawset
 | 
| 
jbe/bsw@2
 | 
    16 local select         = select
 | 
| 
jbe/bsw@2
 | 
    17 local setfenv        = setfenv
 | 
| 
jbe/bsw@2
 | 
    18 local setmetatable   = setmetatable
 | 
| 
jbe/bsw@2
 | 
    19 local tonumber       = tonumber
 | 
| 
jbe/bsw@2
 | 
    20 local tostring       = tostring
 | 
| 
jbe/bsw@2
 | 
    21 local type           = type
 | 
| 
jbe/bsw@2
 | 
    22 local unpack         = unpack
 | 
| 
jbe/bsw@2
 | 
    23 local xpcall         = xpcall
 | 
| 
jbe/bsw@0
 | 
    24 
 | 
| 
jbe/bsw@0
 | 
    25 local io     = io
 | 
| 
jbe/bsw@0
 | 
    26 local math   = math
 | 
| 
jbe/bsw@0
 | 
    27 local os     = os
 | 
| 
jbe/bsw@0
 | 
    28 local string = string
 | 
| 
jbe/bsw@0
 | 
    29 local table  = table
 | 
| 
jbe/bsw@0
 | 
    30 
 | 
| 
jbe/bsw@0
 | 
    31 module(...)
 | 
| 
jbe/bsw@0
 | 
    32 
 | 
| 
jbe/bsw@0
 | 
    33 data_sent = false
 | 
| 
jbe/bsw@0
 | 
    34 
 | 
| 
jbe/bsw@16
 | 
    35 --[[--
 | 
| 
jbe/bsw@16
 | 
    36 rocketcgi.add_header(
 | 
| 
jbe/bsw@16
 | 
    37   string_part1,        -- string
 | 
| 
jbe/bsw@16
 | 
    38   string_part2,        -- optional second part of string to be concatted
 | 
| 
jbe/bsw@16
 | 
    39   ...
 | 
| 
jbe/bsw@16
 | 
    40 )
 | 
| 
jbe/bsw@16
 | 
    41 
 | 
| 
jbe/bsw@16
 | 
    42 Sends a header line to the browser. Multiple arguments are concatted to form a single string.
 | 
| 
jbe/bsw@16
 | 
    43 
 | 
| 
jbe/bsw@16
 | 
    44 --]]--
 | 
| 
jbe/bsw@0
 | 
    45 function add_header(...)
 | 
| 
jbe/bsw@0
 | 
    46   if data_sent then
 | 
| 
jbe/bsw@0
 | 
    47     error("Can not add header after data has been sent.", 2)
 | 
| 
jbe/bsw@0
 | 
    48   end
 | 
| 
jbe/bsw@0
 | 
    49   io.stdout:write(...)
 | 
| 
jbe/bsw@0
 | 
    50   io.stdout:write("\r\n")
 | 
| 
jbe/bsw@0
 | 
    51 end
 | 
| 
jbe/bsw@16
 | 
    52 --//--
 | 
| 
jbe/bsw@0
 | 
    53 
 | 
| 
jbe/bsw@16
 | 
    54 --[[--
 | 
| 
jbe/bsw@16
 | 
    55 rocketcgi.send_data(
 | 
| 
jbe/bsw@16
 | 
    56   string_part1,       -- string
 | 
| 
jbe/bsw@16
 | 
    57   string_part2,       -- optional second part of string to be concatted
 | 
| 
jbe/bsw@16
 | 
    58   ...
 | 
| 
jbe/bsw@16
 | 
    59 )
 | 
| 
jbe/bsw@16
 | 
    60 
 | 
| 
jbe/bsw@16
 | 
    61 Sends document data to the browser. Multiple arguments are concatted to form a single string.
 | 
| 
jbe/bsw@16
 | 
    62 
 | 
| 
jbe/bsw@16
 | 
    63 --]]--
 | 
| 
jbe/bsw@0
 | 
    64 function send_data(...)
 | 
| 
jbe/bsw@0
 | 
    65   if not data_sent then
 | 
| 
jbe/bsw@0
 | 
    66     io.stdout:write("\r\n")
 | 
| 
jbe/bsw@0
 | 
    67     data_sent = true
 | 
| 
jbe/bsw@0
 | 
    68   end
 | 
| 
jbe/bsw@0
 | 
    69   io.stdout:write(...)
 | 
| 
jbe/bsw@0
 | 
    70 end
 | 
| 
jbe/bsw@16
 | 
    71 --//--
 | 
| 
jbe/bsw@0
 | 
    72 
 | 
| 
jbe/bsw@16
 | 
    73 --[[--
 | 
| 
jbe/bsw@16
 | 
    74 rocketcgi.set_status(
 | 
| 
jbe/bsw@16
 | 
    75   status               -- Status code and description, e.g. "404 Not Found"
 | 
| 
jbe/bsw@16
 | 
    76 )
 | 
| 
jbe/bsw@16
 | 
    77 
 | 
| 
jbe/bsw@16
 | 
    78 Sends a header line to the browser, indicating a given HTTP status.
 | 
| 
jbe/bsw@16
 | 
    79 
 | 
| 
jbe/bsw@16
 | 
    80 --]]--
 | 
| 
jbe/bsw@0
 | 
    81 function set_status(status)
 | 
| 
jbe/bsw@0
 | 
    82   add_header("Status: ", status)
 | 
| 
jbe/bsw@0
 | 
    83 end
 | 
| 
jbe/bsw@16
 | 
    84 --//--
 | 
| 
jbe/bsw@0
 | 
    85 
 | 
| 
jbe/bsw@16
 | 
    86 --[[--
 | 
| 
jbe/bsw@16
 | 
    87 rocketcgi.redirect(
 | 
| 
jbe/bsw@16
 | 
    88   status             -- Absolute URL to redirect the browser to
 | 
| 
jbe/bsw@16
 | 
    89 )
 | 
| 
jbe/bsw@16
 | 
    90 
 | 
| 
jbe/bsw@16
 | 
    91 Redirects the browser to the given absolute URL, using a 303 Redirect.
 | 
| 
jbe/bsw@16
 | 
    92 
 | 
| 
jbe/bsw@16
 | 
    93 --]]--
 | 
| 
jbe/bsw@0
 | 
    94 function redirect(location)
 | 
| 
jbe/bsw@0
 | 
    95   set_status("303 See Other")
 | 
| 
jbe/bsw@0
 | 
    96   add_header("Location: ", location)
 | 
| 
jbe/bsw@0
 | 
    97 end
 | 
| 
jbe/bsw@16
 | 
    98 --//--
 | 
| 
jbe/bsw@0
 | 
    99 
 | 
| 
jbe/bsw@16
 | 
   100 --[[--
 | 
| 
jbe/bsw@16
 | 
   101 rocketcgi.set_status(
 | 
| 
jbe/bsw@16
 | 
   102   status               -- Status code and description, e.g. "404 Not Found"
 | 
| 
jbe/bsw@16
 | 
   103 )
 | 
| 
jbe/bsw@16
 | 
   104 
 | 
| 
jbe/bsw@16
 | 
   105 Sends a header line specifying the content-type to the browser.
 | 
| 
jbe/bsw@16
 | 
   106 
 | 
| 
jbe/bsw@16
 | 
   107 --]]--
 | 
| 
jbe/bsw@0
 | 
   108 function set_content_type(content_type)
 | 
| 
jbe/bsw@0
 | 
   109   add_header("Content-Type: ", content_type)
 | 
| 
jbe/bsw@0
 | 
   110 end
 | 
| 
jbe/bsw@16
 | 
   111 --//--
 | 
| 
jbe/bsw@16
 | 
   112 
 | 
| 
jbe/bsw@16
 | 
   113 --[[--
 | 
| 
jbe/bsw@16
 | 
   114 rocketcgi.set_cookie{
 | 
| 
jbe/bsw@16
 | 
   115   name   = name,       -- name of cookie
 | 
| 
jbe/bsw@16
 | 
   116   value  = value,      -- value of cookie
 | 
| 
jbe/bsw@16
 | 
   117   domain = domain,     -- domain where cookie is transmitted
 | 
| 
jbe/bsw@16
 | 
   118   path   = path,       -- path where cookie is transmitted
 | 
| 
jbe/bsw@16
 | 
   119   secure = secure      -- boolean, indicating if cookie should only be transmitted over HTTPS
 | 
| 
jbe/bsw@16
 | 
   120 }
 | 
| 
jbe/bsw@16
 | 
   121 
 | 
| 
jbe/bsw@16
 | 
   122 Sends a header line setting a cookie. NOTE: Currently only session cookies are supported.
 | 
| 
jbe/bsw@16
 | 
   123 
 | 
| 
jbe/bsw@16
 | 
   124 --]]--
 | 
| 
jbe/bsw@16
 | 
   125 function set_cookie(args)
 | 
| 
jbe/bsw@16
 | 
   126   assert(string.find(args.name, "^[0-9A-Za-z%%._~-]+$"), "Illegal cookie name")
 | 
| 
jbe/bsw@16
 | 
   127   assert(string.find(args.value, "^[0-9A-Za-z%%._~-]+$"), "Illegal cookie value")
 | 
| 
jbe/bsw@16
 | 
   128   local parts = {"Set-Cookie: " .. args.name .. "=" .. args.value}
 | 
| 
jbe/bsw@16
 | 
   129   if args.domain then
 | 
| 
jbe/bsw@16
 | 
   130     assert(
 | 
| 
jbe/bsw@16
 | 
   131       string.find(args.path, "^[0-9A-Za-z%%/._~-]+$"),
 | 
| 
jbe/bsw@16
 | 
   132       "Illegal cookie domain"
 | 
| 
jbe/bsw@16
 | 
   133     )
 | 
| 
jbe/bsw@16
 | 
   134     parts[#parts+1] = "domain=" .. args.domain
 | 
| 
jbe/bsw@16
 | 
   135   end
 | 
| 
jbe/bsw@16
 | 
   136   if args.path then
 | 
| 
jbe/bsw@16
 | 
   137     assert(
 | 
| 
jbe/bsw@16
 | 
   138       string.find(args.path, "^[0-9A-Za-z%%/._~-]+$"),
 | 
| 
jbe/bsw@16
 | 
   139       "Illegal cookie path"
 | 
| 
jbe/bsw@16
 | 
   140     )
 | 
| 
jbe/bsw@16
 | 
   141     parts[#parts+1] = "path=" .. args.path
 | 
| 
jbe/bsw@16
 | 
   142   end
 | 
| 
jbe/bsw@16
 | 
   143   if args.secure then
 | 
| 
jbe/bsw@16
 | 
   144     parts[#parts+1] = "secure"
 | 
| 
jbe/bsw@16
 | 
   145   end
 | 
| 
jbe/bsw@16
 | 
   146   add_header(table.concat(parts, "; "))
 | 
| 
jbe/bsw@16
 | 
   147 end
 | 
| 
jbe/bsw@16
 | 
   148 --//--
 | 
| 
jbe/bsw@0
 | 
   149 
 | 
| 
jbe/bsw@0
 | 
   150 method = os.getenv("REQUEST_METHOD") or false
 | 
| 
jbe/bsw@0
 | 
   151 query = os.getenv("QUERY_STRING") or false
 | 
| 
jbe/bsw@0
 | 
   152 cookie_data = os.getenv("HTTP_COOKIE") or false
 | 
| 
jbe/bsw@0
 | 
   153 post_data = io.stdin:read("*a") or false
 | 
| 
jbe/bsw@0
 | 
   154 post_contenttype = os.getenv("CONTENT_TYPE") or false
 | 
| 
jbe/bsw@0
 | 
   155 params = {}
 | 
| 
jbe/bsw@0
 | 
   156 get_params = {}
 | 
| 
jbe/bsw@0
 | 
   157 cookies = {}
 | 
| 
jbe/bsw@0
 | 
   158 post_params = {}
 | 
| 
jbe/bsw@0
 | 
   159 post_filenames = {}
 | 
| 
jbe/bsw@0
 | 
   160 post_types = {}
 | 
| 
jbe/bsw@0
 | 
   161 
 | 
| 
jbe/bsw@0
 | 
   162 local urldecode
 | 
| 
jbe/bsw@0
 | 
   163 do
 | 
| 
jbe/bsw@0
 | 
   164   local b0 = string.byte("0")
 | 
| 
jbe/bsw@0
 | 
   165   local b9 = string.byte("9")
 | 
| 
jbe/bsw@0
 | 
   166   local bA = string.byte("A")
 | 
| 
jbe/bsw@0
 | 
   167   local bF = string.byte("F")
 | 
| 
jbe/bsw@0
 | 
   168   local ba = string.byte("a")
 | 
| 
jbe/bsw@0
 | 
   169   local bf = string.byte("f")
 | 
| 
jbe/bsw@0
 | 
   170   function urldecode(str)
 | 
| 
jbe/bsw@0
 | 
   171     return (
 | 
| 
jbe/bsw@0
 | 
   172       string.gsub(
 | 
| 
jbe/bsw@0
 | 
   173         string.gsub(str, "%+", " "),
 | 
| 
jbe/bsw@0
 | 
   174         "%%([0-9A-Fa-f][0-9A-Fa-f])",
 | 
| 
jbe/bsw@0
 | 
   175         function(hex)
 | 
| 
jbe/bsw@0
 | 
   176           local n1, n2 = string.byte(hex, 1, 2)
 | 
| 
jbe/bsw@0
 | 
   177           if n1 >= b0 and n1 <= b9 then n1 = n1 - b0
 | 
| 
jbe/bsw@0
 | 
   178           elseif n1 >= bA and n1 <= bF then n1 = n1 - bA + 10
 | 
| 
jbe/bsw@0
 | 
   179           elseif n1 >= ba and n1 <= bf then n1 = n1 - ba + 10
 | 
| 
jbe/bsw@0
 | 
   180           else return end
 | 
| 
jbe/bsw@0
 | 
   181           if n2 >= b0 and n2 <= b9 then n2 = n2 - b0
 | 
| 
jbe/bsw@0
 | 
   182           elseif n2 >= bA and n2 <= bF then n2 = n2 - bA + 10
 | 
| 
jbe/bsw@0
 | 
   183           elseif n2 >= ba and n2 <= bf then n2 = n2 - ba + 10
 | 
| 
jbe/bsw@0
 | 
   184           else return end
 | 
| 
jbe/bsw@0
 | 
   185           return string.char(n1 * 16 + n2)
 | 
| 
jbe/bsw@0
 | 
   186         end
 | 
| 
jbe/bsw@0
 | 
   187       )
 | 
| 
jbe/bsw@0
 | 
   188     )
 | 
| 
jbe/bsw@0
 | 
   189   end
 | 
| 
jbe/bsw@0
 | 
   190 end
 | 
| 
jbe/bsw@0
 | 
   191 
 | 
| 
jbe/bsw@0
 | 
   192 local function proc_param(tbl, key, value)
 | 
| 
jbe/bsw@0
 | 
   193   if string.find(key, "%[%]$") then
 | 
| 
jbe/bsw@0
 | 
   194     if tbl[key] then
 | 
| 
jbe/bsw@0
 | 
   195       table.insert(tbl[key], value)
 | 
| 
jbe/bsw@0
 | 
   196     else
 | 
| 
jbe/bsw@0
 | 
   197       local list = { value }
 | 
| 
jbe/bsw@0
 | 
   198       params[key] = list
 | 
| 
jbe/bsw@0
 | 
   199       tbl[key] = list
 | 
| 
jbe/bsw@0
 | 
   200     end
 | 
| 
jbe/bsw@0
 | 
   201   else
 | 
| 
jbe/bsw@0
 | 
   202     params[key] = value
 | 
| 
jbe/bsw@0
 | 
   203     tbl[key] = value
 | 
| 
jbe/bsw@0
 | 
   204   end
 | 
| 
jbe/bsw@0
 | 
   205 end
 | 
| 
jbe/bsw@0
 | 
   206 
 | 
| 
jbe/bsw@0
 | 
   207 local function read_urlencoded_form(tbl, data)
 | 
| 
jbe/bsw@0
 | 
   208   for rawkey, rawvalue in string.gmatch(data, "([^=&]*)=([^=&]*)") do
 | 
| 
jbe/bsw@0
 | 
   209     proc_param(tbl, urldecode(rawkey), urldecode(rawvalue))
 | 
| 
jbe/bsw@0
 | 
   210   end
 | 
| 
jbe/bsw@0
 | 
   211 end
 | 
| 
jbe/bsw@0
 | 
   212 
 | 
| 
jbe/bsw@0
 | 
   213 if query then
 | 
| 
jbe/bsw@0
 | 
   214   read_urlencoded_form(get_params, query)
 | 
| 
jbe/bsw@0
 | 
   215 end
 | 
| 
jbe/bsw@0
 | 
   216 
 | 
| 
jbe/bsw@0
 | 
   217 if cookie_data then
 | 
| 
jbe/bsw@0
 | 
   218   for rawkey, rawvalue in string.gmatch(cookie_data, "([^=; ]*)=([^=; ]*)") do
 | 
| 
jbe/bsw@0
 | 
   219     cookies[urldecode(rawkey)] = urldecode(rawvalue)
 | 
| 
jbe/bsw@0
 | 
   220   end
 | 
| 
jbe/bsw@0
 | 
   221 end
 | 
| 
jbe/bsw@0
 | 
   222 
 | 
| 
jbe/bsw@11
 | 
   223 if post_contenttype and (
 | 
| 
jbe/bsw@11
 | 
   224   post_contenttype == "application/x-www-form-urlencoded" or
 | 
| 
jbe/bsw@11
 | 
   225   string.match(post_contenttype, "^application/x%-www%-form%-urlencoded[ ;]")
 | 
| 
jbe/bsw@11
 | 
   226 ) then
 | 
| 
jbe/bsw@0
 | 
   227   read_urlencoded_form(post_params, post_data)
 | 
| 
jbe/bsw@0
 | 
   228 elseif post_contenttype then
 | 
| 
jbe/bsw@0
 | 
   229   local boundary = string.match(
 | 
| 
jbe/bsw@0
 | 
   230     post_contenttype,
 | 
| 
jbe/bsw@0
 | 
   231     '^multipart/form%-data[ \t]*;[ \t]*boundary="([^"]+)"'
 | 
| 
jbe/bsw@0
 | 
   232   ) or string.match(
 | 
| 
jbe/bsw@0
 | 
   233       post_contenttype,
 | 
| 
jbe/bsw@0
 | 
   234       '^multipart/form%-data[ \t]*;[ \t]*boundary=([^"; \t]+)'
 | 
| 
jbe/bsw@0
 | 
   235   )
 | 
| 
jbe/bsw@0
 | 
   236   if boundary then
 | 
| 
jbe/bsw@0
 | 
   237     local parts = {}
 | 
| 
jbe/bsw@0
 | 
   238     do
 | 
| 
jbe/bsw@0
 | 
   239       local boundary = "\r\n--" .. boundary
 | 
| 
jbe/bsw@0
 | 
   240       local post_data = "\r\n" .. post_data
 | 
| 
jbe/bsw@0
 | 
   241       local pos1, pos2 = string.find(post_data, boundary, 1, true)
 | 
| 
jbe/bsw@0
 | 
   242       while true do
 | 
| 
jbe/bsw@0
 | 
   243         local ind = string.sub(post_data, pos2 + 1, pos2 + 2)
 | 
| 
jbe/bsw@0
 | 
   244         if ind == "\r\n" then
 | 
| 
jbe/bsw@0
 | 
   245           local pos3, pos4 = string.find(post_data, boundary, pos2 + 1, true)
 | 
| 
jbe/bsw@0
 | 
   246           if pos3 then
 | 
| 
jbe/bsw@0
 | 
   247             parts[#parts + 1] = string.sub(post_data, pos2 + 3, pos3 - 1)
 | 
| 
jbe/bsw@0
 | 
   248           else
 | 
| 
jbe/bsw@0
 | 
   249             error("Illegal POST data.")
 | 
| 
jbe/bsw@0
 | 
   250           end
 | 
| 
jbe/bsw@0
 | 
   251           pos1, pos2 = pos3, pos4
 | 
| 
jbe/bsw@0
 | 
   252         elseif ind == "--" then
 | 
| 
jbe/bsw@0
 | 
   253           break
 | 
| 
jbe/bsw@0
 | 
   254         else
 | 
| 
jbe/bsw@0
 | 
   255           error("Illegal POST data.")
 | 
| 
jbe/bsw@0
 | 
   256         end
 | 
| 
jbe/bsw@0
 | 
   257       end
 | 
| 
jbe/bsw@0
 | 
   258     end
 | 
| 
jbe/bsw@0
 | 
   259     for i, part in ipairs(parts) do
 | 
| 
jbe/bsw@0
 | 
   260       local pos = 1
 | 
| 
jbe/bsw@0
 | 
   261       local name, filename, contenttype
 | 
| 
jbe/bsw@0
 | 
   262       while true do
 | 
| 
jbe/bsw@0
 | 
   263         local header
 | 
| 
jbe/bsw@0
 | 
   264         do
 | 
| 
jbe/bsw@0
 | 
   265           local oldpos = pos
 | 
| 
jbe/bsw@0
 | 
   266           pos = string.find(part, "\r\n", oldpos, true)
 | 
| 
jbe/bsw@0
 | 
   267           if not pos then
 | 
| 
jbe/bsw@0
 | 
   268             error("Illegal POST data.")
 | 
| 
jbe/bsw@0
 | 
   269           end
 | 
| 
jbe/bsw@0
 | 
   270           if pos == oldpos then break end
 | 
| 
jbe/bsw@0
 | 
   271           header = string.sub(part, oldpos, pos - 1)
 | 
| 
jbe/bsw@0
 | 
   272           pos = pos + 2
 | 
| 
jbe/bsw@0
 | 
   273         end
 | 
| 
jbe/bsw@0
 | 
   274         if string.find(
 | 
| 
jbe/bsw@0
 | 
   275           string.lower(header),
 | 
| 
jbe/bsw@0
 | 
   276           "^content%-disposition:[ \t]*form%-data[ \t]*;"
 | 
| 
jbe/bsw@0
 | 
   277         ) then
 | 
| 
jbe/bsw@0
 | 
   278           -- TODO: handle all cases correctly
 | 
| 
jbe/bsw@0
 | 
   279           name = string.match(header, ';[ \t]*name="([^"]*)"') or
 | 
| 
jbe/bsw@0
 | 
   280             string.match(header, ';[ \t]*name=([^"; \t]+)')
 | 
| 
jbe/bsw@0
 | 
   281           filename = string.match(header, ';[ \t]*filename="([^"]*)"') or
 | 
| 
jbe/bsw@0
 | 
   282             string.match(header, ';[ \t]*filename=([^"; \t]+)')
 | 
| 
jbe/bsw@0
 | 
   283         else
 | 
| 
jbe/bsw@0
 | 
   284           local dummy, subpos = string.find(
 | 
| 
jbe/bsw@0
 | 
   285             string.lower(header),
 | 
| 
jbe/bsw@0
 | 
   286             "^content%-type:[ \t]*"
 | 
| 
jbe/bsw@0
 | 
   287           )
 | 
| 
jbe/bsw@0
 | 
   288           if subpos then
 | 
| 
jbe/bsw@0
 | 
   289             contenttype = string.sub(header, subpos + 1, #header)
 | 
| 
jbe/bsw@0
 | 
   290           end
 | 
| 
jbe/bsw@0
 | 
   291         end
 | 
| 
jbe/bsw@0
 | 
   292       end
 | 
| 
jbe/bsw@0
 | 
   293       local content = string.sub(part, pos + 2, #part)
 | 
| 
jbe/bsw@0
 | 
   294       if not name then
 | 
| 
jbe/bsw@0
 | 
   295         error("Illegal POST data.")
 | 
| 
jbe/bsw@0
 | 
   296       end
 | 
| 
jbe/bsw@0
 | 
   297       proc_param(post_params, name, content)
 | 
| 
jbe/bsw@0
 | 
   298       post_filenames[name] = filename
 | 
| 
jbe/bsw@0
 | 
   299       post_types[name] = contenttype
 | 
| 
jbe/bsw@0
 | 
   300     end
 | 
| 
jbe/bsw@0
 | 
   301   end
 | 
| 
jbe/bsw@0
 | 
   302 end
 | 
| 
jbe/bsw@0
 | 
   303 
 | 
| 
jbe/bsw@0
 | 
   304 if post_data and #post_data > 262144 then
 | 
| 
jbe/bsw@0
 | 
   305   post_data = nil
 | 
| 
jbe/bsw@0
 | 
   306   collectgarbage("collect")
 | 
| 
jbe/bsw@0
 | 
   307 else
 | 
| 
jbe/bsw@0
 | 
   308   post_data = nil
 | 
| 
jbe/bsw@0
 | 
   309 end
 |