Browse Source

Add missing websocket and corresponding patch

Godzil 6 years ago
parent
commit
c4634a954c
4 changed files with 147 additions and 126 deletions
  1. 9 3
      Makefile
  2. 17 0
      patchs/httpserver_httpserver.patch
  3. 3 3
      src/init.lua
  4. 118 120
      src/webide-websocket.lua

+ 9 - 3
Makefile

@@ -43,7 +43,7 @@ httpserver/Makefile:
 	@git submodule update
 	
 # Patch httpserver makefile for upload and init
-patchserver: httpserver/makefile.patched httpserver/init.patched
+patchserver: httpserver/makefile.patched httpserver/init.patched httpserver/httpserver.patched
 
 httpserver/makefile.patched: patchs/httpserver_makefile.patch httpserver/Makefile
 	@echo Patching httpserver makefile...
@@ -52,11 +52,17 @@ httpserver/makefile.patched: patchs/httpserver_makefile.patch httpserver/Makefil
 	@touch ${@}
 	
 httpserver/init.patched: patchs/httpserver_init.patch httpserver/httpserver-compile.lua
-	@echo Patching httpserver scripts...
+	@echo Patching httpserver compile scripts...
 	@if [ -e $@ ]; then patch -p1 -R < $?; fi
 	@patch -p1 < $?
 	@touch ${@}
-	
+
+httpserver/httpserver.patched: patchs/httpserver_httpserver.patch httpserver/httpserver.lua
+	@echo Patching httpserver.lua ...
+	@if [ -e $@ ]; then patch -p1 -R < $?; fi
+	@patch -p1 < $?
+	@touch ${@}
+
 httpserver/httpserver-start.lua:
 	@echo Replace httpserver init.lua by ${@}
 	@mv httpserver/init.lua ${@}

+ 17 - 0
patchs/httpserver_httpserver.patch

@@ -0,0 +1,17 @@
+diff --git a/httpserver.lua b/httpserver.lua
+index a244335..00d5934 100644
+--- a/httpserver.lua
++++ b/httpserver.lua
+@@ -96,6 +96,12 @@ return function (port)
+ 
+          local function onReceive(connection, payload)
+             collectgarbage()
++
++            -- Check websocket ASAP
++            if payload:find("Upgrade: websocket") then
++                return dofile('webide-websocket.lc')(connection, payload)
++            end
++
+             local conf = dofile("httpserver-conf.lc")
+             local auth
+             local user = "Anonymous"

+ 3 - 3
src/init.lua

@@ -1,8 +1,8 @@
 -- Compile webide files
-if file.exists("httpserver-compile.lc") then
-   dofile("httpserver-compile.lc")
+if file.exists("webide-compile.lc") then
+   dofile("webide-compile.lc")
 else
-   dofile("httpserver-compile.lua")
+   dofile("webide-compile.lua")
 end
 
 if file.exists("startup.lua") then

+ 118 - 120
src/webide-websocket.lua

@@ -1,135 +1,133 @@
 --rewrite from https://github.com/creationix/nodemcu-webide
 
 local function decode(chunk)
-  if #chunk < 2 then return end
-  local second = string.byte(chunk, 2)
-  local len = bit.band(second, 0x7f)
-  local offset
-  if len == 126 then
-    if #chunk < 4 then return end
-    len = bit.bor(
-      bit.lshift(string.byte(chunk, 3), 8),
-      string.byte(chunk, 4))
-    offset = 4
-  elseif len == 127 then
-    if #chunk < 10 then return end
-    len = bit.bor(
+   if #chunk < 2 then return end
+   local second = string.byte(chunk, 2)
+   local len = bit.band(second, 0x7f)
+   local offset
+
+   if len == 126 then
+      if #chunk < 4 then return end
+
+      len = bit.bor(bit.lshift(string.byte(chunk, 3), 8), string.byte(chunk, 4))
+      offset = 4
+
+   elseif len == 127 then
+
+      if #chunk < 10 then return end
+
       -- Ignore lengths longer than 32bit
-      bit.lshift(string.byte(chunk, 7), 24),
-      bit.lshift(string.byte(chunk, 8), 16),
-      bit.lshift(string.byte(chunk, 9), 8),
-      string.byte(chunk, 10))
-    offset = 10
-  else
-    offset = 2
-  end
-  local mask = bit.band(second, 0x80) > 0
-  if mask then
-    offset = offset + 4
-  end
-  if #chunk < offset + len then return end
-
-  local first = string.byte(chunk, 1)
-  local payload = string.sub(chunk, offset + 1, offset + len)
-  assert(#payload == len, "Length mismatch")
-  if mask then
-    payload = crypto.mask(payload, string.sub(chunk, offset - 3, offset))
-  end
-  local extra = string.sub(chunk, offset + len + 1)
-  local opcode = bit.band(first, 0xf)
-  return extra, payload, opcode
+      len = bit.bor(bit.lshift(string.byte(chunk, 7), 24), bit.lshift(string.byte(chunk, 8), 16),
+                    bit.lshift(string.byte(chunk, 9), 8), string.byte(chunk, 10))
+      offset = 10
+   else
+      offset = 2
+   end
+
+   local mask = bit.band(second, 0x80) > 0
+   if mask then
+      offset = offset + 4
+   end
+
+   if #chunk < offset + len then return end
+
+   local first = string.byte(chunk, 1)
+   local payload = string.sub(chunk, offset + 1, offset + len)
+   assert(#payload == len, "Length mismatch")
+   if mask then
+      payload = crypto.mask(payload, string.sub(chunk, offset - 3, offset))
+   end
+   local extra = string.sub(chunk, offset + len + 1)
+   local opcode = bit.band(first, 0xf)
+
+   return extra, payload, opcode
 end
 
 local function encode(payload, opcode)
-  opcode = opcode or 2
-  assert(type(opcode) == "number", "opcode must be number")
-  assert(type(payload) == "string", "payload must be string")
-  local len = #payload
-  local head = string.char(
-    bit.bor(0x80, opcode),
-    bit.bor(len < 126 and len or len < 0x10000 and 126 or 127)
-  )
-  if len >= 0x10000 then
-    head = head .. string.char(
-    0,0,0,0, -- 32 bit length is plenty, assume zero for rest
-    bit.band(bit.rshift(len, 24), 0xff),
-    bit.band(bit.rshift(len, 16), 0xff),
-    bit.band(bit.rshift(len, 8), 0xff),
-    bit.band(len, 0xff)
-  )
-  elseif len >= 126 then
-    head = head .. string.char(bit.band(bit.rshift(len, 8), 0xff), bit.band(len, 0xff))
-  end
-  return head .. payload
+   opcode = opcode or 2
+   assert(type(opcode) == "number", "opcode must be number")
+   assert(type(payload) == "string", "payload must be string")
+   local len = #payload
+   local head = string.char(bit.bor(0x80, opcode), bit.bor(len < 126 and len or len < 0x10000 and 126 or 127))
+
+   if len >= 0x10000 then
+      -- 32 bit length is plenty, assume zero for rest
+      head = head .. string.char(0, 0, 0, 0, bit.band(bit.rshift(len, 24), 0xff), bit.band(bit.rshift(len, 16), 0xff),
+                                 bit.band(bit.rshift(len, 8), 0xff), bit.band(len, 0xff))
+   elseif len >= 126 then
+      head = head .. string.char(bit.band(bit.rshift(len, 8), 0xff), bit.band(len, 0xff))
+   end
+
+   return head .. payload
 end
 
 local guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
 local function acceptKey(key)
-  return crypto.toBase64(crypto.hash("sha1", key .. guid))
+   return crypto.toBase64(crypto.hash("sha1", key .. guid))
 end
 
-return function (connection, payload)
-  local buffer = false
-  local socket = {}
-  local queue = {}
-  local waiting = false
-  local function onSend()
-    if queue[1] then
-      local data = table.remove(queue, 1)
-      return connection:send(data, onSend)
-    end
-    waiting = false
-  end
-  function socket.send(...)
-    local data = encode(...)
-    if not waiting then
-      waiting = true
-      connection:send(data, onSend)
-    else
-      queue[#queue + 1] = data
-    end
-    collectgarbage()
-    print(node.heap())
-  end
-
-  connection:on("receive", function(_, chunk)
-    if buffer then
-      buffer = buffer .. chunk
-      while true do
-        local extra, payload, opcode = decode(buffer)
-        if not extra then return end
-        buffer = extra
-        socket.onmessage(payload, opcode)
+-- Dispatch function
+return function(connection, payload)
+   local buffer = false
+   local socket = {}
+   local queue = {}
+   local waiting = false
+
+   local function onSend()
+      if queue[1] then
+         local data = table.remove(queue, 1)
+         return connection:send(data, onSend)
+      end
+      waiting = false
+   end
+
+   function socket.send(...)
+      local data = encode(...)
+      if not waiting then
+         waiting = true
+         connection:send(data, onSend)
+      else
+         queue[#queue + 1] = data
+      end
+      collectgarbage()
+      print(node.heap())
+   end
+
+   connection:on("receive", function(_, chunk)
+      if buffer then
+         buffer = buffer .. chunk
+         while true do
+            local extra, payload, opcode = decode(buffer)
+            if not extra then return end
+            buffer = extra
+            socket.onmessage(payload, opcode)
+         end
       end
-    end
-  end)
-
-  connection:on("sent", function(_, _)
-    if socket.onsent ~= nil then
-      socket.onsent()
-    end
-  end)
-
-  connection:on("disconnection", function(_, _)
-    if socket.onclose ~= nil then
-      socket.onclose()
-    end
-  end)
-
-  local req = dofile("httpserver-request.lc")(payload)
-  local key = payload:match("Sec%-WebSocket%-Key: ([A-Za-z0-9+/=]+)")
-  local fileExists = file.open(req.uri.file, "r")
-  file.close()
-  if req.method == "GET" and key and fileExists then
-    connection:send(
-      "HTTP/1.1 101 Switching Protocols\r\n" ..
-      "Upgrade: websocket\r\nConnection: Upgrade\r\n" ..
-      "Sec-WebSocket-Accept: " .. acceptKey(key) .. "\r\n\r\n",
-      function () dofile(req.uri.file)(socket) end)
-    buffer = ""
-  else
-    connection:send(
-      "HTTP/1.1 404 Not Found\r\nConnection: Close\r\n\r\n",
-      connection.close)
-  end
+   end)
+
+   connection:on("sent", function(_, _)
+      if socket.onsent ~= nil then
+         socket.onsent()
+      end
+   end)
+
+   connection:on("disconnection", function(_, _)
+      if socket.onclose ~= nil then
+         socket.onclose()
+      end
+   end)
+
+   local req = dofile("httpserver-request.lc")(payload)
+   local key = payload:match("Sec%-WebSocket%-Key: ([A-Za-z0-9+/=]+)")
+   local fileExists = file.open(req.uri.file, "r")
+   file.close()
+   if req.method == "GET" and key and fileExists then
+      connection:send("HTTP/1.1 101 Switching Protocols\r\n" ..
+                      "Upgrade: websocket\r\nConnection: Upgrade\r\n" ..
+                      "Sec-WebSocket-Accept: " .. acceptKey(key) .. "\r\n\r\n",
+                      function() dofile(req.uri.file)(socket) end)
+      buffer = ""
+   else
+      connection:send("HTTP/1.1 404 Not Found\r\nConnection: Close\r\n\r\n", connection.close)
+   end
 end