local outfile; local beginSaving = false; local done = false; local totalReceived = 0; local contentLength = -1; local socket = network.socket("tcp"); local progressBarWidth = 20; local progressFmt = "\rDownloading: %3d%%\t[%-" .. progressBarWidth .. "s]"; function macro.init() print("Socket:", socket); local host = "solarstrike.net"; local connected,err = socket:connect(host, 80); print("Connected:", connected, err); local proto = "http"; local file = "/project/download/14"; local get = sprintf("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", file, host); print("Send:", socket:send(get)); outfile = io.open("download.zip", "wb"); assert(outfile); end function macro.main() if( done ) then printf("Total received bytes: %d\n\n", totalReceived); outfile:close(); return false; else return true; -- Keep on waiting until we're done. end end function macro.event(e, ...) if( e == "socketreceived" ) then -- For every packet we receive... local sockId,data = ...; if( not beginSaving ) then -- Parse needed header content and make use of it. contentLength = data:match("Content%-Length:%s+(%d+)"); if( contentLength ) then contentLength = tonumber(contentLength); printf("Expected file size: %d\n", contentLength); end -- A \r\n\r\n signals the start of the content, so we'll save anything past it. local foundPos = data:find("\r\n\r\n"); if( foundPos ) then print("Data:", string.sub(data, 0, foundPos)); print("Begin saving\n\n"); data = string.sub(data, foundPos + string.len("\r\n\r\n")); beginSaving = true; printf(progressFmt, 0, ''); -- Start displaying our progress bar (blank right now) end end if( beginSaving ) then -- We've received another piece of the file, so save it and update progress. outfile:write(data); totalReceived = totalReceived + string.len(data); local progressRatio = totalReceived / contentLength; local goodCount = 0; if( progressRatio > 0 ) then goodCount = math.floor(progressRatio * progressBarWidth); else goodCount = 0; end printf(progressFmt, math.floor(progressRatio * 100), string.rep('=', goodCount)); if( totalReceived == contentLength ) then print("\n\nSuccessfully completed file transfer."); socket:close(); done = true; end end end -- Check for errors or disconnection if( e == "socketdisconnected" ) then print("\n\nSocket closed.", ...); done = true; end if( e == "socketerror" ) then print("\n\nSocket error", ...); done = true; end end