Example #1
0
 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)
Example #2
0
 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()
Example #4
0
 def start(self):
     for app in ApplicationRegistry():
         try:
             app().start()
         except Exception, e:
             log.warning('Error starting application: %s' % e)
             log.err()
Example #5
0
 def start(self):
     for app in ApplicationRegistry():
         try:
             app().start()
         except Exception, e:
             log.warning('Error starting application: %s' % e)
             log.err()
Example #6
0
 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)
Example #7
0
 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()
Example #8
0
 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()
Example #9
0
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()
Example #10
0
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()
Example #11
0
 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)
Example #12
0
 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()
Example #13
0
 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)
Example #14
0
 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
Example #15
0
 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
Example #16
0
 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()
Example #17
0
    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))
Example #18
0
    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))
Example #19
0
 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
Example #20
0
 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()
Example #21
0
    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))
Example #23
0
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))
Example #24
0
    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))
Example #25
0
 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)
Example #26
0
 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)
Example #27
0
    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))
Example #28
0
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
Example #29
0
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)
Example #30
0
 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()
Example #33
0
    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))
Example #34
0
            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:
Example #35
0
 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()
Example #36
0
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
Example #37
0
 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 callObject_(self, callable):
     try:
         callable()
     except:
         log.err()
 def callTimerObject_(self, timer):
     callable = timer.userInfo()
     try:
         callable()
     except:
         log.err()