nodemcu-httpserver/httpserver.lua

80 lines
3.1 KiB
Lua

-- httpserver
-- Author: Marcos Kirsch
-- Starts web server in the specified port.
return function (port)
local s = net.createServer(net.TCP, 10) -- 10 seconds client timeout
s:listen(
port,
function (connection)
-- This variable holds the thread used for sending data back to the user.
-- We do it in a separate thread because we need to yield when sending lots
-- of data in order to avoid overflowing the mcu's buffer.
local connectionThread
local function onGet(connection, uri)
local fileServeFunction = nil
if #(uri.file) > 32 then
-- nodemcu-firmware cannot handle long filenames.
uri.args['code'] = 400
fileServeFunction = dofile("httpserver-error.lc")
else
local fileExists = file.open(uri.file, "r")
file.close()
if not fileExists then
uri.args['code'] = 404
fileServeFunction = dofile("httpserver-error.lc")
elseif uri.isScript then
collectgarbage()
fileServeFunction = dofile(uri.file)
else
uri.args['file'] = uri.file
uri.args['ext'] = uri.ext
fileServeFunction = dofile("httpserver-static.lc")
end
end
connectionThread = coroutine.create(fileServeFunction)
--print("Thread created", connectionThread)
coroutine.resume(connectionThread, connection, uri.args)
end
local function onReceive(connection, payload)
-- print(payload) -- for debugging
-- parse payload and decide what to serve.
local req = dofile("httpserver-request.lc")(payload)
print("Requested URI: " .. req.request)
if req.methodIsValid then
if req.method == "GET" then onGet(connection, req.uri)
else dofile("httpserver-static.lc")(conection, {code=501}) end
else
dofile("httpserver-static.lc")(conection, {code=400})
end
end
local function onSent(connection, payload)
local connectionThreadStatus = coroutine.status(connectionThread)
-- print (connectionThread, "status is", connectionThreadStatus)
if connectionThreadStatus == "suspended" then
-- Not finished sending file, resume.
-- print("Resume thread", connectionThread)
coroutine.resume(connectionThread)
elseif connectionThreadStatus == "dead" then
-- We're done sending file.
-- print("Done thread", connectionThread)
connection:close()
connectionThread = nil
end
end
connection:on("receive", onReceive)
connection:on("sent", onSent)
end
)
print("nodemcu-httpserver running at http://" .. wifi.sta.getip() .. ":" .. port)
return s
end