From 2e205d131a5a75654496f41fd05be8c090c5ab72 Mon Sep 17 00:00:00 2001 From: Fractal147 <35138372+Fractal147@users.noreply.github.com> Date: Fri, 5 Jan 2018 14:40:19 +0000 Subject: [PATCH 1/3] Made bufferedConnection local bufferedConnection was global and didn't have to be. Part of issue #113 --- httpserver-connection.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpserver-connection.lua b/httpserver-connection.lua index 7026482..52aee69 100644 --- a/httpserver-connection.lua +++ b/httpserver-connection.lua @@ -5,7 +5,7 @@ -- flush() and for closing the connection. -- Author: Philip Gladstone, Marcos Kirsch -BufferedConnection = {} +local BufferedConnection = {} -- parameter is the nodemcu-firmware connection function BufferedConnection:new(connection) From 501fc83c9d7890d8ddd01ec20720901f919b8388 Mon Sep 17 00:00:00 2001 From: Fractal147 <35138372+Fractal147@users.noreply.github.com> Date: Fri, 5 Jan 2018 22:48:13 +0000 Subject: [PATCH 2/3] Directly send chunks of static file. This is a memory optimisation. Directly send 1024 byte chunks of static file to the connection socket, without buffering. Cost is that it never sends 1400 byte packets, but plus is that it never has to store up to 1399 bytes extra in memory. Overall results in less memory usage for static file serving. --- httpserver-static.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/httpserver-static.lua b/httpserver-static.lua index 10f2e70..dff6105 100644 --- a/httpserver-static.lua +++ b/httpserver-static.lua @@ -4,6 +4,8 @@ return function (connection, req, args) dofile("httpserver-header.lc")(connection, 200, args.ext, args.isGzipped) + connection:flush() + coroutine.yield() -- Send file in little chunks local bytesRemaining = file.list()[args.file] -- Chunks larger than 1024 don't work. @@ -13,9 +15,9 @@ return function (connection, req, args) while bytesRemaining > 0 do local bytesToRead = 0 if bytesRemaining > chunkSize then bytesToRead = chunkSize else bytesToRead = bytesRemaining end - local chunk = fileHandle:read(bytesToRead) - connection:send(chunk) - bytesRemaining = bytesRemaining - #chunk + connection.connection:send(fileHandle:read(bytesToRead)) + coroutine.yield() + bytesRemaining = bytesRemaining - bytesToRead --print(args.file .. ": Sent "..#chunk.. " bytes, " .. bytesRemaining .. " to go.") chunk = nil collectgarbage() From a4ecbba0a511508a56ad39e9a4ad5ff1bf14646e Mon Sep 17 00:00:00 2001 From: Fractal147 <35138372+Fractal147@users.noreply.github.com> Date: Fri, 5 Jan 2018 22:49:54 +0000 Subject: [PATCH 3/3] Dropped req table when unneeded for httpserver-static.lua, and httpserver-error.lua, req is never called or needed, so can be set to nil, before it is passed on. This saves memory, particularly for static files, since it never needs to store the full request header. Req is only passed on to scripts. --- httpserver.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/httpserver.lua b/httpserver.lua index 65b4bc8..54715c4 100644 --- a/httpserver.lua +++ b/httpserver.lua @@ -60,6 +60,7 @@ return function (port) -- nodemcu-firmware cannot handle long filenames. uri.args = {code = 400, errorString = "Bad Request", logFunction = log} fileServeFunction = dofile("httpserver-error.lc") + req=nil else local fileExists = false @@ -79,15 +80,18 @@ return function (port) if not fileExists then uri.args = {code = 404, errorString = "Not Found", logFunction = log} fileServeFunction = dofile("httpserver-error.lc") + req=nil elseif uri.isScript then fileServeFunction = dofile(uri.file) else if allowStatic[method] then uri.args = {file = uri.file, ext = uri.ext, isGzipped = uri.isGzipped} fileServeFunction = dofile("httpserver-static.lc") + req=nil else uri.args = {code = 405, errorString = "Method not supported", logFunction = log} fileServeFunction = dofile("httpserver-error.lc") + req=nil end end end