nodemcu-firmware: NodeMCU webserver cant serve big files (about 4Kb's)
to repro use the firmware nnodemcu_20160126.bin upload the code below. Connect your browser to the esp8266. You will see your all your files listed. Click on the small ones, they show up in the browser fine. click on any file bigger than 3Kb… you get it incomplete
I recommend giving a try to this script is really cool.
--[[
XChip's NodeMCU IDE
Edit NodeMCU files using your webbrowser.
]]--
rnrn=0
Status = 0
DataToGet = 0
method=""
url=""
vars=""
function Sendfile(conn, filename)
if file.open(filename, "r") then
repeat
local line=file.read(128)
if line then conn:send(line)end
until not line
file.close()
end
end
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
if Status==0 then
_, _, method, url, vars = string.find(payload, "([A-Z]+) /([^?]*)%??(.*) HTTP")
print(":",method, url, vars)
end
if method=="POST" then
if Status==0 then
--print("status", Status)
_,_,DataToGet, payload = string.find(payload, "Content%-Length: (%d+)(.+)")
if DataToGet~=nil then
DataToGet = tonumber(DataToGet)
--print(DataToGet)
rnrn=1
Status = 1
else
print("Can't get length")
end
end
-- find /r/n/r/n
if Status==1 then
--print("status", Status)
local payloadlen = string.len(payload)
local mark = "\r\n\r\n"
local i
for i=1, payloadlen do
if string.byte(mark, rnrn) == string.byte(payload, i) then
rnrn=rnrn+1
if rnrn==5 then
payload = string.sub(payload, i+1,payloadlen)
file.open(url, "w")
file.close()
Status=2
break
end
else
rnrn=1
end
end
if Status==1 then
return
end
end
if Status==2 then
--print("status", Status)
if payload~=nil then
DataToGet=DataToGet-string.len(payload)
--print("DataToGet:", DataToGet, "payload len:", string.len(payload))
file.open(url, "a+")
file.write(payload)
file.close()
else
conn:send("HTTP/1.1 200 OK\r\n\r\nERROR")
Status=0
end
if DataToGet==0 then
conn:send("HTTP/1.1 200 OK\r\n\r\nOK")
if vars=="run" then
conn:send("<br>Result:<verbatim>")
local st, result=pcall(dofile, url)
conn:send(tostring(result))
conn:send("</verbatim>")
end
Status=0
end
end
return
end
if url == "favicon.ico" then
conn:send("HTTP/1.1 404 file not found")
return
end
conn:send("HTTP/1.1 200 OK\r\n\r\n<html><body>")
conn:send("<h1>NodeMCU IDE</h1>")
if url=="" then
local l = file.list();
for k,v in pairs(l) do
conn:send("<a href='"..k.."'>"..k.."</a>, size:"..v.."<br>")
end
else
conn:send("<script>function tag(t,c) {document.getElementsByTagName(t)[0].innerHTML=c} function upload(f,d){ tag('w','Saving'); var x = new XMLHttpRequest(); x.open('POST', '/'+f, true); x.onreadystatechange=function() { if (x.readyState==4) tag('w',x.responseText); }; x.send(new Blob([document.getElementsByName('t')[0].value], {type: 'text/plain'}));} </script>")
conn:send("<a href='/'>Back to file list</a><br><br><textarea name=t cols=79 rows=17'>")
Sendfile(conn, url)
conn:send("</textarea></br>")
conn:send("<button onclick=\"upload('"..url.."')\">Save</button>")
conn:send("<button onclick=\"upload('"..url.."?run')\">Save+Run</button><br><w></w>")
end
conn:send("</body></html>")
end)
conn:on("sent",function(conn) conn:close() end)
end)
print("listening, free:", node.heap())
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 30 (5 by maintainers)
Ok I fixed the script according to your feedback, now it is working fine. I think the current way nodemcu works is the right one. If you don’t use the callback method then each time the sending buffer is full you should have to block the script until the data is sent.
edit: 02/14 fixed run link