+
+-- Parse a http message body
+function parse_message_body( reader, message, filecb )
+
+ if type(message) == "table" then
+ local env = message.env
+
+ local clen = ( env.CONTENT_LENGTH or HTTP_MAX_CONTENT ) + 0
+
+ -- Process post method
+ if env.REQUEST_METHOD:lower() == "post" and env.CONTENT_TYPE then
+ -- Is it multipart/form-data ?
+ if env.CONTENT_TYPE:match("^multipart/form%-data") then
+ for k, v in pairs( mimedecode(
+ reader,
+ env.CONTENT_TYPE:match("boundary=(.+)"),
+ filecb
+ ) ) do
+ message.params[k] = v
+ end
+
+ -- Is it x-www-form-urlencoded?
+ elseif env.CONTENT_TYPE:match('^application/x%-www%-form%-urlencoded') then
+ -- XXX: readline isn't the best solution here
+ for chunk in reader do
+ for k, v in pairs( urldecode_params( chunk ) ) do
+ message.params[k] = v
+ end
+
+ -- XXX: unreliable (undefined line length)
+ if clen + chunk:len() >= HTTP_MAX_CONTENT then
+ break
+ end
+
+ clen = clen + chunk:len()
+ end
+
+ -- Unhandled encoding
+ -- If a file callback is given then feed it line by line, else
+ -- store whole buffer in message.content
+ else
+ for chunk in reader do
+
+ -- We have a callback, feed it.
+ if type(filecb) == "function" then
+
+ filecb( "_post", nil, chunk, false )
+
+ -- Append to .content buffer.
+ else
+ message.content =
+ type(message.content) == "string"
+ and message.content .. chunk
+ or chunk
+ end
+
+ -- XXX: unreliable
+ if clen + chunk:len() >= HTTP_MAX_CONTENT then
+ break
+ end
+
+ clen = clen + chunk:len()
+ end
+
+ -- Send eof to callback
+ if type(filecb) == "function" then
+ filecb( "_post", nil, "", true )
+ end
+ end
+ end
+ end
+end
+
+
+function _linereader( obj, bufsz )
+
+ bufsz = ( bufsz and bufsz >= 256 ) and bufsz or 256
+
+ local __read = function() return nil end
+ local __eof = function(x) return type(x) ~= "string" or #x == 0 end
+
+ local _pos = 1
+ local _buf = ""
+ local _eof = nil