summaryrefslogtreecommitdiffstats
path: root/src/civetweb/test/handle_form.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/civetweb/test/handle_form.lua')
-rw-r--r--src/civetweb/test/handle_form.lua123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/civetweb/test/handle_form.lua b/src/civetweb/test/handle_form.lua
new file mode 100644
index 00000000..c3694ae2
--- /dev/null
+++ b/src/civetweb/test/handle_form.lua
@@ -0,0 +1,123 @@
+-- Some basic checks
+if mg.request_info.request_method ~= "POST" or mg.request_info.content_type:lower():sub(1,19) ~= 'multipart/form-data' then
+ mg.write("HTTP/1.0 400 OK\r\n")
+ mg.write("Connection: close\r\n")
+ mg.write("Content-Type: text/plain; charset=utf-8\r\n")
+ mg.write("Cache-Control: max-age=0, must-revalidate\r\n")
+ mg.write("\r\n")
+ mg.write("Bad request\r\n\r\n")
+ return
+end
+
+-- HTTP headers
+mg.write("HTTP/1.0 200 OK\r\n")
+mg.write("Connection: close\r\n")
+mg.write("Content-Type: text/plain; charset=utf-8\r\n")
+mg.write("Cache-Control: max-age=0, must-revalidate\r\n")
+mg.write("\r\n")
+
+-- Which form sent the data?
+mg.write("Read POST data from " .. mg.request_info.http_headers.Referer .. ":\r\n\r\n")
+
+-- Count some data fields
+local fields = 0
+local datasize = 0
+
+-- Read the entire body data (POST content) into "bdata" variable.
+-- Use a string builder pattern for performance reasons
+stringtab = {}
+bdata = ""
+repeat
+ local add_data = mg.read()
+ if add_data then
+ stringtab[#stringtab+1] = add_data
+ end
+until (add_data == nil);
+bdata = table.concat(stringtab)
+stringtab = nil
+
+-- Get the boundary string.
+bs = "--" .. ((mg.request_info.content_type):upper():match("BOUNDARY=(.*)"));
+
+-- The POST data has to start with the boundary string.
+-- Check this and remove the starting boundary.
+if bdata:sub(1, #bs) ~= bs then
+ error "invalid format of POST data"
+end
+bdata = bdata:sub(#bs)
+
+-- The boundary now starts with CR LF.
+bs = "\r\n" .. bs
+
+-- Now loop through all the parts
+while #bdata>4 do
+ -- Find the header of new part.
+ part_header_end = bdata:find("\r\n\r\n", 1, true)
+
+ -- Parse the header.
+ local form_field_name, file_name
+ h = bdata:sub(1, part_header_end+2)
+ for key,val in h:gmatch("([^%:\r\n]*)%s*%:%s*([^\r\n]*)\r\n") do
+ if key:upper() == "CONTENT-DISPOSITION" then
+ form_field_name = val:match('name=%"([^%"]*)%"')
+ file_name = val:match('filename=%"([^%"]*)%"')
+ end
+ end
+
+ -- Remove the header from "bdata".
+ bdata = bdata:sub(part_header_end+4)
+
+ -- Find the end of the body by locating the boundary string.
+ local part_body_end = bdata:find(bs, 1, true)
+
+ -- Isolate the content, and drop it from "bdata".
+ local form_field_value = bdata:sub(1,part_body_end-1)
+ bdata = bdata:sub(part_body_end+#bs)
+
+ -- Now the data (file content or field value) is isolated: We know form_field_name and form_field_value.
+ -- Here the script should do something useful with the data. This example just sends it back to the client.
+ if form_field_name then
+ mg.write("Field name: " .. form_field_name .. "\r\n")
+ end
+
+ local len = #form_field_value
+ mg.write("Field data length: " .. len .. "\r\n")
+
+ if file_name then
+ mg.write("File name: " .. file_name .. "\r\n")
+ mg.write("File content:\r\n")
+ local maxlen
+ if len>320 then maxlen=320 else maxlen=len end
+
+ for l=0,maxlen,16 do
+ for m=1,16 do
+ local b = form_field_value:byte(l+m)
+ if (b) then
+ mg.write(string.format("%02x ", b))
+ else
+ mg.write(" ")
+ end
+ end
+ mg.write(" - " .. form_field_value:sub(l+1,l+16):gsub("[%c%z%s]", " ") .. "\r\n")
+ end
+ if maxlen<len then
+ mg.write(string.format("... (+ %u bytes)\r\n", len-maxlen))
+ end
+
+ else
+ -- not a file
+ if len<50 then
+ mg.write("Field value: " .. form_field_value .. "\r\n")
+ else
+ mg.write("Field value: " .. form_field_value:sub(1, 40) .. " .. (" .. len .. " bytes)\r\n")
+ end
+ end
+
+
+ mg.write("\r\n")
+ fields = fields + 1
+ datasize = datasize + len
+
+end
+
+mg.write("Got " .. fields .. " input fields with " .. datasize .. " bytes total\r\n");