nodemcu-httpserver/httpserver.lua
TJ Borromeo 925af34b1a De-duplicate wifi.sta.getip() call
Technically, if the wifi.sta.getip() or wifi.ap.getip() call return invalid ip addresses, you shouldn't assume that it's running.  However, the lack of that type of check means that this change will function similarly without incurring another function call in a constrained stack/heap environment.
2015-04-24 14:54:13 -07:00

89 lines
3.4 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)
collectgarbage()
local fileServeFunction = nil
if #(uri.file) > 32 then
-- nodemcu-firmware cannot handle long filenames.
uri.args = {code = 400, errorString = "Bad Request"}
fileServeFunction = dofile("httpserver-error.lc")
else
local fileExists = file.open(uri.file, "r")
file.close()
if not fileExists then
uri.args = {code = 404, errorString = "Not Found"}
fileServeFunction = dofile("httpserver-error.lc")
elseif uri.isScript then
fileServeFunction = dofile(uri.file)
else
uri.args = {file = uri.file, ext = uri.ext}
fileServeFunction = dofile("httpserver-static.lc")
end
end
connectionThread = coroutine.create(fileServeFunction)
coroutine.resume(connectionThread, connection, uri.args)
end
local function onReceive(connection, payload)
collectgarbage()
-- 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 and req.method == "GET" then
onGet(connection, req.uri)
else
local args = {}
local fileServeFunction = dofile("httpserver-error.lc")
if req.methodIsValid then
args = {code = 501, errorString = "Not Implemented"}
else
args = {code = 400, errorString = "Bad Request"}
end
connectionThread = coroutine.create(fileServeFunction)
coroutine.resume(connectionThread, connection, args)
end
end
local function onSent(connection, payload)
collectgarbage()
if connectionThread then
local connectionThreadStatus = coroutine.status(connectionThread)
if connectionThreadStatus == "suspended" then
-- Not finished sending file, resume.
coroutine.resume(connectionThread)
elseif connectionThreadStatus == "dead" then
-- We're done sending file.
connection:close()
connectionThread = nil
end
end
end
connection:on("receive", onReceive)
connection:on("sent", onSent)
end
)
-- false and nil evaluate as false
local ip = wifi.sta.getip()
if not ip then ip = wifi.ap.getip() end
print("nodemcu-httpserver running at http://" .. ip .. ":" .. port)
return s
end