handle_form_data.lua 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. function add_data(data)
  2. local additional_data = mg.read()
  3. if additional_data then
  4. return data .. additional_data, true
  5. end
  6. return data, false
  7. end
  8. function parse_multipart_form(got_field)
  9. local data, ok = add_data("")
  10. if not ok then
  11. return "Can not read data"
  12. end
  13. --[[
  14. local b = mg.request_info.content_type:upper():find("BOUNDARY=");
  15. if b then
  16. b = mg.request_info.content_type:sub(b+9)
  17. end
  18. if not b or #b<16 or #b>1024 then
  19. return false, "Boundary string not reasonable"
  20. end
  21. ]]
  22. local b = "--" .. mg.request_info.content_type:upper():match("BOUNDARY=(.*)");
  23. --b = "--" .. b
  24. if data:sub(1, #b) ~= b then
  25. return false, "Multipart body does not start properly"
  26. end
  27. data = data:sub(#b)
  28. b = "\r\n" .. b
  29. -- while there are unread parts
  30. while #data>0 and data~="--\r\n" do
  31. local name = nil
  32. local value = nil
  33. local file_name = nil
  34. local file_type = nil
  35. -- isolate the header of the new part
  36. local part_header_end
  37. repeat
  38. part_header_end = data:find("\r\n\r\n", 1, true)
  39. if not part_header_end then
  40. data, ok = add_data(data)
  41. if not ok then
  42. return false, "protocol violation: header does not end properly"
  43. end
  44. end
  45. until part_header_end
  46. -- parse the header of the new part
  47. local header = {}
  48. for k,v in data:sub(1,part_header_end+2):gmatch("([^%:\r\n]*)%s*%:%s*([^\r\n]*)\r\n") do
  49. header[k] = v
  50. local kupper = k:upper()
  51. if (kupper=="CONTENT-DISPOSITION") then
  52. name = v:match('name=%"([^%"]*)%"')
  53. file_name = v:match('filename=%"([^%"]*)%"')
  54. elseif (kupper=="CONTENT-TYPE") then
  55. file_type = v
  56. end
  57. end
  58. -- isolate the body of the new part
  59. local part_body_end
  60. data = data:sub(part_header_end+4)
  61. repeat
  62. part_body_end = data:find(b, 1, true)
  63. if not part_body_end then
  64. data, ok = add_data(data)
  65. if not ok then
  66. return false, "protocol violation: body does not end properly"
  67. end
  68. end
  69. until part_body_end
  70. local value = data:sub(1,part_body_end-1)
  71. data = data:sub(part_body_end+#b)
  72. data = add_data(data)
  73. -- send the result to the caller
  74. got_field(name, value, file_name, file_type)
  75. end
  76. return true, ""
  77. end
  78. mg.write("HTTP/1.0 200 OK\r\n")
  79. mg.write("Connection: close\r\n")
  80. mg.write("Content-Type: text/plain; charset=utf-8\r\n")
  81. mg.write("Cache-Control: max-age=0, must-revalidate\r\n")
  82. mg.write("\r\n")
  83. mg.write("Parse request:\r\n")
  84. function fetch(k, v, fn, ft)
  85. mg.write(k .. " = " .. v .. "\r\n")
  86. end
  87. ok, errtxt = parse_multipart_form(fetch)
  88. if not ok then
  89. mg.write("Error: " .. errtxt .. "\r\n")
  90. else
  91. mg.write("Parsing OK\r\n")
  92. end