gluon-web: improve error handling of parse_message_body()

Actually raise an error and turn it into an HTTP 400 return code when
something goes wrong, rather than ignoring the error.

We also improve the conditions under which errors are thrown before
pump() is called: We don't need to check for the multipart/form-data
content-type twice, and a POST without this content-type is now always
an error.
This commit is contained in:
Matthias Schiffer 2022-01-25 20:56:00 +01:00
parent de43b306d4
commit f3960eeb47
2 changed files with 16 additions and 17 deletions

View File

@ -184,9 +184,15 @@ local function dispatch(config, http, request)
return return
end end
http:parse_input(node.filehandler) local ok, err = pcall(http.parse_input, http, node.filehandler)
if not ok then
http:status(400, "Bad request")
http:prepare_content("text/plain")
http:write(err .. "\r\n")
return
end
local ok, err = pcall(node.target) ok, err = pcall(node.target)
if not ok then if not ok then
http:status(500, "Internal Server Error") http:status(500, "Internal Server Error")
renderer.render_layout("error/500", { renderer.render_layout("error/500", {

View File

@ -108,16 +108,11 @@ end
-- o String value containing a chunk of the file data -- o String value containing a chunk of the file data
-- o Boolean which indicates whether the current chunk is the last one (eof) -- o Boolean which indicates whether the current chunk is the last one (eof)
local function mimedecode_message_body(src, msg, filecb) local function mimedecode_message_body(src, msg, filecb)
local mime_boundary = (msg.env.CONTENT_TYPE or ''):match("^multipart/form%-data; boundary=(.+)$")
if msg and msg.env.CONTENT_TYPE then if not mime_boundary then
msg.mime_boundary = msg.env.CONTENT_TYPE:match("^multipart/form%-data; boundary=(.+)$") error("Invalid Content-Type found")
end end
if not msg.mime_boundary then
return nil, "Invalid Content-Type found"
end
local tlen = 0 local tlen = 0
local inhdr = false local inhdr = false
local field = nil local field = nil
@ -188,10 +183,10 @@ local function mimedecode_message_body(src, msg, filecb)
local spos, epos, found local spos, epos, found
repeat repeat
spos, epos = data:find("\r\n--" .. msg.mime_boundary .. "\r\n", 1, true) spos, epos = data:find("\r\n--" .. mime_boundary .. "\r\n", 1, true)
if not spos then if not spos then
spos, epos = data:find("\r\n--" .. msg.mime_boundary .. "--\r\n", 1, true) spos, epos = data:find("\r\n--" .. mime_boundary .. "--\r\n", 1, true)
end end
@ -250,20 +245,18 @@ local function mimedecode_message_body(src, msg, filecb)
return true return true
end end
return pump(src, snk) assert(pump(src, snk))
end end
-- This function will examine the Content-Type within the given message object -- This function will examine the Content-Type within the given message object
-- to select the appropriate content decoder. -- to select the appropriate content decoder.
-- Currently only the multipart/form-data mime type is supported. -- Currently only the multipart/form-data mime type is supported.
function M.parse_message_body(src, msg, filecb) function M.parse_message_body(src, msg, filecb)
if not (msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE) then if msg.env.REQUEST_METHOD ~= "POST" then
return return
end end
if msg.env.CONTENT_TYPE:match("^multipart/form%-data") then mimedecode_message_body(src, msg, filecb)
return mimedecode_message_body(src, msg, filecb)
end
end end
return M return M