Skip to content
Permalink
Browse files
massive update
  • Loading branch information
PixelToast committed Sep 24, 2013
1 parent a1eac04 commit 3f99326
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 99 deletions.
@@ -1,13 +1,6 @@
------------------------------------------------
-- HTTPNet API
-- By PixelToast
--
-- TODO:
-- clean up
-- comments
-- multiple host support
-- multiple channel support
-- not using eroutine
------------------------------------------------

------------------------------------------------
@@ -111,76 +104,149 @@ local function unserialize(t)
table.insert(out,s)
return out
end
local host
local id
local uid
function send(sid,data)
http.request(host.."send",serialize(id,sid,data))
end
function get(timeout)
local timer
if timeout then
timer=os.startTimer(timeout)
local cl={}
local function receive(self)
local o={}
local cnt=0
for k,v in pairs(self.isOpen) do
cnt=cnt+1
o[cnt]=k
end
while true do
local p={os.pullEvent()}
if p[1]=="httpnet_message" then
return p[2],p[3]
elseif p[1]=="timer" and p[2]==timer then
http.request(self.host.."receive?"..serialize(self.uid),serialize(unpack(o)))
end
local f={
get=function(self,timeout)
local timer
if timeout then
timer=os.startTimer(timeout)
end
while true do
local p={os.pullEvent()}
if p[1]=="httpnet_message" and p[2]==self.uid then
return p[3],p[4],p[5]
elseif p[1]=="timer" and p[2]==timer then
return
end
end
end,
transmit=function(self,sid,id,data)
http.request(self.host.."send",serialize(sid,id,data))
end,
send=function(self,sid,data)
http.request(self.host.."send",serialize(sid,self.id,data))
end,
exit=function(self)
http.request(self.host.."exit?"..serialize(self.uid))
while true do
local p={os.pullEvent("httpnet_exit")}
if p[2]==self.uid then
break
end
end
cl[self.uid]=nil
end,
open=function(self,...)
local t={...}
if #t==0 then
return
end
end
end
function close()
host,id=nil
end
local function receive()
http.request(host.."receive?"..uid,serialize(id))
end
function setHost(h,p,i)
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")
local isOpen=self.isOpen
local channel=self.channel
local req=not next(isOpen)
for k,v in pairs(t) do
v=tostring(v)
if not isOpen[v] then
isOpen[v]=true
end
end
if req then
receive(self)
else
http.request(self.host.."open",serialize(self.uid,...))
end
end,
close=function(self,...)
local t={...}
local isOpen=self.isOpen
local channel=self.channel
for k,v in pairs(t) do
v=tostring(v)
isOpen[v]=nil
end
http.request(self.host.."close",serialize(self.uid,...))
end,
}
function new(h,p,i)
local host="http://"..tostring(h or "localhost")..":"..tostring(p or 1337).."/"
local s=http.get(host.."ping")
local uid
if s then
if s.getResponseCode()~=337 then
return false
end
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
if t[1]~="pong" or not t[2] then
return false
end
uid=t[2]
else
return false
end
else
return false
end
local o={
host=host,
isOpen={},
uid=uid,
id=i,
}
for k,v in pairs(f) do
o[k]=v
end
close()
return false
if i then
o:open(i)
end
cl[uid]=o
return o
end
eroutine.add(function(...)
local p={...}
if p[1]=="http_success" then
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
local h=false
for k,v in pairs(cl) do
if string.sub(p[2],1,#v.host)==v.host then
h=true
break
end
end
if not h then
return
end
eroutine.eatEvent()
local text=p[3].readAll()
if text~="" then
local t=unserialize(text)
if t then
local c=cl[t[1]]
if c then
if t[2]=="msg" then
os.queueEvent("httpnet_message",c.uid,t[3],t[4],t[5])
receive(c)
elseif t[2]=="timeout" then
receive(c)
elseif t[2]=="exit" then
os.queueEvent("httpnet_exit",c.uid)
end
end
end
end
elseif p[1]=="http_failure" then
if host then
if string.sub(p[2],1,#host)==host then
for k,v in pairs(cl) do
if string.sub(p[2],1,#v.host)==v.host then
eroutine.eatEvent()
break
end
end
end
@@ -3,14 +3,6 @@
-- By PixelToast
--
-- Requires lua 5.1 with luasocket.
--
-- TODO:
-- DOS protection
-- comments
-- moar config options
-- error checking
-- clean up a bit
-- add a reconnect buffer so messages arent lost in the short time the client is offline
------------------------------------------------

------------------------------------------------
@@ -19,34 +11,20 @@

local config={
port=1337,

colors=false, -- ANSI colors dont work on windows :/
rainbow=false, -- i got bored
rainbow=false, -- ANSI colors dont work on windows :/
}

------------------------------------------------
-- Server
------------------------------------------------

local colors={
clear="\27[0m",
red="\27[31m",
green="\27[32m",
yellow="\27[33m",
blue="\27[34m",
}
local print=print
if config.rainbow then
local oprint=print
function print(str)
oprint(str:gsub(".",function(s) local r=math.random(0,5) return "\27["..(r+31).."m\27["..(((r+math.random(,5))%6)+41).."m"..s end).."\27[0m")
oprint(str:gsub(".",function(s) local r=math.random(0,5) return "\27["..(r+31).."m\27["..(((r+math.random(1,5))%6)+41).."m"..s end).."\27[0m")
end
end
if not config.colors then
for k,v in pairs(colors) do
colors[k]=""
end
end
local socket=require "socket"
local sv=socket.bind("*",config.port)
sv:settimeout(0)
@@ -64,8 +42,10 @@ local function getmax(tbl)
end
local function genuid()
local o=""
local i
for l1=1,16 do
o=o..string.format("%X",math.random(1,15))
i=math.random(0,15)
o=o..string.char(i+(math.floor(i/10)*7)+48)
end
return o
end
@@ -144,48 +124,79 @@ local function req(cl,s)
if cl.postlen and not t then
close(cl)
else
if cl.uri=="close" then
if cl.uri then
local c=queue[cl.uri]
if c then
serve(c,serialize(c.uid,""))
if cl.uid and (cl.uri=="open" or cl.uri=="close") then
local c=queue[cl.uri]
if c then
if t[1] then
local l=cl.uri=="open" or nil
if l then
print(cl.uid.." opening "..table.concat(t,","))
else
print(cl.uid.." closing "..table.concat(t,","))
end
for k,v in pairs(t) do
c.chan[v]=l
end
if not next(c.chan) then
serve(c,serialize(c.uid))
queue[cl.uri]=nil
end
else
print(cl.uid.." closing all")
for k,v in pairs(c.chan) do
c.chan[k]=nil
end
serve(c,serialize(c.uid))
queue[cl.uri]=nil
end
end
serve(cl,serialize(cl.uid,"close"))
serve(cl,serialize(cl.uid))
end
if cl.uid and cl.uri=="exit" then
print(cl.uid.." is exiting")
local c=queue[cl.uid]
if c then
serve(c,"")
queue[cl.uid]=nil
end
serve(cl,serialize(cl.uid,"exit"))
elseif cl.uri=="ping" then
print("new client")
serve(cl,serialize("pong",genuid()))
elseif cl.uri=="send" and t[3] then
print(colors.green.."'"..serialize(t[1]).."'"..colors.clear.." is sending "..colors.green.."'"..serialize(t[3]).."' to '"..serialize(t[2]).."'"..colors.clear)
print("'"..serialize(t[2]).."' is sending '"..serialize(t[3]).."' to '"..serialize(t[1]).."'")
for k,v in pairs(queue) do
if v.id==t[2] then
serve(v,serialize(v.uid,"msg",t[1],t[3]))
if v.chan[t[1]] then
serve(v,serialize(v.uid,"msg",t[1],t[2],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)
print("bad request "..cl.uid)
else
print(colors.green.."'"..serialize(t[1]).."'"..colors.clear.." is receiving")
cl.id=t[1]
queue[cl.uid]=s
print(cl.uid.." is receiving")
for k,v in pairs(t) do
cl.chan[v]=true
end
queue[cl.uid]=cl
end
else
close(cl)
end
end
end
local ltime=os.time()
print(colors.green.."Server running on port "..config.port..colors.clear)
print("Server running on port "..config.port)
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,dt=0}
cli[a]={s=s,head={},i=a,dt=0,chan={}}
break
end
a=a+1
@@ -205,7 +216,7 @@ while true do
end
end
end
print(colors.green.."'"..cl.id.."'"..colors.clear.." timed out")
print(cl.uid.." timed out")
serve(cl,serialize(cl.uid,"timeout"))
end
local s,e=cl.s:receive(0)

0 comments on commit 3f99326

Please sign in to comment.