fstream/modules/fstream/main.py

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)