def test_pipe(Poller): m = Manager() + Poller() a, b = Pipe("a", "b") a.register(m) b.register(m) a = Client(channel=a.channel).register(m) b = Client(channel=b.channel).register(m) m.start() try: assert pytest.wait_for(a, "ready") assert pytest.wait_for(b, "ready") a.fire(write(b"foo")) assert pytest.wait_for(b, "data", b"foo") b.fire(write(b"foo")) assert pytest.wait_for(a, "data", b"foo") a.fire(close()) assert pytest.wait_for(a, "disconnected") b.fire(close()) assert pytest.wait_for(b, "disconnected") finally: m.stop()
def read(self, data): """Handles incoming raw sensor data and broadcasts it to specified udp servers and connected tcp clients :param data: NMEA raw sentences incoming data """ self.log('Received NMEA data:', data, lvl=debug) # self.log(data, pretty=True) if self._tcp_socket is not None and \ len(self._connected_tcp_endpoints) > 0: self.log('Publishing data on tcp server', lvl=debug) for endpoint in self._connected_tcp_endpoints: self.fireEvent( write( endpoint, bytes(data, 'ascii')), self.channel + '_tcp' ) if self._udp_socket is not None and \ len(self.config.udp_endpoints) > 0: self.log('Publishing data to udp endpoints', lvl=debug) for endpoint in self.config.udp_endpoints: host, port = endpoint.split(":") self.log('Transmitting to', endpoint, lvl=verbose) self.fireEvent( write( (host, int(port)), bytes(data, 'ascii') ), self.channel + '_udp' )
def request(self, method, url, body=None, headers=None): host, port, path, secure = parse_url(url) if not self._transport.connected: self.fire(connect(host, port, secure)) yield self.wait("connected", self._transport.channel) headers = Headers([(k, v) for k, v in (headers or {}).items()]) # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) if "Host" not in headers: headers["Host"] = "{0:s}{1:s}".format( host, "" if port in (80, 443) else ":{0:d}".format(port) ) if body is not None: headers["Content-Length"] = len(body) command = "%s %s HTTP/1.1" % (method, path) message = "%s\r\n%s" % (command, headers) self.fire(write(message.encode('utf-8')), self._transport) if body is not None: self.fire(write(body), self._transport) yield (yield self.wait("response"))
def send(self, event): """Sends a packet to an already known user or one of his clients by UUID""" try: if event.sendtype == "user": hfoslog("[CM] Broadcasting to all of users clients: '%s': '%s" % (event.uuid, event.packet), lvl=debug) if event.uuid not in self._users: hfoslog('[CM] Unknown user! ', event, lvl=critical) return clients = self._users[event.uuid].clients for clientuuid in clients: sock = self._clients[clientuuid].sock if not event.raw: self.fireEvent(write(sock, json.dumps(event.packet)), "wsserver") else: hfoslog("[CM] Sending raw data to client") self.fireEvent(write(sock, event.packet), "wsserver") else: # only to client hfoslog("[CM] Sending to user's client: '%s': '%.50s ..." % (event.uuid, event.packet), lvl=debug) if event.uuid not in self._clients: hfoslog('[CM] Unknown client! ', event.uuid, lvl=critical) hfoslog('[CM] Clients: ', self._clients, lvl=debug) return sock = self._clients[event.uuid].sock if not event.raw: self.fireEvent(write(sock, json.dumps(event.packet)), "wsserver") else: hfoslog("[CM] Sending raw data to client") self.fireEvent(write(sock, event.packet), "wsserver") except Exception as e: hfoslog("[CM] Exception during sending: %s (%s)" % (e, type(e)), lvl=critical)
def authentication(self, event): """Links the client to the granted account and profile, then notifies the client""" try: hfoslog("[CM] Authorization has been granted by DB check: %s" % event) account, profile, clientconfig = event.userdata useruuid = event.useruuid originatingclientuuid = event.clientuuid clientuuid = clientconfig.uuid if clientuuid != originatingclientuuid: hfoslog("[CM] Mutating client uuid to request id: ", clientuuid, lvl=debug) # Assign client to user if useruuid in self._users: signedinuser = self._users[useruuid] else: signedinuser = User(account, profile, useruuid) self._users[account.uuid] = signedinuser if clientuuid in signedinuser.clients: hfoslog("[CM] Client configuration already logged in.", lvl=critical) # TODO: What now?? # Probably senseful would be to add the socket to the client's other socket # The clients would be identical then - that could cause problems # which could be remedied by duplicating the configuration else: signedinuser.clients.append(clientuuid) hfoslog("[CM] Active client registered to user ", clientuuid, useruuid, lvl=info) # Update socket.. socket = self._sockets[event.sock] socket.clientuuid = clientuuid self._sockets[event.sock] = socket # ..and client lists newclient = Client(event.sock, socket.ip, clientuuid, useruuid, clientconfig.name, clientconfig) del (self._clients[originatingclientuuid]) self._clients[clientuuid] = newclient authpacket = {"component": "auth", "action": "login", "data": account.serializablefields()} hfoslog("[CM] Transmitting Authorization to client", authpacket, lvl=debug) self.fireEvent(write(event.sock, json.dumps(authpacket)), "wsserver") profilepacket = {"component": "profile", "action": "get", "data": profile.serializablefields()} hfoslog("[CM] Transmitting Profile to client", profilepacket, lvl=debug) self.fireEvent(write(event.sock, json.dumps(profilepacket)), "wsserver") clientconfigpacket = {"component": "clientconfig", "action": "get", "data": clientconfig.serializablefields()} hfoslog("[CM] Transmitting client configuration to client", clientconfigpacket, lvl=debug) self.fireEvent(write(event.sock, json.dumps(clientconfigpacket)), "wsserver") self.fireEvent(userlogin(clientuuid, useruuid)) hfoslog("[CM] User configured:", signedinuser.__dict__, lvl=info) except Exception as e: hfoslog("[CM] Error (%s, %s) during auth grant: %s" % (type(e), e, event), lvl=error)
def broadcast(self, event): """Broadcasts an event either to all users or clients, depending on event flag""" try: if event.broadcasttype == "users": if len(self._users) > 0: hfoslog("[CM] Broadcasting to all users:", event.content) for useruuid in self._users.keys(): self.fireEvent(send(useruuid, event.content, sendtype="user")) else: hfoslog("[CM] Not broadcasting, no users connected.", lvl=debug) elif event.broadcasttype == "clients": if len(self._clients) > 0: hfoslog("[CM] Broadcasting to all clients: ", event.content) for client in self._clients.values(): self.fireEvent(write(client.sock, event.content), "wsserver") else: hfoslog("[CM] Not broadcasting, no clients connected.", lvl=debug) elif event.broadcasttype == "socks": if len(self._sockets) > 0: hfoslog("[CM] Emergency?! Broadcasting to all sockets: ", event.content) for sock in self._sockets: self.fireEvent(write(sock, event.content), "wsserver") else: hfoslog("[CM] Not broadcasting, no sockets connected.", lvl=debug) except Exception as e: hfoslog("[CM] Error during broadcast: ", e, type(e), lvl=critical)
def _on_stream(self, res, data): sock = res.request.sock if data is not None: if isinstance(data, text_type): data = data.encode(self._encoding) if res.chunked: buf = [ hex(len(data))[2:].encode(self._encoding), b"\r\n", data, b"\r\n" ] data = b"".join(buf) self.fire(write(sock, data)) if res.body and not res.done: try: data = next(res.body) while not data: # Skip over any null byte sequences data = next(res.body) except StopIteration: data = None self.fire(stream(res, data)) else: if res.body: res.body.close() if res.chunked: self.fire(write(sock, b"0\r\n\r\n")) if res.close: self.fire(close(sock)) if sock in self._clients: del self._clients[sock] res.done = True
def broadcast(self, event): """Broadcasts an event either to all users or clients, depending on event flag""" try: if event.broadcasttype == "users": if len(self._users) > 0: hfoslog("[CM] Broadcasting to all users:", event.content) for useruuid in self._users.keys(): self.fireEvent( send(useruuid, event.content, sendtype="user")) else: hfoslog("[CM] Not broadcasting, no users connected.", lvl=debug) elif event.broadcasttype == "clients": if len(self._clients) > 0: hfoslog("[CM] Broadcasting to all clients: ", event.content) for client in self._clients.values(): self.fireEvent(write(client.sock, event.content), "wsserver") else: hfoslog("[CM] Not broadcasting, no clients connected.", lvl=debug) elif event.broadcasttype == "socks": if len(self._sockets) > 0: hfoslog("[CM] Emergency?! Broadcasting to all sockets: ", event.content) for sock in self._sockets: self.fireEvent(write(sock, event.content), "wsserver") else: hfoslog("[CM] Not broadcasting, no sockets connected.", lvl=debug) except Exception as e: hfoslog("[CM] Error during broadcast: ", e, type(e), lvl=critical)
def test_tcp_reconnect(Poller, ipv6): # XXX: Apparently this doesn't work on Windows either? # XXX: UPDATE: Apparently Broken on Windows + Python 3.2 # TODO: Need to look into this. Find out why... if pytest.PLATFORM == "win32" and pytest.PYVER[:2] >= (3, 2): pytest.skip("Broken on Windows on Python 3.2") m = Manager() + Poller() if ipv6: tcp_server = TCP6Server(("::1", 0)) tcp_client = TCP6Client() else: tcp_server = TCPServer(0) tcp_client = TCPClient() server = Server() + tcp_server client = Client() + tcp_client server.register(m) client.register(m) m.start() try: assert pytest.wait_for(client, "ready") assert pytest.wait_for(server, "ready") wait_host(server) # 1st connect client.fire(connect(server.host, server.port)) assert pytest.wait_for(client, "connected") assert pytest.wait_for(server, "connected") assert pytest.wait_for(client, "data", b"Ready") client.fire(write(b"foo")) assert pytest.wait_for(server, "data", b"foo") # disconnect client.fire(close()) assert pytest.wait_for(client, "disconnected") # 2nd reconnect client.fire(connect(server.host, server.port)) assert pytest.wait_for(client, "connected") assert pytest.wait_for(server, "connected") assert pytest.wait_for(client, "data", b"Ready") client.fire(write(b"foo")) assert pytest.wait_for(server, "data", b"foo") client.fire(close()) assert pytest.wait_for(client, "disconnected") assert pytest.wait_for(server, "disconnected") server.fire(close()) assert pytest.wait_for(server, "closed") finally: m.stop()
def send(self, event): """Sends a packet to an already known user or one of his clients by UUID""" try: jsonpacket = json.dumps(event.packet, cls=ComplexEncoder) if event.sendtype == "user": # TODO: I think, caching a user name <-> uuid table would # make sense instead of looking this up all the time. if event.uuid is None: userobject = objectmodels['user'].find_one({'name': event.username}) else: userobject = objectmodels['user'].find_one({'uuid': event.uuid}) if userobject is None: self.log("No user by that name known.", lvl=warn) return else: uuid = userobject.uuid self.log("Broadcasting to all of users clients: '%s': '%s" % ( uuid, event.packet), lvl=network) if uuid not in self._users: self.log("User not connected!", event, lvl=critical) return clients = self._users[uuid].clients for clientuuid in clients: sock = self._clients[clientuuid].sock if not event.raw: self.log("Sending json to client", jsonpacket, lvl=network) self.fireEvent(write(sock, jsonpacket), "wsserver") else: self.log("Sending raw data to client") self.fireEvent(write(sock, event.packet), "wsserver") else: # only to client self.log("Sending to user's client: '%s': '%s'" % ( event.uuid, jsonpacket), lvl=network) if event.uuid not in self._clients: self.log("Unknown client!", event.uuid, lvl=critical) self.log("Clients:", self._clients, lvl=debug) return sock = self._clients[event.uuid].sock if not event.raw: self.fireEvent(write(sock, jsonpacket), "wsserver") else: self.log("Sending raw data to client", lvl=network) self.fireEvent(write(sock, event.packet), "wsserver") except Exception as e: self.log("Exception during sending: %s (%s)" % (e, type(e)), lvl=critical)
def broadcast(self, event): """Broadcasts an event either to all users or clients or a given group, depending on event flag""" try: if event.broadcasttype == "users": if len(self._users) > 0: self.log("Broadcasting to all users:", event.content, lvl=network) for useruuid in self._users.keys(): self.fireEvent( send(useruuid, event.content, sendtype="user")) # else: # self.log("Not broadcasting, no users connected.", # lvl=debug) elif event.broadcasttype == "clients": if len(self._clients) > 0: self.log("Broadcasting to all clients: ", event.content, lvl=network) for client in self._clients.values(): self.fireEvent(write(client.sock, event.content), "wsserver") # else: # self.log("Not broadcasting, no clients # connected.", # lvl=debug) elif event.broadcasttype in ("usergroup", "clientgroup"): if len(event.group) > 0: self.log("Broadcasting to group: ", event.content, event.group, lvl=network) for participant in set(event.group): if event.broadcasttype == 'usergroup': broadcast_type = "user" else: broadcast_type = "client" broadcast = send(participant, event.content, sendtype=broadcast_type) self.fireEvent(broadcast) elif event.broadcasttype == "socks": if len(self._sockets) > 0: self.log("Emergency?! Broadcasting to all sockets: ", event.content) for sock in self._sockets: self.fireEvent(write(sock, event.content), "wsserver") # else: # self.log("Not broadcasting, no sockets # connected.", # lvl=debug) except Exception as e: self.log("Error during broadcast: ", e, type(e), lvl=critical)
def _on_stdin_read(self, data): """read Event Handler for stdin This event is triggered by the connected ``stdin`` component when there is new data to be read in from standard input. """ if not self.opts["udp"]: self.fire(write(data)) else: self.fire(write((self.host, self.port), data))
def read(self, sock, data): data = data.strip().split(" ", 3) try: if len(data) < 2: raise ValueError("At least 2 parameters required {} given".format(len(data))) cmd, sid, args = data[0], data[1], data[2:] cmd = cmd.upper() self.fire(write(sock, "{}\n".format(getattr(self, cmd)(sid, *args)))) except Exception as e: self.fire(write(sock, "ERR {}\n".format(e)))
def connect(self, sock, host, port): """Connect Event -- Triggered for new connecting clients""" self.clients[sock] = { "host": sock, "port": port, "state": { "nickname": None, "registered": False } } self.fire(write(sock, b"Welcome to the circuits Chat Server!\n")) self.fire(write(sock, b"Please enter a desired nickname: "))
def response(self, peer, response): id = response.header.id qname = str(response.q.qname) qtype = response.q.qtype qclass = response.q.qclass if id not in self.peers: self.logger.info( "Unknown Response ({0:s}): {1:s} {2:s} {3:s}".format( "{0:s}:{1:d}".format(*peer), CLASS.get(qclass), QTYPE.get(qtype), qname ) ) return peer = self.peers[id] request = self.requests[id] key = (str(request.q.qname), request.q.qtype, request.q.qclass) reply = request.reply() reply.add_answer(*response.rr) self.cache[key] = reply.rr self.fire(write(peer, reply.pack())) del self.peers[id] del self.requests[id]
def _on_connected(self, host, port): headers = Headers([(k, v) for k, v in self._headers.items()]) # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) if "Host" not in headers: headers["Host"] = self._host \ + (":" + str(self._port)) if self._port else "" headers["Upgrade"] = "websocket" headers["Connection"] = "Upgrade" try: sec_key = os.urandom(16) except NotImplementedError: sec_key = "".join([chr(random.randint(0, 255)) for i in range(16)]) headers["Sec-WebSocket-Key"] = base64.b64encode(sec_key).decode( "latin1") headers["Sec-WebSocket-Version"] = "13" UNSAFE_CHARS = re.compile( '[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~]' ) escaped_resource = UNSAFE_CHARS.sub( '', self._resource.encode('ASCII', 'replace').decode('ASCII')) command = "GET %s HTTP/1.1" % (escaped_resource, ) message = "%s\r\n%s" % (command, headers) self._pending += 1 self.fire(write(message.encode('utf-8')), self._transport) return True
def query(self, peer, request): id = request.header.id qname = request.q.qname queryType = request.q.qtype reply = DNSRecord( DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q ) def cnameRecursion(dHost): global tmpRes # used for overwriting previous recursion value tmpData = dbTest(dHost) # First: get CNAME of desired host cnameAddress = [i[1] for i in tmpData if i[0] == 'CNAME'] tmpRes = (dHost,tmpData) if cnameAddress: newAddr = checkMacro(cnameAddress[0],dHost,peer) reply.add_answer(RR(dHost, QTYPE.CNAME, rdata=CNAME(newAddr))) # Second: get desired QTYPE from desired host printOut(peer,QTYPE.CNAME,str(dHost),newAddr) cnameRecursion(newAddr) return tmpRes qname,rData = cnameRecursion(qname) if queryType == QTYPE.TXT: # TXT rData = [i[1] for i in rData if i[0] == 'TXT'] # Add TXT Record printData = [] for tmprecord in rData: record = checkMacro(tmprecord,qname,peer) n = 255 if len(record) > 20: printData += [ record[:15]+'...(%d)' % len(record) ] else: printData = [record] if len(record) > n: record = [record[i:i+n] for i in range(0, len(record), n)] reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(record if isinstance(record,list) else [record,]))) printOut(peer,queryType,str(qname),printData) else: rData = [i[1] for i in rData if i[0] == qTypeDict[queryType]] resIP = '' if len(rData): resIP = rData elif '*' in db: #elif db.has_key('*'): #python2 only resIP = [i[1] for i in dbTest('*') if i[0] == 'A'] for tmpip in resIP: ip = checkMacro(tmpip,qname,peer) # Add A Record reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip))) if resIP: printOut(peer,queryType,str(qname),', '.join(resIP)) else: printOut(peer,queryType,str(qname),'NONE') # Send To Client self.fire(write(peer, reply.pack()))
def _transmit(self, packet): self.log(packet) unicode = dumps(packet).encode('utf-8') self.log(unicode, type(unicode)) self.fireEvent(write(bytes(unicode)), 'ws')
def _on_httperror_failure(self, evt, error): client = evt.args[0] socket = client.socket try: state = self._buffers[socket] except KeyError: self._premature_client_disconnect(client) return if client in state.responses: return print('Exception in httperror_failure: %s, %r' % (error, client)) self.default_internal_server_error(client, error) self.fire(write(socket, bytes(client.response))) self.fire(write(socket, bytes(client.response.headers))) self.fire(write(socket, bytes(client.response.body))) self.fire(close(socket))
def parse(data): # TODO: if we have a socket with TLS support we should try to use it instead so that we can speak HTTPS and redirect to the other port. # self.fire(write(socket, b'\x15\x03\x01\x00\x02\x02(')) self.fire(write(socket, b'\x15\x03\x01\x00\x02\x02G')) # self.fire(write(socket, b'<html><head><title>use plaintext HTTP</title></head><body></body>USE HTTP!</html>')) self.fire(close(socket)) return parser(b'')
def _on_request(self, client): if client.socket is None: host = client.request.uri.host port = client.request.uri.port secure = client.request.uri.scheme == u'https' result = yield self.call( connect(host, port, secure, certfile=client.ssl.cert, keyfile=client.ssl.key, ca_certs=[client.ssl.ca])) if result.errors: reraise(*result.value) client.socket = result.value if not client.socket.connected: yield self.wait("connected", client.socket.channel) try: state = self._buffers[client.socket] except KeyError: return # server disconnected state['requests'].append(client) composer = ComposedRequest(client.request) composer.prepare() for data in composer: self.fire(write(data), client.socket) yield client
def query(self, qname, qtype="A", qclass="IN"): qtype = QTYPE.reverse[qtype] qclass = CLASS.reverse[qclass] q = DNSRecord(q=DNSQuestion(qname, qtype, qclass)) self.fire(write((self.server, self.port), q.pack()))
def _on_response_start(self, client): request, response = client socket = client.socket try: state = self._buffers[socket] except KeyError: # client disconnected before receiving answer self._premature_client_disconnect(client) return state.response_started.add(client) if client.response.status == 101 or client.request.method == u'CONNECT' and client.response.status.successful: state.tunnel = True # prepare for sending composed = ComposedResponse(response, request) composed.prepare() state.composed[client] = composed # send HTTP response status line and headers bresponse = bytes(response) bheaders = bytes(response.headers) self.fire(write(socket, b'%s%s' % (bresponse, bheaders))) self.fire(_ResponseBody(client))
def __init__(self, *args, **opts): super(Telnet, self).__init__() self.args = args self.opts = opts if len(args) == 1: if os.path.exists(args[0]): UNIXClient(channel=self.channel).register(self) host = dest = port = args[0] dest = (dest, ) else: raise OSError("Path %s not found" % args[0]) else: if not opts["udp"]: TCPClient(channel=self.channel).register(self) else: UDPClient(0, channel=self.channel).register(self) host, port = args port = int(port) dest = host, port self.host = host self.port = port print("Trying %s ..." % host) if not opts["udp"]: self.fire(connect(*dest, secure=opts["secure"])) else: self.fire(write((host, port), b"\x00"))
def __init__(self, *args, **opts): super(Telnet, self).__init__() self.args = args self.opts = opts if len(args) == 1: if os.path.exists(args[0]): UNIXClient(channel=self.channel).register(self) host = dest = port = args[0] dest = (dest,) else: raise OSError("Path %s not found" % args[0]) else: if not opts["udp"]: TCPClient(channel=self.channel).register(self) else: UDPClient(0, channel=self.channel).register(self) host, port = args port = int(port) dest = host, port self.host = host self.port = port print("Trying %s ..." % host) if not opts["udp"]: self.fire(connect(*dest, secure=opts["secure"])) else: self.fire(write((host, port), b"\x00"))
def response(self, peer, response): id = response.header.id qname = str(response.q.qname) qtype = response.q.qtype qclass = response.q.qclass if id not in self.peers: self.logger.info( "Unknown Response ({0:s}): {1:s} {2:s} {3:s}".format( "{0:s}:{1:d}".format(*peer), CLASS.get(qclass), QTYPE.get(qtype), qname)) return peer = self.peers[id] request = self.requests[id] key = (str(request.q.qname), request.q.qtype, request.q.qclass) reply = request.reply() reply.add_answer(*response.rr) self.cache[key] = reply.rr self.fire(write(peer, reply.pack())) del self.peers[id] del self.requests[id]
def on_request(self, event, req, res): if req.selector and req.selector.startswith("URL:"): event.stop() _, url = req.selector.split(":", 1) req.stream = True self.fire(write(req.sock, TEMPLATE.format(timeout=self.timeout, url=url))) self.fire(close(req.sock))
def test_basic(Poller, ipv6): m = Manager() + Poller() if ipv6: udp_server = UDP6Server(("::1", 0)) udp_client = UDP6Client(("::1", 0), channel="client") else: udp_server = UDPServer(0) udp_client = UDPClient(0, channel="client") server = Server() + udp_server client = Client() + udp_client server.register(m) client.register(m) m.start() try: assert pytest.wait_for(server, "ready") assert pytest.wait_for(client, "ready") wait_host(server) client.fire(write((server.host, server.port), b"foo")) assert pytest.wait_for(server, "data", b"foo") client.fire(close()) assert pytest.wait_for(client, "closed") server.fire(close()) assert pytest.wait_for(server, "closed") finally: m.stop()
def http_through_ssl(self, socket): # If we receive a plain HTTP request and we're a TLS enabled socket # inform the user about his misusage and close the connection immediately. self.fire(write(socket, b"""Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please: https://%s""")) # TODO: add URI by parsing the data which were written into the socket self.fire(close(socket))
def parse(data): # TODO: if we have a socket with TLS support we should try to use it instead so that we can speak HTTPS and redirect to the other port. #self.fire(write(socket, b'\x15\x03\x01\x00\x02\x02(')) self.fire(write(socket, b'\x15\x03\x01\x00\x02\x02G')) #self.fire(write(socket, b'<html><head><title>use plaintext HTTP</title></head><body></body>USE HTTP!</html>')) self.fire(close(socket)) return parser(b'')
def test_tcp_connect_closed_port(Poller, ipv6): ### FIXME: This test is wrong. ### We need to figure out the sequence of events on Windows ### for this scenario. I think if you attempt to connect to ### a shutdown listening socket (tcp server) you should get ### an error event as response. if pytest.PLATFORM == "win32": pytest.skip("Broken on Windows") m = Manager() + Poller() if ipv6: tcp_server = TCP6Server(("::1", 0)) tcp_client = TCP6Client() else: tcp_server = TCPServer(0) tcp_client = TCPClient() server = Server() + tcp_server client = Client() + tcp_client server.register(m) client.register(m) m.start() try: assert pytest.wait_for(client, "ready") assert pytest.wait_for(server, "ready") wait_host(server) host, port = server.host, server.port tcp_server._sock.close() # 1st connect client.fire(connect(host, port)) assert pytest.wait_for(client, "connected") assert isinstance(client.error, SocketError) client.fire(write(b"foo")) assert pytest.wait_for(client, "disconnected") client.disconnected = False client.fire(write(b"foo")) assert pytest.wait_for(client, "disconnected", timeout=1.0) is None finally: m.stop()
def read(self, peer, data): try: self.fire(query(peer, DNSRecord.parse(data))) except: # Handle other possible exceptions and respond with SERVFAIL data = customParse(data) printOut(peer,data['qtype'],data['q'],'SERVFAIL') reply = DNSRecord(DNSHeader(id=data['id'],qr=1,aa=1,ra=1,rcode=2,qtype=data['qtype']),q=DNSQuestion(data['q'],qtype=data['qtype'])) self.fire(write(peer, reply.pack()))
def test(webapp): transport = TCPClient() client = Client() client += transport client.start() host, port, resource, secure = parse_url(webapp.server.http.base) client.fire(connect(host, port)) assert pytest.wait_for(transport, "connected") client.fire(write(b"GET / HTTP/1.1\r\n")) client.fire(write(b"Content-Type: text/plain\r\n\r\n")) assert pytest.wait_for(client, "done") client.stop() s = client.buffer().decode('utf-8').split('\r\n')[0] assert s == "HTTP/1.1 200 OK"
def _on_target_read(self, event, data): """Read Event Handler This unbound function will be later added as an event handler to a dynamically created and registered client instance and used to process Read events of a connected client. """ sock = self._sockets[event.channels[0]] self.fire(write(sock, data), "source")
def request(self, event, message): event.stop() if message.command == "PRIVMSG": if not self.privmsg_queue: self.fire(Event.create('privmsg_queue')) self.privmsg_queue.append(message) return self.last_called = time.time() message.encoding = self.irc.encoding self.fire(write(bytes(message)))
def _privmsg_queue(self): while self.privmsg_queue: message = self.privmsg_queue.pop(0) message.encoding = self.irc.encoding self.last_called = time.time() self.fire(write(bytes(message))) elapsed = time.time() - self.last_called must_wait = 1 / self.max_rate - elapsed if must_wait > 0: yield sleep(max(0, must_wait))
def reply(self, target, message): user = self.users[target] if message.add_nick: message.args.insert(0, user.nick or "") if message.prefix is None: message.prefix = self.host self.fire(write(target, bytes(message)))
def reply(self, sock, message): user = User.objects.filter(sock=sock).first() if message.add_nick: message.args.insert(0, user.nick or u"") if message.prefix is None: message.prefix = self.server.host self.fire(write(sock, bytes(message)))
def file_read(self, event, *args): # Ignore the server read event(s) if len(args) > 1: return data = args[0] channel = event.channels[0] if channel in self.streams: req, file = self.streams[channel] self.fire(write(req.sock, data))
def send(self, event): """Sends a packet to an already known user or one of his clients by UUID""" try: if event.sendtype == "user": hfoslog( "[CM] Broadcasting to all of users clients: '%s': '%s" % (event.uuid, event.packet), lvl=debug) if event.uuid not in self._users: hfoslog('[CM] Unknown user! ', event, lvl=critical) return clients = self._users[event.uuid].clients for clientuuid in clients: sock = self._clients[clientuuid].sock if not event.raw: self.fireEvent(write(sock, json.dumps(event.packet)), "wsserver") else: hfoslog("[CM] Sending raw data to client") self.fireEvent(write(sock, event.packet), "wsserver") else: # only to client hfoslog("[CM] Sending to user's client: '%s': '%.50s ..." % (event.uuid, event.packet), lvl=debug) if event.uuid not in self._clients: hfoslog('[CM] Unknown client! ', event.uuid, lvl=critical) hfoslog('[CM] Clients: ', self._clients, lvl=debug) return sock = self._clients[event.uuid].sock if not event.raw: self.fireEvent(write(sock, json.dumps(event.packet)), "wsserver") else: hfoslog("[CM] Sending raw data to client") self.fireEvent(write(sock, event.packet), "wsserver") except Exception as e: hfoslog("[CM] Exception during sending: %s (%s)" % (e, type(e)), lvl=critical)
def expect(self, client): for expect in client.request.headers.elements('Expect'): if expect.is_100_continue: if not self.expect_continue(client): raise EXPECTATION_FAILED() data = Response(status=CONTINUE().code) data = b'%s%s' % (data, data.headers) self.fire(write(data, client.socket), client.server.channel) else: raise EXPECTATION_FAILED('Unknown expect header: %r' % (expect,))
def connect(self, socket, host, port): log("RaspuinoDartMiniEcho::connect({}, {}, {})".format( id(socket), host, port)) self.clients[socket] = {"host": host, "port": port} self.fireEvent( write( socket, "welcome %s:%d, you're connection number %d" % (host, port, len(self.clients)))) self.broadcast("%s:%d joined as number %d" % (host, port, len(self.clients)))
def expect(self, client): for expect in client.request.headers.elements('Expect'): if expect.is_100_continue: if not self.expect_continue(client): raise EXPECTATION_FAILED() data = Response(status=CONTINUE().code) data = b'%s%s' % (data, data.headers) self.fire(write(data, client.socket), client.server.channel) else: raise EXPECTATION_FAILED('Unknown expect header: %r' % (expect, ))
def _on_request(self, event, client): request, response = client headers = request.headers if not headers.element('Connection').upgrade or not headers.element('Upgrade').tls: return data = Response(status=SWITCHING_PROTOCOLS().code) data.headers['Upgrade'] = '%s, %s' % (headers['Upgrade'], response.protocol) data.headers['Connection'] = 'Upgrade' data = b'%s%s' % (data, data.headers) self.fire(write(data, client.socket), client.server.channel) yield self.wait(starttls(client.socket))
def _on_source_read(self, sock, data): """Explicitly defined Read Event Handler This evens is triggered by the underlying TCPServer Component when a connected client has some data ready to be processed. Here we simply fire a cooresponding write event to the cooresponding matching client which we lookup using the socket object as the key to determinte the unique id. """ client = self._clients[sock] self.fire(write(data), client.channel)
def request(self, event, message): """request Event Handler (Default) This is a default event handler to respond to ``request`` events by converting the given message to bytes and firing a ``write`` event to a hopefully connected client socket. Components may override this, but be sure to respond to ``request`` events by either explicitly calling this method or sending your own ``write`` events as the client socket. """ event.stop() message.encoding = self.encoding self.fire(write(bytes(message)))