forked from marcoskirsch/nodemcu-httpserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttpserver-connection.lua
67 lines (59 loc) · 2.44 KB
/
httpserver-connection.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
-- 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