def update(self, spin, data): self.box = self.box + data while len(self.box) >= self.size: chunk = buffer(self.box, 0, 4) self.box = buffer(self.box, 4) spawn(spin, BOX, chunk)
def process(self, spin, request): request.build_data() spawn(spin, request.method, request) spawn(spin, '%s %s' % (request.method, request.path), request) # When there is no route found it is necessary to spawn DUMPED # anyway otherwise we dont get the connection closed. # The browser will remain waiting for the service response. spin.dump(b'')
def update(self, device): try: data = device.read() spawn(device, LOAD, data) except IOError as excpt: # If something went wrong it spawns CLOSE with err. err = excpt.args[0] spawn(device, CLOSE, err)
def spawn_response(self): """ """ spawn(self.spin, HTTP_RESPONSE, self.response[0], self.response[1], self.response[2], self.header, self.data) self.__init__(self.spin)
def lose(spin): spin.destroy() try: spin.close() except Exception as excpt: err = excpt.args[0] spawn(spin, CLOSE_ERR, err) debug()
def process(self, spin, request, data): self.request = request contype = request.headers.get('connection', '').lower() uptype = request.headers.get('upgrade', '').lower() if contype == 'upgrade' and uptype == 'websocket': spawn(spin, RequestHandle.DONE, request) else: self.accumulate(spin, data)
def accumulate(self, spin, data): size = int(self.request.headers.get('content-length', '0')) NonPersistentConnection(spin) if RequestHandle.MAX_SIZE <= size: spawn(spin, RequestHandle.OVERFLOW, self.request) else: TmpFile(spin, data, size, self.request.fd)
def accumulate(self, spin, data): size = int(self.request.headers.get('content-length', '0')) NonPersistentConnection(spin) # PersistentConnection(spin) if RequestHandle.MAX_SIZE <= size: spawn(spin, RequestHandle.OVERFLOW, self.request) else: TmpFile(spin, data, size, self.request.fd)
def split(self, con, data): try: reg = match(RFC_REG, data) prefix = reg.group('prefix') command = reg.group('command') argument = reg.group('argument') except: pass else: command = command.upper() spawn(con, command, prefix, argument)
def handle_found(self, dev, data): TABLE = { '\> (.+)\(([0-9]+)\)(.+)':'LINE', '\(Pdb\) Deleted breakpoint ([0-9]+)':'DELETED_BREAKPOINT', '\(Pdb\) Breakpoint ([0-9]+) at (.+)\:([0-9]+)':'BREAKPOINT'} data = data.decode(self.encoding) for regstr, event in TABLE.items(): regex = search(regstr, data) if regex: spawn(dev, event, *regex.groups())
def drop(spin, filename): """ Shouldn't be called outside this module. """ try: fd = open(filename, 'rb') except IOError as excpt: err = excpt.args[0] spawn(spin, OPEN_FILE_ERR, err) else: spin.dumpfile(fd)
def update(self, spin): # All linked to CONNECT is called. err = spin.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) # If the err is non zero the socket is in error. if err != 0: spawn(spin, CONNECT_ERR, err) else: spawn(spin, CONNECT) # As we can connect just once, it unlinks self.update from # WRITE. zmap(spin, WRITE, self.update)
def handle_found(device, data): TABLE = { '\> (?P<filename>.+)\((?P<line>[0-9]+)\)(?P<args>.+)':('LINE', ('filename', 'line', 'args')), '\(Pdb\) Deleted breakpoint (?P<index>[0-9]+)':('DELETED_BREAKPOINT', ('index',)), '\(Pdb\) Breakpoint (?P<index>[0-9]+) at (?P<filename>.+)\:(?P<line>[0-9]+)':('BREAKPOINT', ('index', 'filename', 'line')) } for regex, (event, groups) in TABLE.iteritems(): sch = search(regex, data) if not sch: continue spawn(device, event, *sch.group(*groups)) break
def update(self, spin): """ This method is called on READ to recv data from the socket. Events: LOAD, CLOSE, RECV_ERR """ try: # Receive self.SIZE bytes at most. data = spin.recv(self.SIZE) # If data == '' then it is over. if not data: spawn(spin, CLOSE, '') # Otherwise it arose data. else: spawn(spin, LOAD, data) except socket.error as excpt: # The excpt.args[0] contains the socket # status. err = excpt.args[0] # If it is the case of the connection being closed # we spawn CLOSE with the motive. if err in CLOSE_ERR_CODE: spawn(spin, CLOSE, err) else: # In case of error. spawn(spin, RECV_ERR, err) debug()
def update(self, spin): try: # If self.data is '' we read from the file. if not self.data: self.data = self.fd.read(self.BLOCK) # If self.data is '' then we are done. if not self.data: # Spreads DUMPED_FILE so clients of this protocol # can know when their files were sent. zmap(spin, WRITE, self.update) spawn(spin, DUMPED_FILE) # We no more need to write. # We are done. return size = spin.send(self.data) # We use buffer to send faster. self.data = buffer(self.data, size) # If it arose error when sending we deal with it. except socket.error as excpt: err = excpt.args[0] if err in CLOSE_ERR_CODE: spawn(spin, CLOSE) else: spawn(spin, SEND_ERR, excpt) except IOError as excpt: err = excpt.args[0] spawn(spin, READ_ERR, err)
def handle_found(device, data): TABLE = { '\> (?P<filename>.+)\((?P<line>[0-9]+)\)(?P<args>.+)': ('LINE', ('filename', 'line', 'args')), '\(Pdb\) Deleted breakpoint (?P<index>[0-9]+)': ('DELETED_BREAKPOINT', ('index', )), '\(Pdb\) Breakpoint (?P<index>[0-9]+) at (?P<filename>.+)\:(?P<line>[0-9]+)': ('BREAKPOINT', ('index', 'filename', 'line')) } for regex, (event, groups) in TABLE.iteritems(): sch = search(regex, data) if not sch: continue spawn(device, event, *sch.group(*groups)) break
def update(self, device): try: data = self.queue.popleft() device.write(data) except IOError as excpt: err = excpt.args[0] spawn(device, CLOSE, err) debug() except IndexError: # If the queue is empty we no more need # the WRITE event. zmap(device, WRITE, self.update) # It is important to know when all data was # fully sent. It spawns DUMPED when the queue # is empty. spawn(device, DUMPED)
def cave(self, args, base, event, cond): """ This function shouldn't be called outside untwisted. """ val = cond(self.data, event, args) if not val: return for ind in base: ind() self.count = self.count - 1 if not self.count: spawn(self, COMPLETE, self.data)
def __init__(self, spin): self.request = None xmap(spin, TransferHandle.DONE, self.process) # It will not be spawned if it is a websocket connection. xmap( spin, TmpFile.DONE, lambda spin, fd, data: spawn( spin, RequestHandle.DONE, self.request))
def update(self, device): try: data = self.queue.popleft() # As device.write returns None # we don't need to worry whether it has sent all the bytes # unlike with sockets. device.write(data) except IndexError: # When the queue is empty then we don't need # the WRITE event. zmap(device, WRITE, self.update) spawn(device, DUMPED) except IOError as excpt: # If something went wrong it spawns CLOSE with err. # The err parameter gives a clue of what happened. err = excpt.args[0] spawn(device, CLOSE, err)
def __init__(self, spin): self.request = None xmap(spin, TransferHandle.DONE, self.process) # It will not be spawned if it is a websocket connection. xmap(spin, TmpFile.DONE, lambda spin, fd, data: spawn(spin, RequestHandle.DONE, self.request))
def update(self, spin): # Calls repeatedly accept to improve efficience. while True: try: sock, addr = spin.accept() # Instantiate a new Spin and spreads it. # Since it is connected is_on=True new = Spin(sock) spawn(spin, ACCEPT, new) except socket.error as excpt: # If there is no client accept throws # an exception that is spreaded too. err = excpt.args[0] if not err in ACCEPT_ERR_CODE: # It spawns ACCEPT_ERR just if the socket # it isn't a peculiar set of conditions. # As we are calling accpet inside a while # we would have continously EAGAIN, EWOULDBLOCK etc. spawn(spin, ACCEPT_ERR, err) debug() else: break
def update(self, device): try: # It might happen of data having length lower than SIZE. data = device.read(self.SIZE) except IOError as excpt: # When an exception occurs it deliveries the exception err. # It as well spawns CLOSE. err = excpt.args[0] spawn(device, CLOSE, err) # This is interesting so we can know what is going on. debug() else: if not data: spawn(device, CLOSE, '') # The event carrying the data. # This is interesting sharing the LOAD event # since we can use sub protocols for Stdout. spawn(device, LOAD, data)
def update(self, spin): """ This method is called on WRITE to send data. It attempts to optmize the job of sending bytes by using buffer. The algorithm is explained in the class doc. Events: DUMPED, CLOSE, SEND_ERR See help(Stdin). """ try: if not self.data: self.data = self.queue.popleft() # As we are in non blocking mode a call to send # doesn't block. We just need to know the amount # of bytes sent. size = spin.send(self.data) # We move the pointer size bytes ahead. self.data = buffer(self.data, size) except socket.error as excpt: err = excpt.args[0] # The err value contains the socket status error code. # It is passed with either CLOSE or SEND_ERR so # users of this protocol can know what happened # exactly with the call to send. if err in CLOSE_ERR_CODE: spawn(spin, CLOSE, err) else: spawn(spin, SEND_ERR, err) debug() except IndexError: # If the queue is empty we no more need # the WRITE event. zmap(spin, WRITE, self.update) # It is important to know when all data was # fully sent. It spawns DUMPED when the queue # is empty. spawn(spin, DUMPED)
class Job(Spin): def __init__(self): # I have to improve this code. # i have to handle the exception # if the port is in use etc. Spin.__init__(self) server = socket(AF_INET, SOCK_STREAM) server.bind(('127.0.0.1', 0)) server.listen(1) self.connect_ex(server.getsockname()) sock, addr = server.accept() self.sock = sock server.close() xmap(self, READ, self.dispatch) self.lock = Lock() self.ident = None self.data = None def register(self, callback, *args, **kwargs): thread = Machine(self, callback, *args, **kwargs) return thread.getName() @staticmethod def dispatch(self): try: self.recv(1) except error, (err, msg): if err in CODE: return else: raise spawn(self, self.ident, self.data) self.lock.release()
def process(self, spin, request): request.build_data() spawn(spin, request.method, request) spawn(spin, '%s %s' % (request.method, request.path), request) spin.dump('')
def on_nick(con, nicka, user, host, nickb): if not con.nick == nicka: return con.nick = nickb; spawn(con, 'MENICK', nicka, user, host, nickb)
def on_part(con, nick, user, host, chan): spawn(con, 'PART->%s' % chan, nick, user, host) if con.nick == nick: spawn(con, 'PART->%s->MEPART' % chan, chan)
def handle_found(client, data): op, args = data.split(' ', 1) args = map(float, args.split(' ')) spawn(client, op, args)
def handle_found(self, device, data): tokens = data.split(self.delim, 4) event = tokens[0] del tokens[0] spawn(device, event, *tokens)
def __init__(self, spin): xmap( spin, AccUntil.DONE, lambda spin, request, data: spawn( spin, TransferHandle.DONE, Request(request), data))
def spawn_user_cmd(self, spin, nick, user, host, target, msg): spawn(spin, msg, nick, user, host, target, msg)
def split(server, nick, user, host, target, msg): spawn(server, host, nick, user, target, msg)
def spawn_response(self, *args): """ """ spawn(self.spin, HTTP_RESPONSE, self.response[0], self.response[1], self.response[2], self.header, self.data)
def spawn_method(self, spin, version, code, reason, header, message): spawn(spin, code, version, reason, header, message)
def on_privmsg(con, nick, user, host, target, msg): spawn(con, 'PRIVMSG->%s' % target.lower(), nick, user, host, msg) spawn(con, 'PRIVMSG->%s' % nick.lower(), target, user, host, msg)
def on_join(con, nick, user, host, chan): if con.nick == nick: spawn(con, 'MEJOIN', chan) else: spawn(con, 'JOIN->%s' % chan, nick, user, host)
def handle_found(self, spin, data): data = data.decode(self.encoding) regex = search(self.regstr, data) if regex: spawn(spin, self.event, *regex.groups())
def on_353(con, prefix, nick, mode, chan, peers): spawn(con, '353->%s' % chan, prefix, nick, mode, peers)
def handle_found(client, data): op, args = data.decode('utf8').split(' ', 1) args = list(map(float, args.split(' '))) spawn(client, op, args)
def on_332(con, addr, nick, channel, msg): spawn(con, '332->%s' % channel, addr, nick, msg)