Esempio n. 1
0
    def on_message(self, content):
        """
        Callback when message is received
        :param content: Message content, in JSON format as it was sent
        """
        message = utils.from_json(content)
        # :type message: herald.beans.MessageReceived
        sender_uid = message.get_header(herald.MESSAGE_HEADER_SENDER_UID)
        # Ignore loop-backs
        if sender_uid == self.__peer.uid:
            return
        reply_to = message.get_header(herald.MESSAGE_HEADER_REPLIES_TO)
        subject = message.subject

        extra = {
            "sender_uid": sender_uid,
            "parent_uid": message.uid
        }

        message.set_extra(extra)
        message.set_access(ACCESS_ID)

        # Log before giving message to Herald
        self._probe.store(herald.PROBE_CHANNEL_MSG_RECV, {
            "uid": message.uid,
            "timestamp": time.time(),
            "transport": ACCESS_ID,
            "subject": subject,
            "source": sender_uid,
            "repliesTo": reply_to or "",
            "transportSource": sender_uid})

        if subject.startswith(SUBJECT_DISCOVERY_PREFIX):
            # Handle discovery message
            self.__contact.herald_message(self._herald, message)
        else:
            try:
                # Is peer familiar?
                self._directory.get_peer(sender_uid)
            except KeyError:
                # Case when message by peer was sent to a group
                pass
            else:
                # All other messages are given to Herald Core
                self._herald.handle_message(message)
Esempio n. 2
0
    def on_message(self, content):
        """
        Callback when message is received
        :param content: Message content, in JSON format as it was sent
        """
        message = utils.from_json(content)
        # :type message: herald.beans.MessageReceived
        sender_uid = message.get_header(herald.MESSAGE_HEADER_SENDER_UID)
        # Ignore loop-backs
        if sender_uid == self.__peer.uid:
            return
        reply_to = message.get_header(herald.MESSAGE_HEADER_REPLIES_TO)
        subject = message.subject

        extra = {"sender_uid": sender_uid, "parent_uid": message.uid}

        message.set_extra(extra)
        message.set_access(ACCESS_ID)

        # Log before giving message to Herald
        self._probe.store(
            herald.PROBE_CHANNEL_MSG_RECV, {
                "uid": message.uid,
                "timestamp": time.time(),
                "transport": ACCESS_ID,
                "subject": subject,
                "source": sender_uid,
                "repliesTo": reply_to or "",
                "transportSource": sender_uid
            })

        if subject.startswith(SUBJECT_DISCOVERY_PREFIX):
            # Handle discovery message
            self.__contact.herald_message(self._herald, message)
        else:
            try:
                # Is peer familiar?
                self._directory.get_peer(sender_uid)
            except KeyError:
                # Case when message by peer was sent to a group
                pass
            else:
                # All other messages are given to Herald Core
                self._herald.handle_message(message)
Esempio n. 3
0
    def do_POST(self, request, response):
        """
        Handles a POST request, i.e. the reception of a message

        :param request: The HTTP request bean
        :param response: The HTTP response handler
        """
        # pylint: disable=C0103
        # Default code and content
        code = 200
        content = ""

        # Extract headers
        """
        content_type = request.get_header('content-type')
        subject = request.get_header('herald-subject')
        uid = request.get_header('herald-uid')
        reply_to = request.get_header('herald-reply-to')
        timestamp = request.get_header('herald-timestamp')
        sender_uid = request.get_header('herald-sender-uid')
        """
        content_type = request.get_header('content-type')
        subject = None
        uid = None
        reply_to = None
        timestamp = None
        sender_uid = None
        
        raw_content = to_unicode(request.read_data())
        
        # Client information
        host = utils.normalize_ip(request.get_client_address()[0])
        
        message = None
        
        if content_type != CONTENT_TYPE_JSON:
            # Raw message
            uid = str(uuid.uuid4())
            subject = herald.SUBJECT_RAW
            #msg_content = raw_content
            msg_content = raw_content
            port = -1
            extra = {'host': host, 'raw': True}     
            
            # construct a new Message bean
            message = herald.beans.MessageReceived(uid, subject, msg_content,
                                               None, None,
                                               ACCESS_ID, None, extra)                  
        else:
            # Herald message
            try:            
                received_msg = utils.from_json(raw_content)                
            except Exception as ex:
                _logger.exception("DoPOST ERROR:: %s", ex)
                
            msg_content = received_msg.content
            
            subject = received_msg.subject
            uid = received_msg.uid
            reply_to = received_msg.reply_to
            timestamp = received_msg.timestamp
            sender_uid = received_msg.sender
            
            if not uid or not subject:
                # Raw message
                uid = str(uuid.uuid4())
                subject = herald.SUBJECT_RAW
                #msg_content = raw_content
                msg_content = raw_content
                port = -1
                extra = {'host': host, 'raw': True}     
                
                # construct a new Message bean
                message = herald.beans.MessageReceived(uid, subject, msg_content,
                                               None, None,
                                               ACCESS_ID, None, extra) 
                
            else:       
                # Store sender information
                try:                 
                    port = int(received_msg.get_header(herald.transports.http.MESSAGE_HEADER_PORT))                    
                except (KeyError, ValueError, TypeError):
                    port = 80
                path = None
                if herald.transports.http.MESSAGE_HEADER_PATH in received_msg.headers:
                    path = received_msg.get_header(herald.transports.http.MESSAGE_HEADER_PATH)                
                extra = {'host': host, 'port': port,
                         'path': path,
                         'parent_uid': uid}
    
                try:
                    # Check the sender UID port
                    # (not perfect, but can avoid spoofing)
                    if not self._http_directory.check_access(
                            sender_uid, host, port):
                        # Port doesn't match: invalid UID
                        sender_uid = "<invalid>"
                except ValueError:
                    # Unknown peer UID: keep it as is
                    pass
            
                # Prepare the bean
                received_msg.add_header(herald.MESSAGE_HEADER_SENDER_UID, sender_uid)
                received_msg.set_access(ACCESS_ID)
                received_msg.set_extra(extra)
                message = received_msg
                           
        # Log before giving message to Herald
        self._probe.store(
            herald.PROBE_CHANNEL_MSG_RECV,
            {"uid": message.uid, "timestamp": time.time(),
             "transport": ACCESS_ID, "subject": message.subject,
             "source": sender_uid, "repliesTo": reply_to or "",
             "transportSource": "[{0}]:{1}".format(host, port)})

        if subject.startswith(peer_contact.SUBJECT_DISCOVERY_PREFIX):
            # Handle discovery message
            self.__contact.herald_message(self._core, message)
        else:
            # All other messages are given to Herald Core
            self._core.handle_message(message)

        # Convert content (Python 3)
        if content:
            content = jabsorb.to_jabsorb(content)

        content = to_bytes(content)

        # Send response
        response.send_content(code, content, CONTENT_TYPE_JSON)
Esempio n. 4
0
    def __on_message(self, msg):
        """
        Received an XMPP message

        :param msg: A message stanza
        """
        if msg['delay']['stamp'] is not None:
            # Delayed message: ignore
            return

        subject = msg['subject']
        if not subject:
            # No subject: not an Herald message, treat it differently
            self.__handle_raw_message(msg)
            return

        # Check if the message is from Multi-User Chat or direct
        muc_message = msg['type'] == 'groupchat' \
            or msg['from'].domain == self.__muc_service

        sender_jid = msg['from'].full
        try:
            if muc_message:
                # Group message: resource is the isolate UID
                sender_uid = msg['from'].resource
            else:
                sender_uid = self._xmpp_directory.from_jid(sender_jid).uid
        except KeyError:
            sender_uid = "<unknown>"

        try:            
            received_msg = utils.from_json(msg['body'])
            content = received_msg.content
        except ValueError:
            # Content can't be decoded, use its string representation as is
            content = msg['body']

        uid = msg['thread']
        reply_to = msg['parent_thread']

        # Extra parameters, for a reply
        extra = {"parent_uid": uid,
                 "sender_jid": sender_jid}
                 
        received_msg.add_header(herald.MESSAGE_HEADER_UID, uid)
        received_msg.add_header(herald.MESSAGE_HEADER_SENDER_UID, sender_uid)
        received_msg.add_header(herald.MESSAGE_HEADER_REPLIES_TO, reply_to)
        received_msg.set_content(content)
        received_msg.set_access(self._access_id)
        received_msg.set_extra(extra)
        
        # Call back the core service
        message = received_msg

        # Log before giving message to Herald
        self._probe.store(
            herald.PROBE_CHANNEL_MSG_RECV,
            {"uid": message.uid, "timestamp": time.time(),
             "transport": ACCESS_ID, "subject": message.subject,
             "source": sender_uid, "repliesTo": reply_to or "",
             "transportSource": str(sender_jid)})

        if subject.startswith(peer_contact.SUBJECT_DISCOVERY_PREFIX):
            # Handle discovery message
            self.__contact.herald_message(self._herald, message)
        else:
            # All other messages are given to Herald Core
            self._herald.handle_message(message)
Esempio n. 5
0
    def do_POST(self, request, response):
        """
        Handles a POST request, i.e. the reception of a message

        :param request: The HTTP request bean
        :param response: The HTTP response handler
        """
        # pylint: disable=C0103
        # Default code and content
        code = 200
        content = ""

        # Extract headers
        """
        content_type = request.get_header('content-type')
        subject = request.get_header('herald-subject')
        uid = request.get_header('herald-uid')
        reply_to = request.get_header('herald-reply-to')
        timestamp = request.get_header('herald-timestamp')
        sender_uid = request.get_header('herald-sender-uid')
        """
        content_type = request.get_header('content-type')
        subject = None
        uid = None
        reply_to = None
        timestamp = None
        sender_uid = None

        raw_content = to_unicode(request.read_data())

        # Client information
        host = utils.normalize_ip(request.get_client_address()[0])

        message = None

        if content_type != CONTENT_TYPE_JSON:
            # Raw message
            uid = str(uuid.uuid4())
            subject = herald.SUBJECT_RAW
            #msg_content = raw_content
            msg_content = raw_content
            port = -1
            extra = {'host': host, 'raw': True}

            # construct a new Message bean
            message = herald.beans.MessageReceived(uid, subject, msg_content,
                                                   None, None, ACCESS_ID, None,
                                                   extra)
        else:
            # Herald message
            try:
                received_msg = utils.from_json(raw_content)
            except Exception as ex:
                _logger.exception("DoPOST ERROR:: %s", ex)

            msg_content = received_msg.content

            subject = received_msg.subject
            uid = received_msg.uid
            reply_to = received_msg.reply_to
            timestamp = received_msg.timestamp
            sender_uid = received_msg.sender

            if not uid or not subject:
                # Raw message
                uid = str(uuid.uuid4())
                subject = herald.SUBJECT_RAW
                #msg_content = raw_content
                msg_content = raw_content
                port = -1
                extra = {'host': host, 'raw': True}

                # construct a new Message bean
                message = herald.beans.MessageReceived(uid, subject,
                                                       msg_content, None, None,
                                                       ACCESS_ID, None, extra)

            else:
                # Store sender information
                try:
                    port = int(
                        received_msg.get_header(
                            herald.transports.http.MESSAGE_HEADER_PORT))
                except (KeyError, ValueError, TypeError):
                    port = 80
                path = None
                if herald.transports.http.MESSAGE_HEADER_PATH in received_msg.headers:
                    path = received_msg.get_header(
                        herald.transports.http.MESSAGE_HEADER_PATH)
                extra = {
                    'host': host,
                    'port': port,
                    'path': path,
                    'parent_uid': uid
                }

                try:
                    # Check the sender UID port
                    # (not perfect, but can avoid spoofing)
                    if not self._http_directory.check_access(
                            sender_uid, host, port):
                        # Port doesn't match: invalid UID
                        sender_uid = "<invalid>"
                except ValueError:
                    # Unknown peer UID: keep it as is
                    pass

                # Prepare the bean
                received_msg.add_header(herald.MESSAGE_HEADER_SENDER_UID,
                                        sender_uid)
                received_msg.set_access(ACCESS_ID)
                received_msg.set_extra(extra)
                message = received_msg

        # Log before giving message to Herald
        self._probe.store(
            herald.PROBE_CHANNEL_MSG_RECV, {
                "uid": message.uid,
                "timestamp": time.time(),
                "transport": ACCESS_ID,
                "subject": message.subject,
                "source": sender_uid,
                "repliesTo": reply_to or "",
                "transportSource": "[{0}]:{1}".format(host, port)
            })

        if subject.startswith(peer_contact.SUBJECT_DISCOVERY_PREFIX):
            # Handle discovery message
            self.__contact.herald_message(self._core, message)
        else:
            # All other messages are given to Herald Core
            self._core.handle_message(message)

        # Convert content (Python 3)
        if content:
            content = jabsorb.to_jabsorb(content)

        content = to_bytes(content)

        # Send response
        response.send_content(code, content, CONTENT_TYPE_JSON)
Esempio n. 6
0
    def __on_message(self, msg):
        """
        Received an XMPP message

        :param msg: A message stanza
        """
        if msg['delay']['stamp'] is not None:
            # Delayed message: ignore
            return

        subject = msg['subject']
        if not subject:
            # No subject: not an Herald message, treat it differently
            self.__handle_raw_message(msg)
            return

        # Check if the message is from Multi-User Chat or direct
        muc_message = msg['type'] == 'groupchat' \
            or msg['from'].domain == self.__muc_service

        sender_jid = msg['from'].full
        try:
            if muc_message:
                # Group message: resource is the isolate UID
                sender_uid = msg['from'].resource
            else:
                sender_uid = self._xmpp_directory.from_jid(sender_jid).uid
        except KeyError:
            sender_uid = "<unknown>"

        try:
            received_msg = utils.from_json(msg['body'])
            content = received_msg.content
        except ValueError:
            # Content can't be decoded, use its string representation as is
            content = msg['body']

        uid = msg['thread']
        reply_to = msg['parent_thread']

        # Extra parameters, for a reply
        extra = {"parent_uid": uid, "sender_jid": sender_jid}

        received_msg.add_header(herald.MESSAGE_HEADER_UID, uid)
        received_msg.add_header(herald.MESSAGE_HEADER_SENDER_UID, sender_uid)
        received_msg.add_header(herald.MESSAGE_HEADER_REPLIES_TO, reply_to)
        received_msg.set_content(content)
        received_msg.set_access(self._access_id)
        received_msg.set_extra(extra)

        # Call back the core service
        message = received_msg

        # Log before giving message to Herald
        self._probe.store(
            herald.PROBE_CHANNEL_MSG_RECV, {
                "uid": message.uid,
                "timestamp": time.time(),
                "transport": ACCESS_ID,
                "subject": message.subject,
                "source": sender_uid,
                "repliesTo": reply_to or "",
                "transportSource": str(sender_jid)
            })

        if subject.startswith(peer_contact.SUBJECT_DISCOVERY_PREFIX):
            # Handle discovery message
            self.__contact.herald_message(self._herald, message)
        else:
            # All other messages are given to Herald Core
            self._herald.handle_message(message)