httpserver-request.lua 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. --print("Request: \n", request)
  51. local e = request:find("\r\n", 1, true)
  52. if not e then return nil end
  53. local line = request:sub(1, e - 1)
  54. local r = {}
  55. _, i, r.method, r.request = line:find("^([A-Z]+) (.-) HTTP/[1-9]+.[0-9]+$")
  56. r.methodIsValid = validateMethod(r.method)
  57. r.uri = parseUri(r.request)
  58. return r
  59. end