diff --git a/httpserver-connection.lua b/httpserver-connection.lua index 329e603..75d7c75 100644 --- a/httpserver-connection.lua +++ b/httpserver-connection.lua @@ -1,67 +1,59 @@ --- httpserver-connection --- Part of nodemcu-httpserver, provides a buffered connection object that can handle multiple --- consecutive send() calls, and buffers small payloads to send once they get big. --- For this to work, it must be used from a coroutine and owner is responsible for the final --- flush() and for closing the connection. --- Author: Philip Gladstone, Marcos Kirsch - -BufferedConnection = {} - --- parameter is the nodemcu-firmware connection -function BufferedConnection:new(connection) - local newInstance = {} - newInstance.connection = connection - newInstance.size = 0 - newInstance.data = {} - - function newInstance:flush() - if self.size > 0 then - self.connection:send(table.concat(self.data, "")) - self.data = {} - self.size = 0 - return true - end - return false - end - - function newInstance:send(payload) - local flushthreshold = 1400 - - local newsize = self.size + payload:len() - while newsize > flushthreshold do - --STEP1: cut out piece from payload to complete threshold bytes in table - local piecesize = flushthreshold - self.size - local piece = payload:sub(1, piecesize) - payload = payload:sub(piecesize + 1, -1) - --STEP2: insert piece into table - table.insert(self.data, piece) - self.size = self.size + piecesize --size should be same as flushthreshold - --STEP3: flush entire table - if self:flush() then - coroutine.yield() - end - --at this point, size should be 0, because the table was just flushed - newsize = self.size + payload:len() - end - - --at this point, whatever is left in payload should be <= flushthreshold - local plen = payload:len() - if plen == flushthreshold then - --case 1: what is left in payload is exactly flushthreshold bytes (boundary case), so flush it - table.insert(self.data, payload) - self.size = self.size + plen - if self:flush() then - coroutine.yield() - end - elseif payload:len() then - --case 2: what is left in payload is less than flushthreshold, so just leave it in the table - table.insert(self.data, payload) - self.size = self.size + plen - --else, case 3: nothing left in payload, so do nothing - end - end - - return newInstance -end - -return BufferedConnection +-- httpserver-connection +-- Part of nodemcu-httpserver, provides a buffered connection object that can handle multiple +-- consecutive send() calls, and buffers small payloads to send once they get big. +-- For this to work, it must be used from a coroutine and owner is responsible for the final +-- flush() and for closing the connection. +-- Author: Philip Gladstone, Marcos Kirsch + +BufferedConnection = {} + +-- parameter is the nodemcu-firmware connection +function BufferedConnection:new(connection) + local newInstance = {} + newInstance.connection = connection + newInstance.size = 0 + newInstance.data = {} + + -- Returns true if there was any data to be sent. + function newInstance:flush() + if self.size > 0 then + self.connection:send(table.concat(self.data, "")) + self.data = {} + self.size = 0 + return true + end + return false + end + + function newInstance:send(payload) + local flushThreshold = 1400 + local newSize = self.size + payload:len() + while newSize >= flushThreshold do + --STEP1: cut out piece from payload to complete threshold bytes in table + local pieceSize = flushThreshold - self.size + local piece = payload:sub(1, pieceSize) + payload = payload:sub(pieceSize + 1, -1) + --STEP2: insert piece into table + table.insert(self.data, piece) + piece = nil + self.size = self.size + pieceSize --size should be same as flushThreshold + --STEP3: flush entire table + if self:flush() then + coroutine.yield() + end + --at this point, size should be 0, because the table was just flushed + newSize = self.size + payload:len() + end + + --at this point, whatever is left in payload should be < flushThreshold + if payload:len() ~= 0 then + --leave remaining data in the table + table.insert(self.data, payload) + self.size = self.size + payload:len() + end + end + return newInstance + +end + +return BufferedConnection