164 lines
4.6 KiB
Python
164 lines
4.6 KiB
Python
global select
|
|
import select
|
|
global time
|
|
import time
|
|
global codecs
|
|
import codecs
|
|
|
|
global clientLoopIn
|
|
def clientLoopIn(self):
|
|
chars = 0
|
|
nl = False
|
|
while chars < httpHeaderMaxSize:
|
|
chars += 1
|
|
char = recv(self.connection,1).decode(errors="replace")
|
|
if char == "\n":
|
|
if nl == True:
|
|
chars = 0
|
|
break
|
|
|
|
if nl == False:
|
|
nl = True
|
|
else:
|
|
nl = False
|
|
if chars >= httpHeaderMaxSize: return
|
|
|
|
cmd = getResponse(self.connection,1024).decode("utf-8")
|
|
if cmd == False: return
|
|
cmd = commandToList(cmd)
|
|
args = {}
|
|
q = False
|
|
for arg in cmd[1:]:
|
|
argSplit = arg.split("=",1)
|
|
args[argSplit[0]] = argSplit[1]
|
|
|
|
if not "channel" in args: args["channel"] = "default"
|
|
if not "channel_password" in args: args["channel_password"] = ""
|
|
|
|
with clientDataLock:
|
|
setClientData(self.cID,"type",cmd[0])
|
|
setClientData(self.cID,"args",args)
|
|
|
|
if cmd[0] == "broadcast":
|
|
setClientData(self.cID,"buffer",{})
|
|
setClientData(self.cID,"bufferPacket",-1)
|
|
|
|
if cmd[0] == "watch":
|
|
q = queue.Queue()
|
|
setClientData(self.cID,"queue",q)
|
|
|
|
if cmd[0] == "token":
|
|
q = queue.Queue()
|
|
setClientData(self.cID,"queue",q)
|
|
setClientData(self.cID,"active",False)
|
|
token = codecs.encode(os.urandom(tokenLength),"hex")
|
|
setClientData(self.cID,"token",token)
|
|
|
|
if cmd[0] == "token":
|
|
if not authenticate(args["user"],args["user_password"]): return
|
|
with clientDataLock:
|
|
with clientsLock:
|
|
for client in clients:
|
|
if getClientData(client,"type") != "token": continue
|
|
if getClientData(client,"args")["user"] != args["user"]: continue
|
|
if getClientData(client,"active") != True: continue
|
|
setClientData(client,"active",False)
|
|
getClientData(client,"queue").put(None)
|
|
setClientData(self.cID,"active",True)
|
|
|
|
ttimeout = time.monotonic()
|
|
self.connection.sendall(token)
|
|
self.connection.close()
|
|
ttimeout = tokenTimeout - (time.monotonic() - ttimeout)
|
|
if ttimeout <= 0: return
|
|
try:
|
|
q.get(True,ttimeout)
|
|
except Queue.Empty:
|
|
pass
|
|
return
|
|
|
|
if cmd[0] == "broadcast":
|
|
if not "token" in args:
|
|
if not authenticate(args["user"],args["user_password"]): return
|
|
else:
|
|
tokenAuthed = False
|
|
with clientDataLock:
|
|
args["token"] = args["token"].encode("ascii")
|
|
with clientsLock:
|
|
for client in clients:
|
|
if getClientData(client,"type") != "token": continue
|
|
if getClientData(client,"args")["user"] != args["user"]: continue
|
|
if getClientData(client,"active") != True: continue
|
|
if getClientData(client,"token") != args["token"]: return
|
|
tokenAuthed = True
|
|
break
|
|
if not tokenAuthed: return
|
|
|
|
if not "bufsize" in args:
|
|
bufsize = 0
|
|
else:
|
|
bufsize = int(args["bufsize"])
|
|
if bufsize < 0: bufsize = 0
|
|
if bufsize > maxBuffer: bufsize = maxBuffer
|
|
|
|
buffer = getClientData(self.cID,"buffer")
|
|
packet = -1
|
|
packetMin = 0
|
|
bufferSize = 0
|
|
while True:
|
|
if bufsize == 0:
|
|
data = self.connection.recv(connBuffer)
|
|
else:
|
|
data = recv(self.connection,bufsize)
|
|
if data == b"": return
|
|
with clientDataLock:
|
|
dataSize = len(data)
|
|
if dataSize > maxBuffer: return
|
|
bufferSize += dataSize + bufferCost
|
|
while bufferSize > maxBuffer:
|
|
bufferSize -= len(buffer[str(packetMin)]) + bufferCost
|
|
del buffer[str(packetMin)]
|
|
packetMin += 1
|
|
packet += 1
|
|
buffer[str(packet)] = data
|
|
setClientData(self.cID,"bufferPacket",packet)
|
|
with clientsLock:
|
|
for cID in clients:
|
|
if (
|
|
getClientData(cID,"type") == "watch" and
|
|
getClientData(cID,"args")["user"] == args["user"] and
|
|
getClientData(cID,"args")["channel"] == args["channel"]
|
|
):
|
|
getClientData(cID,"queue").put("")
|
|
|
|
if cmd[0] == "watch":
|
|
packet = -1
|
|
watchID = False
|
|
data = b""
|
|
with clientDataLock:
|
|
with clientsLock:
|
|
for cID in clients:
|
|
if (
|
|
getClientData(cID,"type") == "broadcast" and
|
|
getClientData(cID,"args")["user"] == args["user"] and
|
|
getClientData(cID,"args")["channel"] == args["channel"] and
|
|
getClientData(cID,"args")["channel_password"] == args["channel_password"]
|
|
):
|
|
watchID = cID
|
|
packet = getClientData(cID,"bufferPacket")
|
|
|
|
if watchID == False: return
|
|
if packet == -1:
|
|
q.get(timeout=timeout)
|
|
with clientDataLock:
|
|
packet = getClientData(watchID,"bufferPacket")
|
|
data = getClientData(watchID,"buffer")[str(packet)]
|
|
self.connection.sendall(data)
|
|
|
|
while True:
|
|
q.get(timeout=timeout)
|
|
packet += 1
|
|
with clientDataLock:
|
|
data = getClientData(watchID,"buffer")[str(packet)]
|
|
self.connection.sendall(data)
|