httpserver-request.lua 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. -- httpserver-request
  2. -- Part of nodemcu-httpserver, parses incoming client requests.
  3. -- Author: Marcos Kirsch
  4. local function validateMethod(method)
  5. local httpMethods = {GET=true, HEAD=true, POST=true, PUT=true, DELETE=true, TRACE=true, OPTIONS=true, CONNECT=true, PATCH=true}
  6. -- default for non-existent attributes returns nil, which evaluates to false
  7. return httpMethods[method]
  8. end
  9. local function uriToFilename(uri)
  10. return "http/" .. string.sub(uri, 2, -1)
  11. end
  12. local function parseArgs(args)
  13. local r = {}; i=1
  14. if args == nil or args == "" then return r end
  15. for arg in string.gmatch(args, "([^&]+)") do
  16. local name, value = string.match(arg, "(.*)=(.*)")
  17. if name ~= nil then r[name] = value end
  18. i = i + 1
  19. end
  20. return r
  21. end
  22. local function parseUri(uri)
  23. local r = {}
  24. local filename
  25. local ext
  26. local fullExt = {}
  27. if uri == nil then return r end
  28. if uri == "/" then uri = "/index.html" end
  29. questionMarkPos, b, c, d, e, f = uri:find("?")
  30. if questionMarkPos == nil then
  31. r.file = uri:sub(1, questionMarkPos)
  32. r.args = {}
  33. else
  34. r.file = uri:sub(1, questionMarkPos - 1)
  35. r.args = parseArgs(uri:sub(questionMarkPos+1, #uri))
  36. end
  37. filename = r.file
  38. while filename:match("%.") do
  39. filename,ext = filename:match("(.+)%.(.+)")
  40. table.insert(fullExt,1,ext)
  41. end
  42. r.ext = table.concat(fullExt,".")
  43. r.isScript = r.ext == "lua" or r.ext == "lc"
  44. r.file = uriToFilename(r.file)
  45. return r
  46. end
  47. -- Parses the client's request. Returns a dictionary containing pretty much everything
  48. -- the server needs to know about the uri.
  49. return function (request)
  50. local e = request:find("\r\n", 1, true)
  51. if not e then return nil end
  52. local line = request:sub(1, e - 1)
  53. local r = {}
  54. _, i, r.method, r.request = line:find("^([A-Z]+) (.-) HTTP/[1-9]+.[0-9]+$")
  55. r.methodIsValid = validateMethod(r.method)
  56. r.uri = parseUri(r.request)
  57. return r
  58. end