|
@@ -13,47 +13,51 @@ return function (port)
|
|
-- We do it in a separate thread because we need to yield when sending lots
|
|
-- 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.
|
|
-- of data in order to avoid overflowing the mcu's buffer.
|
|
local connectionThread
|
|
local connectionThread
|
|
-
|
|
|
|
|
|
+
|
|
local allowStatic = {GET=true, HEAD=true, POST=false, PUT=false, DELETE=false, TRACE=false, OPTIONS=false, CONNECT=false, PATCH=false}
|
|
local allowStatic = {GET=true, HEAD=true, POST=false, PUT=false, DELETE=false, TRACE=false, OPTIONS=false, CONNECT=false, PATCH=false}
|
|
|
|
|
|
- local function startServing(fileServeFunction, connection, req, args)
|
|
|
|
|
|
+ local function startServing(fileServeFunction, connection, req, args)
|
|
|
|
+
|
|
local bufferedConnection = {}
|
|
local bufferedConnection = {}
|
|
connectionThread = coroutine.create(function(fileServeFunction, bconnection, req, args)
|
|
connectionThread = coroutine.create(function(fileServeFunction, bconnection, req, args)
|
|
fileServeFunction(bconnection, req, args)
|
|
fileServeFunction(bconnection, req, args)
|
|
if not bconnection:flush() then
|
|
if not bconnection:flush() then
|
|
- connection:close()
|
|
|
|
- connectionThread = nil
|
|
|
|
- end
|
|
|
|
|
|
+ connection:close()
|
|
|
|
+ connectionThread = nil
|
|
|
|
+ end
|
|
end)
|
|
end)
|
|
- function bufferedConnection:flush()
|
|
|
|
- if self.size > 0 then
|
|
|
|
- connection:send(table.concat(self.data, ""))
|
|
|
|
- self.data = {}
|
|
|
|
- self.size = 0
|
|
|
|
- return true
|
|
|
|
- end
|
|
|
|
- return false
|
|
|
|
|
|
+
|
|
|
|
+ function bufferedConnection:flush()
|
|
|
|
+ if self.size > 0 then
|
|
|
|
+ connection:send(table.concat(self.data, ""))
|
|
|
|
+ self.data = {}
|
|
|
|
+ self.size = 0
|
|
|
|
+ return true
|
|
|
|
+ end
|
|
|
|
+ return false
|
|
end
|
|
end
|
|
- function bufferedConnection:send(payload)
|
|
|
|
- local l = payload:len()
|
|
|
|
- if l + self.size > 1000 then
|
|
|
|
- if self:flush() then
|
|
|
|
- coroutine.yield()
|
|
|
|
- end
|
|
|
|
- end
|
|
|
|
- if l > 800 then
|
|
|
|
- connection:send(payload)
|
|
|
|
- coroutine.yield()
|
|
|
|
- else
|
|
|
|
- table.insert(self.data, payload)
|
|
|
|
- self.size = self.size + l
|
|
|
|
- end
|
|
|
|
|
|
+
|
|
|
|
+ function bufferedConnection:send(payload)
|
|
|
|
+ local l = payload:len()
|
|
|
|
+ if l + self.size > 1000 then
|
|
|
|
+ if self:flush() then
|
|
|
|
+ coroutine.yield()
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+ if l > 800 then
|
|
|
|
+ connection:send(payload)
|
|
|
|
+ coroutine.yield()
|
|
|
|
+ else
|
|
|
|
+ table.insert(self.data, payload)
|
|
|
|
+ self.size = self.size + l
|
|
|
|
+ end
|
|
end
|
|
end
|
|
|
|
+
|
|
bufferedConnection.size = 0
|
|
bufferedConnection.size = 0
|
|
bufferedConnection.data = {}
|
|
bufferedConnection.data = {}
|
|
local status, err = coroutine.resume(connectionThread, fileServeFunction, bufferedConnection, req, args)
|
|
local status, err = coroutine.resume(connectionThread, fileServeFunction, bufferedConnection, req, args)
|
|
if not status then
|
|
if not status then
|
|
- print(err)
|
|
|
|
|
|
+ print("Error: ", err)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
@@ -62,9 +66,9 @@ return function (port)
|
|
local method = req.method
|
|
local method = req.method
|
|
local uri = req.uri
|
|
local uri = req.uri
|
|
local fileServeFunction = nil
|
|
local fileServeFunction = nil
|
|
-
|
|
|
|
- print("Method: " .. method);
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ --print("Method: " .. method);
|
|
|
|
+
|
|
if #(uri.file) > 32 then
|
|
if #(uri.file) > 32 then
|
|
-- nodemcu-firmware cannot handle long filenames.
|
|
-- nodemcu-firmware cannot handle long filenames.
|
|
uri.args = {code = 400, errorString = "Bad Request"}
|
|
uri.args = {code = 400, errorString = "Bad Request"}
|
|
@@ -72,17 +76,17 @@ return function (port)
|
|
else
|
|
else
|
|
local fileExists = file.open(uri.file, "r")
|
|
local fileExists = file.open(uri.file, "r")
|
|
file.close()
|
|
file.close()
|
|
-
|
|
|
|
|
|
+
|
|
if not fileExists then
|
|
if not fileExists then
|
|
- -- gzip check
|
|
|
|
- fileExists = file.open(uri.file .. ".gz", "r")
|
|
|
|
- file.close()
|
|
|
|
-
|
|
|
|
- if fileExists then
|
|
|
|
- print("gzip variant exists, serving that one")
|
|
|
|
- uri.file = uri.file .. ".gz"
|
|
|
|
- uri.isGzipped = true
|
|
|
|
- end
|
|
|
|
|
|
+ -- gzip check
|
|
|
|
+ fileExists = file.open(uri.file .. ".gz", "r")
|
|
|
|
+ file.close()
|
|
|
|
+
|
|
|
|
+ if fileExists then
|
|
|
|
+ print("gzip variant exists, serving that one")
|
|
|
|
+ uri.file = uri.file .. ".gz"
|
|
|
|
+ uri.isGzipped = true
|
|
|
|
+ end
|
|
end
|
|
end
|
|
|
|
|
|
if not fileExists then
|
|
if not fileExists then
|
|
@@ -92,11 +96,11 @@ return function (port)
|
|
fileServeFunction = dofile(uri.file)
|
|
fileServeFunction = dofile(uri.file)
|
|
else
|
|
else
|
|
if allowStatic[method] then
|
|
if allowStatic[method] then
|
|
- uri.args = {file = uri.file, ext = uri.ext, gzipped = uri.isGzipped}
|
|
|
|
- fileServeFunction = dofile("httpserver-static.lc")
|
|
|
|
|
|
+ uri.args = {file = uri.file, ext = uri.ext, isGzipped = uri.isGzipped}
|
|
|
|
+ fileServeFunction = dofile("httpserver-static.lc")
|
|
else
|
|
else
|
|
- uri.args = {code = 405, errorString = "Method not supported"}
|
|
|
|
- fileServeFunction = dofile("httpserver-error.lc")
|
|
|
|
|
|
+ uri.args = {code = 405, errorString = "Method not supported"}
|
|
|
|
+ fileServeFunction = dofile("httpserver-error.lc")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
@@ -136,7 +140,7 @@ return function (port)
|
|
local function onSent(connection, payload)
|
|
local function onSent(connection, payload)
|
|
collectgarbage()
|
|
collectgarbage()
|
|
if connectionThread then
|
|
if connectionThread then
|
|
- local connectionThreadStatus = coroutine.status(connectionThread)
|
|
|
|
|
|
+ local connectionThreadStatus = coroutine.status(connectionThread)
|
|
if connectionThreadStatus == "suspended" then
|
|
if connectionThreadStatus == "suspended" then
|
|
-- Not finished sending file, resume.
|
|
-- Not finished sending file, resume.
|
|
local status, err = coroutine.resume(connectionThread)
|
|
local status, err = coroutine.resume(connectionThread)
|
|
@@ -158,7 +162,7 @@ return function (port)
|
|
connectionThread = nil
|
|
connectionThread = nil
|
|
collectgarbage()
|
|
collectgarbage()
|
|
end
|
|
end
|
|
- end)
|
|
|
|
|
|
+ end)
|
|
|
|
|
|
end
|
|
end
|
|
)
|
|
)
|