]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | -- Some basic checks\r |
2 | if mg.request_info.request_method ~= "POST" or mg.request_info.content_type:lower():sub(1,19) ~= 'multipart/form-data' then\r | |
3 | mg.write("HTTP/1.0 400 OK\r\n")\r | |
4 | mg.write("Connection: close\r\n")\r | |
5 | mg.write("Content-Type: text/plain; charset=utf-8\r\n")\r | |
6 | mg.write("Cache-Control: max-age=0, must-revalidate\r\n")\r | |
7 | mg.write("\r\n")\r | |
8 | mg.write("Bad request\r\n\r\n")\r | |
9 | return\r | |
10 | end\r | |
11 | \r | |
12 | -- HTTP headers\r | |
13 | mg.write("HTTP/1.0 200 OK\r\n")\r | |
14 | mg.write("Connection: close\r\n")\r | |
15 | mg.write("Content-Type: text/plain; charset=utf-8\r\n")\r | |
16 | mg.write("Cache-Control: max-age=0, must-revalidate\r\n")\r | |
17 | mg.write("\r\n")\r | |
18 | \r | |
19 | -- Which form sent the data?\r | |
20 | mg.write("Read POST data from " .. mg.request_info.http_headers.Referer .. ":\r\n\r\n")\r | |
21 | \r | |
22 | -- Count some data fields\r | |
23 | local fields = 0\r | |
24 | local datasize = 0\r | |
25 | \r | |
26 | -- Read the entire body data (POST content) into "bdata" variable.\r | |
27 | -- Use a string builder pattern for performance reasons\r | |
28 | stringtab = {}\r | |
29 | bdata = ""\r | |
30 | repeat\r | |
31 | local add_data = mg.read()\r | |
32 | if add_data then\r | |
33 | stringtab[#stringtab+1] = add_data\r | |
34 | end\r | |
35 | until (add_data == nil);\r | |
36 | bdata = table.concat(stringtab)\r | |
37 | stringtab = nil\r | |
38 | \r | |
39 | -- Get the boundary string.\r | |
40 | bs = "--" .. ((mg.request_info.content_type):upper():match("BOUNDARY=(.*)"));\r | |
41 | \r | |
42 | -- The POST data has to start with the boundary string.\r | |
43 | -- Check this and remove the starting boundary.\r | |
44 | if bdata:sub(1, #bs) ~= bs then\r | |
45 | error "invalid format of POST data"\r | |
46 | end\r | |
47 | bdata = bdata:sub(#bs)\r | |
48 | \r | |
49 | -- The boundary now starts with CR LF.\r | |
50 | bs = "\r\n" .. bs\r | |
51 | \r | |
52 | -- Now loop through all the parts\r | |
53 | while #bdata>4 do\r | |
54 | -- Find the header of new part.\r | |
55 | part_header_end = bdata:find("\r\n\r\n", 1, true)\r | |
56 | \r | |
57 | -- Parse the header.\r | |
58 | local form_field_name, file_name\r | |
59 | h = bdata:sub(1, part_header_end+2)\r | |
60 | for key,val in h:gmatch("([^%:\r\n]*)%s*%:%s*([^\r\n]*)\r\n") do\r | |
61 | if key:upper() == "CONTENT-DISPOSITION" then\r | |
62 | form_field_name = val:match('name=%"([^%"]*)%"')\r | |
63 | file_name = val:match('filename=%"([^%"]*)%"')\r | |
64 | end\r | |
65 | end\r | |
66 | \r | |
67 | -- Remove the header from "bdata".\r | |
68 | bdata = bdata:sub(part_header_end+4)\r | |
69 | \r | |
70 | -- Find the end of the body by locating the boundary string.\r | |
71 | local part_body_end = bdata:find(bs, 1, true)\r | |
72 | \r | |
73 | -- Isolate the content, and drop it from "bdata".\r | |
74 | local form_field_value = bdata:sub(1,part_body_end-1)\r | |
75 | bdata = bdata:sub(part_body_end+#bs)\r | |
76 | \r | |
77 | -- Now the data (file content or field value) is isolated: We know form_field_name and form_field_value.\r | |
78 | -- Here the script should do something useful with the data. This example just sends it back to the client.\r | |
79 | if form_field_name then\r | |
80 | mg.write("Field name: " .. form_field_name .. "\r\n")\r | |
81 | end\r | |
82 | \r | |
83 | local len = #form_field_value\r | |
84 | mg.write("Field data length: " .. len .. "\r\n")\r | |
85 | \r | |
86 | if file_name then\r | |
87 | mg.write("File name: " .. file_name .. "\r\n")\r | |
88 | mg.write("File content:\r\n")\r | |
89 | local maxlen\r | |
90 | if len>320 then maxlen=320 else maxlen=len end\r | |
91 | \r | |
92 | for l=0,maxlen,16 do\r | |
93 | for m=1,16 do\r | |
94 | local b = form_field_value:byte(l+m)\r | |
95 | if (b) then\r | |
96 | mg.write(string.format("%02x ", b))\r | |
97 | else\r | |
98 | mg.write(" ")\r | |
99 | end\r | |
100 | end\r | |
101 | mg.write(" - " .. form_field_value:sub(l+1,l+16):gsub("[%c%z%s]", " ") .. "\r\n")\r | |
102 | end\r | |
103 | if maxlen<len then\r | |
104 | mg.write(string.format("... (+ %u bytes)\r\n", len-maxlen))\r | |
105 | end\r | |
106 | \r | |
107 | else\r | |
108 | -- not a file\r | |
109 | if len<50 then\r | |
110 | mg.write("Field value: " .. form_field_value .. "\r\n")\r | |
111 | else\r | |
112 | mg.write("Field value: " .. form_field_value:sub(1, 40) .. " .. (" .. len .. " bytes)\r\n")\r | |
113 | end\r | |
114 | end\r | |
115 | \r | |
116 | \r | |
117 | mg.write("\r\n")\r | |
118 | fields = fields + 1\r | |
119 | datasize = datasize + len\r | |
120 | \r | |
121 | end\r | |
122 | \r | |
123 | mg.write("Got " .. fields .. " input fields with " .. datasize .. " bytes total\r\n");\r |