def run(self): """Run the event queue processing loop in its own thread""" while not self._exit.isSet(): self._active.wait() event = self.queue.get() if event is StopProcessing: break elif event is ProcessEvents: if self._waiting: preserved = [] try: unhandled = self.handle(self._waiting) if not isinstance(unhandled, (list, type(None))): raise ValueError("%s handler must return a list of unhandled events or None" % self.__class__.__name__) if unhandled is not None: preserved = unhandled # preserve the unhandled events that the handler returned except Exception: log.error("exception happened during event handling") log.err() self._waiting = preserved elif event is DiscardEvents: self._waiting = [] else: if getattr(event, 'high_priority', False): try: self.handle([event]) except Exception: log.error("exception happened during high priority event handling") log.err() finally: del event # do not reference this event until the next event arrives, in order to allow it to be released else: self._waiting.append(event)
def _EH_CallFunctionEvent(self, event): try: event.function(*event.args, **event.kw) except: log.error('Exception occurred while calling %r in the %r thread' % (event.function, current_thread().name)) log.err()
def post_notification(self, name, sender=UnknownSender, data=NotificationData()): """ Post a notification which will be delivered to all observers whose subscription matches the name and sender attributes of the notification. """ notification = Notification(name, sender, data) notification.center = self queue = self.queue queue.append(notification) if len(queue) > 1: # This is true if we post a notification from inside a notification handler return empty_set = set() while queue: notification = queue[0] observers = (self.observers.get((Any, Any), empty_set) | self.observers.get((Any, notification.sender), empty_set) | self.observers.get((notification.name, Any), empty_set) | self.observers.get((notification.name, notification.sender), empty_set)) for observer in observers: try: observer.handle_notification(notification) except Exception: log.error("Exception occurred in observer %r while handling notification %r" % (observer, notification.name)) log.err() queue.popleft()
def start(self): for app in ApplicationRegistry(): try: app().start() except Exception, e: log.warning('Error starting application: %s' % e) log.err()
def start(self): interface = WebServerConfig.local_ip port = WebServerConfig.local_port cert_path = WebServerConfig.certificate.normalized if WebServerConfig.certificate else None cert_chain_path = WebServerConfig.certificate_chain.normalized if WebServerConfig.certificate_chain else None if cert_path is not None: if not os.path.isfile(cert_path): log.error('Certificate file %s could not be found' % cert_path) return try: ssl_ctx_factory = DefaultOpenSSLContextFactory(cert_path, cert_path) except Exception: log.exception('Creating TLS context') log.err() return if cert_chain_path is not None: if not os.path.isfile(cert_chain_path): log.error('Certificate chain file %s could not be found' % cert_chain_path) return ssl_ctx = ssl_ctx_factory.getContext() try: ssl_ctx.use_certificate_chain_file(cert_chain_path) except Exception: log.exception('Setting TLS certificate chain file') log.err() return self.listener = reactor.listenSSL(port, self.site, ssl_ctx_factory, backlog=511, interface=interface) scheme = 'https' else: self.listener = reactor.listenTCP(port, self.site, backlog=511, interface=interface) scheme = 'http' port = self.listener.getHost().port self.__dict__['url'] = '%s://%s:%d' % (scheme, WebServerConfig.hostname or interface.normalized, port) log.msg('Web server listening for requests on: %s' % self.url)
def _EH_CallFunctionEvent(self, event): try: event.function(*event.args, **event.kw) except: log.error( 'Exception occured while calling function %s in the GUI thread' % event.function.__name__) log.err()
def update_statistics(self, stats): log.debug("Got statistics: %s" % stats) if stats["start_time"] is not None: for accounting in self.accounting: try: accounting.do_accounting(stats) except Exception, e: log.error("An unhandled error occured while doing accounting: %s" % e) log.err()
def load_applications(): load_builtin_applications() load_extra_applications() for app in ApplicationRegistry(): try: app() except Exception, e: log.warning('Error loading application: %s' % e) log.err()
def _CH_process_results(self, command): for file in (f for f in command.files if not f.closed): try: _bonjour.DNSServiceProcessResult(file.file) except: # Should we close the file? The documentation doesn't say anything about this. -Luci log.err() for file in command.files: file.active = False self._files = [f for f in self._files if not f.closed] self._select_proc.kill(RestartSelect)
def update_statistics(self, stats): log.debug("Got statistics: %s" % stats) if stats["start_time"] is not None: for accounting in self.accounting: try: accounting.do_accounting(stats) except Exception, e: log.error( "An unhandled error occured while doing accounting: %s" % e) log.err()
def lookup(self, key): network = self.networks.get("sip_proxy", None) if network is None: return None try: node = network.lookup_node(key) except LookupError: node = None except Exception: log.err() node = None return node
def stop(self): self.authorization_handler.stop() notification_center = NotificationCenter() notification_center.remove_observer(self, name='SIPSessionNewIncoming') notification_center.remove_observer(self, name='SIPIncomingSubscriptionGotSubscribe') notification_center.remove_observer(self, name='SIPIncomingReferralGotRefer') notification_center.remove_observer(self, name='SIPIncomingRequestGotRequest') for app in ApplicationRegistry(): try: app().stop() except Exception, e: log.warning('Error stopping application: %s' % e) log.err()
def save(self): """ Use the ConfigurationManager to store the object under its id in the specified group or top-level otherwise, depending on whether group is None. This method will also post a CFGSettingsObjectDidChange notification, regardless of whether the settings have been saved to persistent storage or not. If the save does fail, a CFGManagerSaveFailed notification is posted as well. """ if self.__state__ == 'deleted': return configuration = ConfigurationManager() notification_center = NotificationCenter() oldkey = self.__oldkey__ # save this here as get_modified will reset it modified_id = self.__class__.__id__.get_modified(self) if isinstance(self.__class__.__id__, SettingsObjectID) else None modified_settings = self.get_modified() if not modified_id and not modified_settings and self.__state__ != 'new': return if self.__state__ == 'new': configuration.update(self.__key__, self.__getstate__()) self.__state__ = 'active' notification_center.post_notification('CFGSettingsObjectWasActivated', sender=self) notification_center.post_notification('CFGSettingsObjectWasCreated', sender=self) modified_data = None elif not modified_id and all(isinstance(self.__settings__[key], RuntimeSetting) for key in modified_settings): notification_center.post_notification('CFGSettingsObjectDidChange', sender=self, data=NotificationData(modified=modified_settings)) return else: if modified_id: configuration.rename(oldkey, self.__key__) if modified_settings: configuration.update(self.__key__, self.__getstate__()) modified_data = modified_settings or {} if modified_id: modified_data['__id__'] = modified_id notification_center.post_notification('CFGSettingsObjectDidChange', sender=self, data=NotificationData(modified=modified_data)) try: configuration.save() except Exception, e: log.err() notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='save', modified=modified_data, exception=e))
def run(self): """Run the event queue processing loop in its own thread""" while not self._exit.isSet(): self._active.wait() event = self.queue.get() if event is StopProcessing: break try: self.handle(event) except Exception: log.error("exception happened during event handling") log.err() finally: del event # do not reference this event until the next event arrives, in order to allow it to be released
def stop(self): self.authorization_handler.stop() notification_center = NotificationCenter() notification_center.remove_observer(self, name='SIPSessionNewIncoming') notification_center.remove_observer( self, name='SIPIncomingSubscriptionGotSubscribe') notification_center.remove_observer(self, name='SIPIncomingReferralGotRefer') notification_center.remove_observer( self, name='SIPIncomingRequestGotRequest') for app in ApplicationRegistry(): try: app().stop() except Exception, e: log.warning('Error stopping application: %s' % e) log.err()
def delete(self): """Remove the group from the persistent storage.""" if self.__state__ == 'deleted': return self.__state__ = 'deleted' configuration = ConfigurationManager() notification_center = NotificationCenter() configuration.delete(self.__key__) notification_center.post_notification('VirtualGroupWasDeleted', sender=self) try: configuration.save() except Exception, e: log.err() notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='delete', exception=e))
def save(self): """ Store the group into persistent storage (local). This method will post the VirtualGroupWasCreated and VirtualGroupWasActivated notifications on the first save or a VirtualGroupDidChange notification on subsequent saves. A CFGManagerSaveFailed notification is posted if saving to the persistent configuration storage fails. """ if self.__state__ == 'deleted': return modified_settings = self.get_modified() if not modified_settings and self.__state__ != 'new': return configuration = ConfigurationManager() notification_center = NotificationCenter() if self.__state__ == 'new': configuration.update(self.__key__, self.__getstate__()) self.__state__ = 'active' modified_data = None notification_center.post_notification('VirtualGroupWasActivated', sender=self) notification_center.post_notification('VirtualGroupWasCreated', sender=self) else: configuration.update(self.__key__, self.__getstate__()) notification_center.post_notification( 'VirtualGroupDidChange', sender=self, data=NotificationData(modified=modified_settings)) modified_data = modified_settings try: configuration.save() except Exception as e: log.err() notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData( object=self, operation='save', modified=modified_data, exception=e))
def dial(): to = request.args.get('to', None) if to is None: return error_response(400, 'destionation not specified') account_id = request.args.get('from', None) account = None if account_id is not None: try: account = AccountManager().get_account(account_id) except KeyError: return error_response(400, 'invalid account specified') try: SessionManager().start_call(None, to, [AudioStream()], account=account) except Exception, e: log.error('Starting call to %s: %s' % (to, e)) log.err() return error_response(400, str(e))
def delete(self): """ Remove this object from the persistent configuration. """ if self.__id__ is self.__class__.__id__: raise TypeError("cannot delete %s instance with default id" % self.__class__.__name__) if self.__state__ == 'deleted': return self.__state__ = 'deleted' configuration = ConfigurationManager() notification_center = NotificationCenter() configuration.delete(self.__oldkey__) # we need the key that wasn't yet saved notification_center.post_notification('CFGSettingsObjectWasDeleted', sender=self) try: configuration.save() except Exception, e: log.err() notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='delete', exception=e))
def lineReceived(self, line): if line == 'pong': self._queued_keepalives -= 1 return if self.command is None: try: command, seq = line.split() except ValueError: log.error("Could not decode command/sequence number pair from dispatcher: %s" % line) return if command in self.required_headers: self.command = command self.seq = seq self.headers = DecodingDict() else: log.error("Unknown command: %s" % command) self.transport.write("%s error\r\n" % seq) elif line == "": try: missing_headers = self.required_headers[self.command].difference(self.headers) if missing_headers: for header in missing_headers: log.error("Missing mandatory header '%s' from '%s' command" % (header, self.command)) response = "error" else: try: response = self.factory.parent.got_command(self.factory.host, self.command, self.headers) except: log.err() response = "error" finally: self.transport.write("%s %s\r\n" % (self.seq, response)) self.command = None else: try: name, value = line.split(": ", 1) except ValueError: log.error("Unable to parse header: %s" % line) else: try: self.headers[name] = value except DecodingError, e: log.error("Could not decode header: %s" % e)
def format_log_message(request, response, reason): msg = '' info = '' try: msg = format_access_record(request, response) code = getattr(response, 'code', None) info += log_format_request_headers(code, request) info += log_format_request_body(code, request) info += log_format_response_headers(code, response) info += log_format_response_body(code, response) info += log_format_stacktrace(code, reason) except Exception: log.error('Formatting log message failed') log.err() if info[-1:]=='\n': info = info[:-1] if info: info = '\n' + info return msg + info
class Backend(object): """Configuration datatype, used to select a backend module from the configuration file.""" def __new__(typ, value): value = value.lower() try: return __import__('xcap.interfaces.backend.%s' % value, globals(), locals(), ['']) except (ImportError, AssertionError), e: log.fatal("Cannot load '%s' backend module: %s" % (value, str(e))) sys.exit(1) except Exception, e: log.err() sys.exit(1)
def start(self): interface = WebServerConfig.local_ip port = WebServerConfig.local_port cert_path = WebServerConfig.certificate.normalized if WebServerConfig.certificate else None if cert_path is not None: if not os.path.isfile(cert_path): log.error('Certificate file %s could not be found' % cert_path) return try: ssl_context = DefaultOpenSSLContextFactory(cert_path, cert_path) except Exception: log.exception('Creating SSL context') log.err() return self.listener = reactor.listenSSL(port, self.site, ssl_context, backlog=511, interface=interface) scheme = 'https' else: self.listener = reactor.listenTCP(port, self.site, backlog=511, interface=interface) scheme = 'http' port = self.listener.getHost().port self.__dict__['url'] = '%s://%s:%d' % (scheme, WebServerConfig.hostname or interface.normalized, port) log.msg('Web server listening for requests on: %s' % self.url)
def delete(self): """Remove the group from the persistent storage.""" if self.__state__ == 'deleted': return self.__state__ = 'deleted' configuration = ConfigurationManager() notification_center = NotificationCenter() configuration.delete(self.__key__) notification_center.post_notification('VirtualGroupWasDeleted', sender=self) try: configuration.save() except Exception as e: log.err() notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData( object=self, operation='delete', exception=e))
def post_notification(self, name, sender=UnknownSender, data=NotificationData()): """ Post a notification which will be delivered to all observers whose subscription matches the name and sender attributes of the notification. """ notification = Notification(name, sender, data) notification.center = self queue = self.queue queue.append(notification) if len( queue ) > 1: # This is true if we post a notification from inside a notification handler return empty_set = set() while queue: notification = queue[0] observers = ( self.observers.get((Any, Any), empty_set) | self.observers.get( (Any, notification.sender), empty_set) | self.observers.get( (notification.name, Any), empty_set) | self.observers.get( (notification.name, notification.sender), empty_set)) for observer in observers: try: observer.handle_notification(notification) except Exception: log.error( "Exception occurred in observer %r while handling notification %r" % (observer, notification.name)) log.err() queue.popleft()
def save(self): """ Store the group into persistent storage (local). This method will post the VirtualGroupWasCreated and VirtualGroupWasActivated notifications on the first save or a VirtualGroupDidChange notification on subsequent saves. A CFGManagerSaveFailed notification is posted if saving to the persistent configuration storage fails. """ if self.__state__ == 'deleted': return modified_settings = self.get_modified() if not modified_settings and self.__state__ != 'new': return configuration = ConfigurationManager() notification_center = NotificationCenter() if self.__state__ == 'new': configuration.update(self.__key__, self.__getstate__()) self.__state__ = 'active' modified_data = None notification_center.post_notification('VirtualGroupWasActivated', sender=self) notification_center.post_notification('VirtualGroupWasCreated', sender=self) else: configuration.update(self.__key__, self.__getstate__()) notification_center.post_notification('VirtualGroupDidChange', sender=self, data=NotificationData(modified=modified_settings)) modified_data = modified_settings try: configuration.save() except Exception, e: log.err() notification_center.post_notification('CFGManagerSaveFailed', sender=configuration, data=NotificationData(object=self, operation='save', modified=modified_data, exception=e))
log.fatal("Cannot start %s: %s" % (fullname, e)) sys.exit(1) log.start_syslog(name) if ipstreamer.cfg_filename: log.msg("Starting %s %s, config=%s" % (fullname, version, ipstreamer.cfg_filename)) else: log.fatal("Starting %s %s, with no configuration file" % (fullname, version)) sys.exit(1) try: from ipstreamer.server import IPStreamerDaemon server = IPStreamerDaemon() except Exception, e: log.fatal("failed to start %s" % fullname) log.err() sys.exit(1) def stop_server(*args): if not server.stopping: log.msg('Stopping %s...' % fullname) server.stop() def kill_server(*args): log.msg('Killing %s...' % fullname) os._exit(1) process.signals.add_handler(signal.SIGTERM, stop_server) process.signals.add_handler(signal.SIGINT, stop_server) try:
class MSRPTransport(GreenTransportBase): protocol_class = MSRPProtocol_withLogging def __init__(self, local_uri, logger, use_sessmatch=False): GreenTransportBase.__init__(self) if local_uri is not None and not isinstance(local_uri, protocol.URI): raise TypeError('Not MSRP URI instance: %r' % (local_uri, )) # The following members define To-Path and From-Path headers as following: # * Outgoing request: # From-Path: local_uri # To-Path: local_path + remote_path + [remote_uri] # * Incoming request: # From-Path: remote_path + remote_uri # To-Path: remote_path + local_path + [local_uri] # XXX self.local_uri = local_uri if logger is None: logger = Logger() self.logger = logger self.local_path = [] self.remote_uri = None self.remote_path = [] self.use_sessmatch = use_sessmatch self._msrpdata = None def next_host(self): if self.local_path: return self.local_path[0] return self.full_remote_path[0] def set_local_path(self, lst): self.local_path = lst @property def full_local_path(self): "suitable to put into INVITE" return self.local_path + [self.local_uri] @property def full_remote_path(self): return self.remote_path + [self.remote_uri] def make_request(self, method): transaction_id = '%x' % random.getrandbits(64) chunk = protocol.MSRPData(transaction_id=transaction_id, method=method) chunk.add_header( protocol.ToPathHeader(self.local_path + self.remote_path + [self.remote_uri])) chunk.add_header(protocol.FromPathHeader([self.local_uri])) return chunk def make_send_request(self, message_id=None, data='', start=1, end=None, length=None): chunk = self.make_request('SEND') if end is None: end = start - 1 + len(data) if length is None: length = start - 1 + len(data) if end == length != '*': contflag = '$' else: contflag = '+' chunk.add_header( protocol.ByteRangeHeader( (start, end if length <= 2048 else None, length))) if message_id is None: message_id = '%x' % random.getrandbits(64) chunk.add_header(protocol.MessageIDHeader(message_id)) chunk.data = data chunk.contflag = contflag return chunk def _data_start(self, data): self._queue.send((data_start, data)) def _data_end(self, continuation): self._queue.send((data_end, continuation)) def _data_write(self, contents, final): if final: self._queue.send((data_final_write, contents)) else: self._queue.send((data_write, contents)) def write(self, bytes, wait=True): """Write `bytes' to the socket. If `wait' is true, wait for an operation to complete""" self.logger.report_out(bytes, self.transport) return GreenTransportBase.write(self, bytes, wait) def write_chunk(self, chunk, wait=True): trailer = chunk.encode_start() footer = chunk.encode_end(chunk.contflag) self.write(trailer + chunk.data + footer, wait=wait) self.logger.sent_new_chunk(trailer, self, chunk=chunk) if chunk.data: self.logger.sent_chunk_data(chunk.data, self, chunk.transaction_id) self.logger.sent_chunk_end(footer, self, chunk.transaction_id) def read_chunk(self, max_size=1024 * 1024 * 4): """Wait for a new chunk and return it. If there was an error, close the connection and raise ChunkParseError. In case of unintelligible input, lose the connection and return None. When the connection is closed, raise the reason of the closure (e.g. ConnectionDone). """ assert max_size > 0 if self._msrpdata is None: func, msrpdata = self._wait() if func != data_start: self.logger.debug('Bad data: %r %r' % (func, msrpdata)) self.loseConnection() raise ChunkParseError else: msrpdata = self._msrpdata data = msrpdata.data func, param = self._wait() while func == data_write: data += param if len(data) > max_size: self.logger.debug('Chunk is too big (max_size=%d bytes)' % max_size) self.loseConnection() raise ChunkParseError func, param = self._wait() if func == data_final_write: data += param func, param = self._wait() if func != data_end: self.logger.debug('Bad data: %r %s' % (func, repr(param)[:100])) self.loseConnection() raise ChunkParseError if param not in "$+#": self.logger.debug('Bad data: %r %s' % (func, repr(param)[:100])) self.loseConnection() raise ChunkParseError msrpdata.data = data msrpdata.contflag = param self._msrpdata = None self.logger.debug('read_chunk -> %r' % (msrpdata, )) return msrpdata def _set_full_remote_path(self, full_remote_path): "as received in response to INVITE" if not all(isinstance(x, protocol.URI) for x in full_remote_path): raise TypeError('Not all elements are MSRP URI: %r' % full_remote_path) self.remote_uri = full_remote_path[-1] self.remote_path = full_remote_path[:-1] def bind(self, full_remote_path): self._set_full_remote_path(full_remote_path) chunk = self.make_send_request() self.write_chunk(chunk) # With some ACM implementations both parties may think they are active, # so they will both send an empty SEND request. -Saul while True: chunk = self.read_chunk() if chunk.code is None: # This was not a response, it was a request if chunk.method == 'SEND' and not chunk.data: self.write_response(chunk, 200, 'OK') else: self.loseConnection(wait=False) raise MSRPNoSuchSessionError( 'Chunk received while binding session: %s' % chunk) elif chunk.code != 200: self.loseConnection(wait=False) raise MSRPNoSuchSessionError('Cannot bind session: %s' % chunk) else: break def write_response(self, chunk, code, comment, wait=True): """Generate and write the response, lose the connection in case of error""" try: response = make_response(chunk, code, comment) except ChunkParseError, ex: log.error('Failed to generate a response: %s' % ex) self.loseConnection(wait=False) raise except Exception: log.error('Failed to generate a response') log.err() self.loseConnection(wait=False) raise
def _EH_CallFunctionEvent(self, event): try: event.function(*event.args, **event.kw) except: log.error('Exception occured while calling function %s in the GUI thread' % event.function.__name__) log.err()
def callObject_(self, callable): try: callable() except: log.err()
def callTimerObject_(self, timer): callable = timer.userInfo() try: callable() except: log.err()