diff --git a/Makefile b/Makefile
index 348bfcc..10c6c27 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ SPEED=9600
# End of user config
######################################################################
HTTP_FILES := $(wildcard http/*)
-LUA_FILES := init.lua httpserver.lua httpserver-request.lua httpserver-static.lua httpserver-error.lua
+LUA_FILES := init.lua httpserver.lua httpserver-request.lua httpserver-static.lua httpserver-header.lua httpserver-error.lua
# Print usage
usage:
diff --git a/httpserver-error.lua b/httpserver-error.lua
index 3bc5af9..a8dfe84 100644
--- a/httpserver-error.lua
+++ b/httpserver-error.lua
@@ -2,20 +2,13 @@
-- Part of nodemcu-httpserver, handles sending error pages to client.
-- Author: Marcos Kirsch
-local function getHTTPStatusString(code)
- if code == 404 then return "Not Found" end
- if code == 400 then return "Bad Request" end
- if code == 501 then return "Not Implemented" end
- return "Unknown HTTP status"
-end
-
-local function sendHeader(connection, code, codeString, mimeType)
- connection:send("HTTP/1.0 " .. code .. " " .. codeString .. "\r\nServer: nodemcu-httpserver\r\nContent-Type: " .. mimeType .. "\r\nConnection: close\r\n\r\n")
-end
-
return function (connection, args)
- local errorString = getHTTPStatusString(args.code)
- print("Error " .. args.code .. ": " .. errorString)
- sendHeader(connection, args.code, errorString, "text/html")
- connection:send("
" .. args.code .. " - " .. errorString .. "" .. args.code .. " - " .. errorString .. "
\r\n")
+
+ local function sendHeader(connection, code, errorString, mimeType)
+ connection:send("HTTP/1.0 " .. code .. " " .. errorString .. "\r\nServer: nodemcu-httpserver\r\nContent-Type: " .. mimeType .. "\r\nConnection: close\r\n\r\n")
+ end
+
+ print("Error " .. args.code .. ": " .. args.errorString)
+ sendHeader(connection, args.code, args.errorString, "text/html")
+ connection:send("" .. args.code .. " - " .. args.errorString .. "" .. args.code .. " - " .. args.errorString .. "
\r\n")
end
diff --git a/httpserver-static.lua b/httpserver-static.lua
index e7ca343..d3ac1bd 100644
--- a/httpserver-static.lua
+++ b/httpserver-static.lua
@@ -2,41 +2,20 @@
-- Part of nodemcu-httpserver, handles sending static files to client.
-- Author: Marcos Kirsch
-local function getMimeType(ext)
- local gzip = false
- -- A few MIME types. Keep list short. If you need something that is missing, let's add it.
- local mt = {css = "text/css", gif = "image/gif", html = "text/html", ico = "image/x-icon", jpeg = "image/jpeg", jpg = "image/jpeg", js = "application/javascript", json = "application/json", png = "image/png"}
- -- add comressed flag if file ends with gz
- if ext:find("%.gz$") then
- ext = ext:sub(1, -4)
- gzip = true
- end
- if mt[ext] then contentType = mt[ext] else contentType = "text/plain" end
- return {contentType = contentType, gzip = gzip }
-
-end
-
-local function sendHeader(connection, code, codeString, mimeType)
- connection:send("HTTP/1.0 " .. code .. " " .. codeString .. "\r\nServer: nodemcu-httpserver\r\nContent-Type: " .. mimeType["contentType"] .. "\r\n")
- if mimeType["gzip"] then
- connection:send("Content-Encoding: gzip\r\n")
- end
- connection:send("Connection: close\r\n\r\n")
-end
-
return function (connection, args)
- sendHeader(connection, 200, "OK", getMimeType(args.ext))
+ dofile("httpserver-header.lc")(connection, 200, args.ext)
--print("Begin sending:", args.file)
-- Send file in little chunks
local continue = true
local bytesSent = 0
while continue do
+ collectgarbage()
-- NodeMCU file API lets you open 1 file at a time.
-- So we need to open, seek, close each time in order
-- to support multiple simultaneous clients.
file.open(args.file)
file.seek("set", bytesSent)
- local chunk = file.read(512)
+ local chunk = file.read(256)
file.close()
if chunk == nil then
continue = false
@@ -44,6 +23,7 @@ return function (connection, args)
coroutine.yield()
connection:send(chunk)
bytesSent = bytesSent + #chunk
+ chunk = nil
--print("Sent" .. args.file, bytesSent)
end
end
diff --git a/httpserver.lua b/httpserver.lua
index 23b7ac6..1a2a0b7 100644
--- a/httpserver.lua
+++ b/httpserver.lua
@@ -15,32 +15,31 @@ return function (port)
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
+ uri.args = {code = 400, errorString = "Bad Request"}
fileServeFunction = dofile("httpserver-error.lc")
else
local fileExists = file.open(uri.file, "r")
file.close()
- collectgarbage()
if not fileExists then
- uri.args['code'] = 404
+ 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
- uri.args['ext'] = uri.ext
+ uri.args = {file = uri.file, 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)
+ collectgarbage()
-- print(payload) -- for debugging
-- parse payload and decide what to serve.
local req = dofile("httpserver-request.lc")(payload)
@@ -49,23 +48,29 @@ return function (port)
onGet(connection, req.uri)
else
local args = {}
- if req.methodIsValid then args['code'] = 501 else args['code'] = 400 end
- dofile("httpserver-error.lc")(connection, 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)
- 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
+ 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
diff --git a/init.lua b/init.lua
index 07df51d..99a33df 100644
--- a/init.lua
+++ b/init.lua
@@ -43,7 +43,7 @@ local compileAndRemoveIfNeeded = function(f)
end
end
-local serverFiles = {'httpserver.lua', 'httpserver-request.lua', 'httpserver-static.lua', 'httpserver-error.lua'}
+local serverFiles = {'httpserver.lua', 'httpserver-request.lua', 'httpserver-static.lua', 'httpserver-header.lua', 'httpserver-error.lua'}
for i, f in ipairs(serverFiles) do compileAndRemoveIfNeeded(f) end
compileAndRemoveIfNeeded = nil