diff --git a/http/index.html b/http/index.html index 76e2922..8e033d6 100644 --- a/http/index.html +++ b/http/index.html @@ -29,6 +29,7 @@
  • NodeMCU info: Shows some basic NodeMCU(Lua)
  • List all server files: Displays a list of all the server files. (Lua)
  • Foo: A file that doesn't exist. Should error (404 error)
  • +
  • Upload: update, remove, list files on the server.
  • diff --git a/http/upload.full.html b/http/upload.full.html new file mode 100644 index 0000000..1b1a47b --- /dev/null +++ b/http/upload.full.html @@ -0,0 +1,568 @@ + + + + + + + +
    +
    +
    + Drop Here + + Browse + Upload + +
    + + +
    Files on device:
    + +
    +
    + + diff --git a/http/upload.html.gz b/http/upload.html.gz new file mode 100644 index 0000000..3dc89bf Binary files /dev/null and b/http/upload.html.gz differ diff --git a/http/upload.lua b/http/upload.lua new file mode 100644 index 0000000..acf12bf --- /dev/null +++ b/http/upload.lua @@ -0,0 +1,127 @@ +return function (connection, req, args) + dofile("httpserver-header.lc")(connection, 200, 'application/json') + connection:send('{') + + local mbOffset = nil + local mbLen = nil + local mbData = nil + local mbCmd = nil + local mbFilename = nil + local fieldsCount = 0 + local fileSize = 0 + local i = 0 + local binaryData = '' + local currentByte = nil + + for name, value in pairs(args) do + if (name == "offset") then + mbOffset = tonumber(value, 10) + + fieldsCount = fieldsCount + 1 + end + if (name == "len") then + mbLen = tonumber(value, 10) + + fieldsCount = fieldsCount + 1 + end + if (name == "data") then + mbData = value + + fieldsCount = fieldsCount + 1 + end + if (name == "filename") then + mbFilename = value + + fieldsCount = fieldsCount + 1 + end + if (name == "filesize") then + fileSize = tonumber(value, 10) + + fieldsCount = fieldsCount + 1 + end + if (name == "cmd") then + mbCmd = value + + fieldsCount = fieldsCount + 1 + end + end + + if (mbCmd == 'upload') then + if (fieldsCount > 5) then + if (mbFilename ~= 'upload.lua') then + connection:send('"offset":"' .. mbOffset .. '",') + connection:send('"len":"' .. mbLen .. '",') + connection:send('"filename":"' .. mbFilename .. '"') + + mbFilename = 'http/' .. mbFilename + + for i=1,string.len(mbData),2 do + currentByte = tonumber(string.sub(mbData, i, i + 1), 16) + binaryData = binaryData .. string.char(currentByte) + end + + if (mbOffset > 0) then + file.open(mbFilename .. '.dnl','a+') + else + file.remove(mbFilename .. '.dnl') + file.open(mbFilename .. '.dnl','w+') + end + file.seek("set", mbOffset) + file.write(binaryData) + file.close() + + binaryData = nil + + if (fileSize == mbLen + mbOffset) then + file.remove(mbFilename) + file.rename(mbFilename .. '.dnl', mbFilename) + file.remove(mbFilename .. '.dnl') + + if (string.sub(mbFilename, -4) == '.lua') then + file.remove(string.sub(mbFilename, 0, -3) .. "lc") + node.compile(mbFilename) + file.remove(mbFilename) + end + end + end + end + elseif (mbCmd == 'list') then + local remaining, used, total=file.fsinfo() + + local headerExist = 0 + + connection:send('"files":{') + + for name, size in pairs(file.list()) do + local isHttpFile = string.match(name, "(http/)") ~= nil + + if isHttpFile then + if (headerExist > 0) then + connection:send(',') + end + + local url = string.match(name, ".*/(.*)") + + connection:send('"' .. url .. '":"' .. size .. '"') + + headerExist = 1 + end + end + + connection:send('},') + + connection:send('"total":"' .. total .. '",') + connection:send('"used":"' .. used .. '",') + connection:send('"free":"' .. remaining .. '"') + elseif (mbCmd == 'remove') then + if (fieldsCount > 1) then + if (mbFilename ~= 'upload.lua') and (mbFilename ~= 'upload.lc') and (mbFilename ~= 'upload.html.gz') then + file.remove('http/' .. mbFilename) + end + end + end + + connection:send('}') + collectgarbage() +end + diff --git a/httpserver-header.lua b/httpserver-header.lua index 3010492..3b69cd3 100644 --- a/httpserver-header.lua +++ b/httpserver-header.lua @@ -2,10 +2,10 @@ -- Part of nodemcu-httpserver, knows how to send an HTTP header. -- Author: Marcos Kirsch -return function (connection, code, extension, isGzipped) +return function(connection, code, extension, isGzipped) local function getHTTPStatusString(code) - local codez = {[200]="OK", [400]="Bad Request", [404]="Not Found",} + local codez = { [200] = "OK", [400] = "Bad Request", [404] = "Not Found", [500] = "Internal Server Error", } local myResult = codez[code] -- enforce returning valid http codes all the way throughout? if myResult then return myResult else return "Not Implemented" end @@ -25,6 +25,5 @@ return function (connection, code, extension, isGzipped) connection:send("Cache-Control: private, max-age=2592000\r\nContent-Encoding: gzip\r\n") end connection:send("Connection: close\r\n\r\n") - end