def on_close(self): global clientsList if not clientsList: log.warning("Clients list not found") return clientsList.remove(self.client) log.debug("WebSocket closed for client %s" % self.client)
def post(self): # arguments = { k.lower(): self.get_argument(k) for k in self.request.arguments } first_name = self.get_argument("name", "") last_name = self.get_argument("lastname", "") email = self.get_argument("email", "") subject = self.get_argument("subject", "") message = self.get_argument("question", "") topic = self.get_argument("topic", "") topics = topic.replace(',', '\n') log.debug( f'''{first_name}, {last_name}, {email}, {topics}, {message}''') try: token = DB.add_new_request({ 'email': email, 'last_name': last_name, 'first_name': first_name, 'subject': subject, 'message': message, 'topics': topics, }) except Exception as e: log.error(f'''Error adding form record: {e}''') self.write( 'There was an error submitting your form. Please try again.') self.set_status(500) self.flush() self.finish() return try: if token: send_confirmation_email( base_url=BASE_URL, token=token, email=email, last_name=last_name, first_name=first_name, subject=subject, message=message, topics=topics, ) self.set_status(200) self.flush() self.finish() return else: self.write( 'There was an error submitting your form. Please try again.' ) self.set_status(500) self.flush() self.finish() return except Exception as e: log.error(f'''Error sending confirmation email to "{email}"''') self.write( 'There was an error submitting your form. Please try again.') self.set_status(500) self.flush() self.finish() return
def on_message(self, message): data = json.loads(message) for command, args in data.iteritems(): if command in self.command: log.debug("Command executed: %s(%s)" % (command, args)) self.command[command](args) else: log.error("Command % s not found" % command)
def control_message(self, event): """ Respond to control message from main application thread Currently unused. :param event: anything. """ log.debug("control message: %s", event)
async def open(self, *args, **kwargs): q = self.request.query_arguments if self.application.listener_key and ('key' not in q or q['key'][0].decode() != self.application.listener_key): return self.send_error(403) log.debug("Opened socket. %s", json.dumps(q)) # self.application.db_changed.connect(self.send_event) queue.sender = self await self.sendout()
def open(self, *args): global clientsList self.client = User() clientsList.add(self.client) self.stream.set_nodelay(True) self.write_message(json.dumps({ "detail": { "uuid": self.client.uuid } })) self.timeline_th = None log.debug("WebSocket opened client %s" % self.client)
def send_ping(self, *args, **kwargs): """ Sends ping message Runs periodically. """ log.debug("Sending ping") message = PING_MESSAGE try: self.udp.send(message) except Exception: log.exception("Failed to send ping") self.stop()
def __init__(self, address='', port=8080, loglevel=logging.WARNING, mounting_point='', listener_key=None, notifier_key=None): self.listener_key = listener_key self.notifier_key = notifier_key # tornado.log.enable_pretty_logging(logger=logging.getLogger('tornado')) log.setLevel(loglevel) log.debug('Initializing server') tornado.web.Application.__init__(self, [ (mounting_point + r'/send', SendHandler), (mounting_point + r'/listen', NotificationSocket), ], websocket_ping_interval=10) self.stopped = Event() self.address = address self.port = port
def stop(self): """ Stop ping agent and close pipe for communication with callee """ log.debug("Stopping Agent thread.") self.agent.stop() log.debug("Waiting for Agent thread to join us.") self.agent_thread.join() log.debug("Closing main thread part of the pipe") self.pipe.close() log.debug("Closing agent thread part of the pipe") self._agent_pipe.close() log.debug("Terminating context") self.ctx.term()
def _close(self): log.debug("Stopping periodic ping.") self.periodic_ping.stop() log.debug("Removing beacon handler.") self.loop.remove_handler(self.udp.handle.fileno()) log.debug("Closing UDP client.") self.loop.add_callback(self.udp.close) log.debug("Stopping loop from agent") self.loop.add_callback(self.loop.stop)
def reap_peers(self): """ Removes peers whose activity wasn't seen for a long time Called periodically. Sends messages through pipe to main application thread. """ now = time.time() for peer in list(self.peers.values()): if peer.expires_at < now: log.debug("reaping %s", peer.hw_address, peer.expires_at, now) self.peers.pop(peer.hw_address) msg_parts = [b"LEFT", peer.hw_address] try: self._send_to_pipe_multipart(msg_parts) except Exception: return
def _send_to_pipe_multipart(self, msg_parts): """ Handle errors while sending message to pipe as ERROR message sent to pipe Caller should catch use these messages to stop interface thread and thus agent as well. :param iterable msg_parts: A sequence of objects to send as a multipart message. :raises TypeError: after error is caught and ERROR message sent to pipe """ log.debug("Going to send %r.", msg_parts) try: self.pipe.send_multipart(msg_parts) except TypeError as err: log.error("Failed to send multipart message to pipe: %s", err) self.pipe.send_multipart( [b"ERROR", b"Failed to send a message to main thread."] ) self.stop() raise
def post(self): try: req_data = json.loads(self.request.body) except ValueError: log.debug('Unable to load request JSON.') raise tornado.web.HTTPError(400, 'Unable to load request JSON.') try: jsonschema.validate(req_data, postvalidate.schema) except jsonschema.ValidationError: log.debug('Post JSON validation failed.') raise tornado.web.HTTPError(400, 'Post JSON validation failed.') hash_id = dbi.store_grid_entry(req_data) if req_data['secret']: url = 'http://ipythonblocks.org/secret/{}' else: url = 'http://ipythonblocks.org/{}' url = url.format(hash_id) self.write({'url': url})
def start(self): """ Main entry of the thread Hooks necessary handlers to send pings, process incoming data and mark peers offline if they doesn't respond for long time. """ log.debug("Starting Agent") self.loop = tornado.ioloop.IOLoop.current() self.loop.add_handler(self.udp.handle.fileno(), self.handle_beacon, self.loop.READ) stream = ZMQStream(self.pipe, self.loop) stream.on_recv(self.control_message) pc = PeriodicCallback(self.send_ping, PING_INTERVAL * 1000) pc.start() pc = PeriodicCallback(self.reap_peers, PING_INTERVAL * 1000) pc.start() log.debug("Starting Loop") self.loop.start() log.debug("Loop ended")
def get(self, path): log = logging.getLogger(__name__) cookie_user_id = None try: cookie_user_id = int( self.get_secure_cookie(COOKIE_NAME, max_age_days=COOKIE_DURATION_DAYS)) except ValueError: pass except TypeError: pass self.clear() if cookie_user_id is None: self.set_status(403) return path = zyn_util.util.normalized_remote_path('/' + path) _, filename = zyn_util.util.split_remote_path(path) session = user_sessions.find_session(cookie_user_id) socket_id = None open_rsp = None log.debug('Raw file requested, path="{}", cookie="{}"'.format( path, cookie_user_id, )) try: socket_id = session.add_websocket(None) connection = session.sockets(socket_id).connection rsp = connection.open_file_read(path=path) if rsp.is_error(): self.set_status(400) raise RuntimeError( zyn_util.errors.error_to_string(rsp.error_code())) open_rsp = rsp.as_open_rsp() if open_rsp.type_of_file == zyn_util.connection.FILE_TYPE_RANDOM_ACCESS: rsp, data = connection.read_file(open_rsp.node_id, 0, open_rsp.size) if rsp.is_error(): self.set_status(500) raise RuntimeError( zyn_util.errors.error_to_string(rsp.error_code())) self.write(data) elif open_rsp.type_of_file == zyn_util.connection.FILE_TYPE_BLOB: if open_rsp.size > open_rsp.block_size: # For large files, server should sent the content is blocks self.set_status(500) raise RuntimeError('Large file download not implemented') rsp, data = connection.read_file(open_rsp.node_id, 0, open_rsp.size) if rsp.is_error(): self.set_status(500) raise RuntimeError( zyn_util.errors.error_to_string(rsp.error_code())) self.write(data) else: self.set_status(500) raise RuntimeError() self.set_header('Content-Disposition', 'attachment; filename=' + filename) except RuntimeError as e: self.write(str(e)) finally: if open_rsp is not None: connection.close_file(open_rsp.node_id) if socket_id is not None: session.remove_websocket(socket_id)
def action(server, sniffer): log.debug("Configure sniffer %s on %s" % (sniffer.__class__.__name__, server.name)) if data['enable']: sniffer.capture_start() else: sniffer.capture_stop()
def handle_beacon(self, fd, event): """ Reads response from nodes Creates :class:`Peer` objects and tracks them in `self.peers`. Finally sends messages through pipe to main application thread. :param fd: not used :param event: not used """ log.debug("Waiting for a beacon.") try: data, host = self._next_packet() except ReceiveTimeout: msg_parts = [b"RECEIVE_TIMEOUT"] try: self._send_to_pipe_multipart(msg_parts) except Exception: return return if data == PING_MESSAGE: log.debug("Ignoring ping message received from network from %s.", host) return log.debug("Received a beacon from %s.", host) ip_address, device_id = decode_discovery_response(data) # if host != ip_address: # print("Host {} != ip_address {}".format(host, ip_address)) log.debug("Getting hardware address of %s.", ip_address) hw_address = self.get_mac_address(ip_address) if hw_address is None: log.error("Unable to get HW adress of %s.", ip_address) msg_parts = [b"ERROR", device_id, ip_address] try: self._send_to_pipe_multipart(msg_parts) except Exception: return return # print("Host {} has MAC address {}".format(ip_address, hw_address)) if hw_address in self.peers: log.debug("Peer %s seen before.", hw_address) return self.process_seen_peer(hw_address, device_id, ip_address) else: log.debug("Never seen %s before.", hw_address) return self.process_new_peer(hw_address, device_id, ip_address)
def xdiscover(find_id=None, destination_host=None, timeout=None): """Generator discover all devices or device of specific id Device can be specified either by id or by host. :param str find_id: (optional) Device id to look for. If not set first node that responded is returned. :param str destination_host: (optional) Ping selected node only. :param float timeout: (optional) Number of seconds until discovery timeouts. :return: namedtuple of hardware address, device id and host name. :rtype: namedtuple :raises DiscoverTimeout: timeout exceeded while waiting for a device """ assert not (find_id and destination_host) receive_timeout = None if timeout: receive_timeout = timeout / 2 hw_address = device_id = ip_address = None start = monotonic() with DiscoveryInterface( destination_host, receive_timeout=receive_timeout ) as interface: while True: try: response = interface.recv() except KeyboardInterrupt: raise assert len(response) > 0 event = response.pop(0) if event == b"JOINED": assert len(response) == 3 hw_address, device_id, ip_address = response if isinstance(hw_address, bytes): hw_address = hw_address.decode("utf-8") if isinstance(device_id, bytes): device_id = device_id.decode("utf-8") if isinstance(ip_address, bytes): ip_address = ip_address.decode("utf-8") if find_id is None or find_id == device_id: DiscoveredDevice = collections.namedtuple( "DiscoveredDevice", ["hw_address", "id", "ip_address"] ) yield DiscoveredDevice(hw_address, device_id, ip_address) if find_id == device_id: return else: log.debug( "Device id {} ({}) joined: {}".format( device_id, hw_address, ip_address ) ) if timeout and (monotonic() - start) > timeout: raise DiscoverTimeout() elif event == b"ERROR": log.error( "Received error from discovery. Parameters: {}".format(response) ) raise Exception("Error") elif event == b"RECEIVE_TIMEOUT": assert timeout if monotonic() - start > timeout: raise DiscoverTimeout() else: continue elif event == b"ALIVE": if timeout and (monotonic() - start) > timeout: raise DiscoverTimeout() else: log.error("Unknown event: {}".format(event)) log.error("Parameters: {}".format(response)) raise Exception("Unknown event")
def start(self): log.debug('Starting server at %s:%d' % (self.address, self.port)) self.listen(self.port, self.address) self.io_loop = tornado.ioloop.IOLoop.current() self.io_loop.start() self.stopped.set()
def on_close(self): log.debug("Closed socket: code: {s.close_code}, reason: {s.close_reason}".format(s=self)) queue.sender = None
def action(server, sniffer): log.debug("Cleanup traces on sniffer %s on %s" % (sniffer.__class__.__name__, server.name)) sniffer.clean()
def handle_beacon(self, fd, event): """ Reads response from nodes Creates :class:`Peer` objects and tracks them in `self.peers`. Finally sends messages through pipe to main application thread. :param fd: not used :param event: not used """ log.debug("Waiting for a beacon.") data, host = self.udp.recv(64) if data == PING_MESSAGE: log.debug("Ignoring ping message received from network from %s.", host) return log.debug("Received a beacon from %s.", host) ip_address, device_name = decode_discovery_response(data) # if host != ip_address: # print("Host {} != ip_address {}".format(host, ip_address)) log.debug("Getting hardware address of %s.", ip_address) hw_address = arpreq(ip_address) if is_py3 and not isinstance(hw_address, bytes): hw_address = bytes(hw_address, "utf-8") if hw_address is None: log.error("Unable to get HW adress of %s.", ip_address) msg_parts = [b"ERROR", device_name, ip_address] try: self._send_to_pipe_multipart(msg_parts) except Exception: return # print("Host {} has MAC address {}".format(ip_address, hw_address)) if hw_address in self.peers: log.debug("Peer %s seen before.", hw_address) self.peers[hw_address].is_alive() if device_name != self.peers[hw_address].device_name: old_device_name = self.peers[hw_address].device_name self.peers[hw_address].device_name = device_name msg_parts = [ b"RENAMED", hw_address, old_device_name, device_name ] try: self._send_to_pipe_multipart(msg_parts) except Exception: return if ip_address != self.peers[hw_address].ip_address: old_ip_address = self.peers[hw_address].ip_address self.peers[hw_address].ip_address = ip_address msg_parts = [ b"ADDRESS_CHANGED", hw_address, old_ip_address, ip_address ] try: self._send_to_pipe_multipart(msg_parts) except Exception: return else: log.debug("Never seen %s before.", hw_address) self.peers[hw_address] = Peer(hw_address, device_name, ip_address) msg_parts = [b"JOINED", hw_address, device_name, ip_address] try: self._send_to_pipe_multipart(msg_parts) except Exception: return
def decode_discovery_response(data): """ Decodes response for discovery """ log.debug("Received {0!r}".format(data)) if is_py3: if isinstance(data, bytes): data = bytearray(data) if not isinstance(data, bytearray): msg = "Data must be bytearray. Was {} instead".format(type(data)) raise TypeError(msg) else: if not isinstance(data, basestring): msg = "Data must be string. Was {} instead".format(type(data)) raise TypeError(msg) if len(data) < 7: msg = "Data must be longer than 7 bytes. Was {} instead.".format(len(data)) raise ValueError(msg) if data[4:6] != b"OK": msg = "Expected 'OK' in status of data message. Was {0!r} instead.".format( data[4:6] ) raise ValueError(msg) if is_py3: tail = 0 else: tail = b"\x00" if data[-1] != tail: msg = ( "Expected zero character on the end of message. " "Was {0!r} instead.".format(data[-1]) ) raise ValueError(msg) # First four bytes in reversed order ip_address_data = data[3::-1] if is_py3: ip_address_data = bytes(ip_address_data) else: # Detect if ipaddress is backport to python 2 - py2-ipaddress if ( hasattr(ipaddress, "bytes") and hasattr(ipaddress, "bytearray") and ipaddress.bytes == ipaddress.bytearray ): # py2-ipaddress differs from ipaddress by Google and python 3 # module: # Since Python 2 has no distinct bytes type, bytearray is used # instead for the "packed" (binary) address representation ip_address_data = bytearray(ip_address_data) ip_address_obj = ipaddress.ip_address(ip_address_data) ip_address_exploded = ip_address_obj.exploded if is_py3: if not isinstance(ip_address_exploded, bytes): ip_address_exploded = bytes(ip_address_exploded, "utf-8") else: ip_address_exploded = ip_address_exploded.encode("utf-8") device_id = data[6:-1] if is_py3: device_id = bytes(device_id) else: device_id = device_id.encode("utf-8") return ip_address_exploded, device_id