155 lines
4.5 KiB
Python
155 lines
4.5 KiB
Python
global select
|
|
import select
|
|
global time
|
|
import time
|
|
global binascii
|
|
import binascii
|
|
|
|
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 = os.urandom(tokenLength)
|
|
setClientData(self.cID,"token",token)
|
|
|
|
if cmd[0] == "token":
|
|
if not authenticate(args["user"],args["user-password"]): return
|
|
with clientDataLock:
|
|
setClientData(self.cID,"active",True)
|
|
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)
|
|
|
|
ttimeout = time.monotonic()
|
|
self.connection.sendall(binascii.hexlify(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"] = bytes.fromhex(args["token"])
|
|
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") != 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"] and getClientData(cID,"args")["channel-password"] == args["channel-password"]:
|
|
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,"args")["user"] == args["user"] and getClientData(cID,"type") == "broadcast":
|
|
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)
|