Skip to content
Permalink
Browse files
Update
  • Loading branch information
PixelToast committed Sep 16, 2013
1 parent 82619b3 commit 90e3b92
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 47 deletions.
@@ -3,14 +3,11 @@
-- By PixelToast
--
-- TODO:
-- retry on http_failure
-- clean up
-- comments
-- multiple host support
-- multiple channel support
-- not using eroutine
-- check if connection was sucessful
-- random number in (what will be) timeout to make sure it does not receive multiple times at once
------------------------------------------------

------------------------------------------------
@@ -116,6 +113,7 @@ local function unserialize(t)
end
local host
local id
local uid
function send(sid,data)
http.request(host.."send",serialize(id,sid,data))
end
@@ -137,30 +135,53 @@ function close()
host,id=nil
end
local function receive()
http.request(host.."receive",serialize(id))
http.request(host.."receive?"..uid,serialize(id))
end
function setHost(h,p,i)
host="http://"..tostring(h or "localhost")..":"..tostring(p or 1337).."/"
id=tostring(i or os.getComputerID())
receive()
close()
local shost="http://"..tostring(h or "localhost")..":"..tostring(p or 1337).."/"
local sid=tostring(i or os.getComputerID())
local s=http.get(shost.."ping")
if s then
local t=unserialize(s.readAll())
if t then
if t[1]=="pong" and t[2] then
host=shost
id=sid
uid=t[2]
receive()
return true
end
end
end
close()
return false
end
eroutine.add(function(...)
local p={...}
if p[1]=="http_success" then
if string.sub(p[2],1,#host)==host then
eroutine.eatEvent()
local text=p[3].readAll()
if text~="" and not receiveing then
local t=unserialize(text)
if t[1] then
os.queueEvent("httpnet_message",t[1],t[2])
receive()
if host then
if string.sub(p[2],1,#host)==host then
eroutine.eatEvent()
local text=p[3].readAll()
if text~="" then
local t=unserialize(text)
if t[1]==uid then
if t[2]=="msg" then
os.queueEvent("httpnet_message",t[3],t[4])
receive()
elseif t[2]=="timeout" then
receive()
end
end
end
end
end
elseif p[1]=="http_failure" then
if string.sub(p[2],1,#host)==host then
eroutine.eatEvent()
if host then
if string.sub(p[2],1,#host)==host then
eroutine.eatEvent()
end
end
end
end,"httpnet")
@@ -9,8 +9,8 @@
-- comments
-- moar config options
-- error checking
-- timeouts
-- clean up a bit
-- add a reconnect buffer so messages arent lost in the short time the client is offline
------------------------------------------------

------------------------------------------------
@@ -40,6 +40,13 @@ local function getmax(tbl)
end
return mx
end
local function genuid()
local o=""
for l1=1,16 do
o=o..string.format("%X",math.random(1,15))
end
return o
end
local function serialize(...)
local t={...}
local out=""
@@ -107,60 +114,88 @@ local function close(cl)
cli[cl.i]=nil
end
local function serve(cl,dat)
cl.s:send("HTTP/1.1 337 Potato\r\nContent-Length: "..dat:len().."\r\n\r\n"..dat)
cl.s:send("HTTP/1.1 337 H4X\r\nContent-Length: "..dat:len().."\r\n\r\n"..dat) -- nothing to see here
close(cl)
end
local function req(cl,s)
local t=unserialize(s)
if cl.postlen and not t then
close(cl)
else
if cl.uri=="ping" then
serve(cl,serialize("pong",genuid()))
elseif cl.uri=="send" and t[3] then
print("'"..serialize(t[1]).."' is sending '"..serialize(t[3]).."' to '"..serialize(t[2]).."'")
for k,v in pairs(queue) do
if v.id==t[2] then
serve(v,serialize(v.uid,"msg",t[1],t[3]))
queue[k]=nil
end
end
serve(cl,"")
elseif cl.uri=="receive" and t[1] then
if not cl.uid then
print("Bad request "..cl.id)
else
print("'"..serialize(t[1]).."' is receiving")
cl.id=t[1]
table.insert(queue,cl)
end
else
close(cl)
end
end
end
local ltime=os.clock()
while true do
local s=sv:accept()
while s do
s:settimeout(0)
local a=1
while true do
if not cli[a] then
cli[a]={s=s,head={},i=a}
cli[a]={s=s,head={},i=a,dt=0}
break
end
a=a+1
end
s=sv:accept()
end
local cdt=os.clock()-ltime
for i=1,getmax(cli) do
local cl=cli[i]
if cl then
cl.dt=cl.dt+cdt
if cl.dt>30 then
for k,v in pairs(queue) do
if v then
if v.s==cl then
queue[k]=nil
end
end
end
print("'"..cl.id.."' timed out")
serve(cl,serialize(cl.uid,"timeout"))
end
local s,e=cl.s:receive(0)
if e=="closed" and not s then
cl.s:close()
cli[i]=nil
close(cl)
else
local s,e=cl.s:receive(cl.postlen)
while s do
if cl.postlen then
local t=unserialize(s)
if not t then
close(cl)
else
if cl.uri=="send" and t[3] then
print("'"..serialize(t[1]).."' is sending '"..serialize(t[3]).."' to '"..serialize(t[2]).."'")
for k,v in pairs(queue) do
if v.id==t[2] then
serve(v,serialize(t[1],t[3]))
queue[k]=nil
end
end
serve(cl,"")
elseif cl.uri=="receive" and t[1] then
print("'"..serialize(t[1]).."' is receiving")
cl.id=t[1]
table.insert(queue,cl)
else
close(cl)
end
end
req(cl,s)
elseif s=="" then
local pg,d=cl.head[1]:match("^(.-) (.-) HTTP/1.1$")
if pg=="POST" and not cl.postlen then
cl.uri=d:sub(2)
cl.postlen=tonumber(prochead(cl)["Content-Length:"])
if not cl.postlen then
cl.uri=d:sub(2):gsub("(%?(.+))$","")
cl.uid=d:sub(2):match("%?(.+)$")
cl.rid=d
if pg=="POST" then
cl.postlen=tonumber(prochead(cl)["Content-Length:"])
else
req(cl,s)
end
else
close(cl)
end
@@ -176,9 +211,10 @@ while true do
end
end
end
ltime=os.clock()
local clt={sv}
for k,v in pairs(cli) do
table.insert(clt,v.s)
end
socket.select(clt,nil)
socket.select(clt,nil,10)
end

0 comments on commit 90e3b92

Please sign in to comment.