Browse Source

Merge pull request #54 from devyte/master

httpserver-connection: implement fragmentation logic
Marcos 8 years ago
parent
commit
9bd12123b0
1 changed files with 32 additions and 14 deletions
  1. 32 14
      httpserver-connection.lua

+ 32 - 14
httpserver-connection.lua

@@ -25,21 +25,39 @@ function BufferedConnection:new(connection)
    end
 
    function newInstance:send(payload)
-      local l = payload:len()
-      if l + self.size > 1024 then
-         -- Send what we have buffered so far, not including payload.
-         if self:flush() then
-            coroutine.yield()
-         end
+      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
-      if l > 768 then
-         -- Payload is big. Send it now rather than buffering it for later.
-         self.connection:send(payload)
-         coroutine.yield()
-      else
-         -- Payload is small. Save off payload for later sending.
-         table.insert(self.data, payload)
-         self.size = self.size + l
+            
+      --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