Пример #1
0
    def testDoubleConvert(self):
        """
        Checks the beheavior after a second call to to_jabsorb
        """
        value = {"list": [1, 2, 3],
                 "tuple": (1, 2, 3),
                 "set": {1, 2, 3},
                 "dict": {"a": "b", "c": "d"},
                 "int": 42,
                 "float": 3.14,
                 None: None,
                 3.10: 51}

        # Double conversion: no modification on second pass
        first = jabsorb.to_jabsorb(value)
        second = jabsorb.to_jabsorb(first)
        self.assertDictEqual(second, first)

        # Double revert
        revert_second = jabsorb.from_jabsorb(second)
        revert_first = jabsorb.from_jabsorb(revert_second)

        # Check results
        self.assertDictEqual(revert_second, value)
        self.assertDictEqual(revert_first, value)
    def _simple_dispatch(self, name, params):
        """
        Dispatch method
        """
        # Normalize parameters
        if params:
            if isinstance(params, (list, tuple)):
                params = [jabsorb.from_jabsorb(param) for param in params]
            else:
                params = {key: jabsorb.from_jabsorb(value)
                          for key, value in params.items()}

        # Dispatch like JSON-RPC
        return super(JabsorbRpcDispatcher, self)._simple_dispatch(name, params)
Пример #3
0
    def testBeanInTheMiddle(self):
        """
        Tests the conversion of the content of a bean (half parsed stream)
        """
        class Bean(object):

            def __init__(self):
                self.list = jabsorb.to_jabsorb([1, 2, 3])
                self.tuple = jabsorb.to_jabsorb((1, 2, 3))
                self.set = jabsorb.to_jabsorb(set((1, 2, 3)))

            def __eq__(self, other):
                return self.list == other.list \
                    and self.tuple == other.tuple \
                    and self.set == other.set

        # Prepare the bean
        bean = Bean()

        # Parse its content
        revert = jabsorb.from_jabsorb(bean)
        self.assertIs(revert, bean)
        self.assertEqual(revert.list, [1, 2, 3])
        self.assertEqual(revert.tuple, (1, 2, 3))
        self.assertEqual(revert.set, {1, 2, 3})
Пример #4
0
    def testCustomClass(self):
        """
        Tests the conversion of a custom class
        """
        # Basic class
        class Custom(object):
            javaClass = "test.Custom"

            def __init__(self):
                self.value = str(uuid.uuid4())
                self._value = str(uuid.uuid4())
                self.__value = str(uuid.uuid4())

        # Convert it
        value = Custom()
        jabsorb_value = jabsorb.to_jabsorb(value)
        revert = jabsorb.from_jabsorb(jabsorb_value)

        # Check Jabsorb public value
        self.assertEqual(jabsorb_value[jabsorb.JAVA_CLASS], Custom.javaClass)
        self.assertEqual(jabsorb_value['value'], value.value)

        # Check absence of private value
        self.assertNotIn('_value', jabsorb_value)
        self.assertNotIn('__value', jabsorb_value)
        self.assertNotIn('_Custom__value', jabsorb_value)

        # Check revert value
        self.assertEqual(revert[jabsorb.JAVA_CLASS], Custom.javaClass)
        self.assertEqual(revert['value'], value.value)
        self.assertEqual(revert.javaClass, Custom.javaClass)
        self.assertEqual(revert.value, value.value)
Пример #5
0
    def testMirror(self):
        """
        Tests the result of to_jabsorb + from_jabsorb
        """
        value = {
            "list": [1, 2, 3],
            "tuple": (1, 2, 3),
            "set": set((1, 2, 3)),
            "dict": {
                "a": "b",
                "c": "d"
            },
            "int": 42,
            "float": 3.14,
            None: None,
            3.10: 51
        }

        # Convert to Jabsorb
        jabsorb_value = jabsorb.to_jabsorb(value)

        # ... back to "normal" Python
        revert_value = jabsorb.from_jabsorb(jabsorb_value)

        # Check content
        self.assertDictEqual(revert_value, value)
Пример #6
0
    def do_POST(self, request, response):
        """
        Handle a POST request

        :param request: The HTTP request bean
        :param request: The HTTP response handler
        """
        # Get the request JSON content
        data = jsonrpclib.loads(to_str(request.read_data()))

        # Convert from Jabsorb
        data = jabsorb.from_jabsorb(data)

        # Dispatch
        try:
            result = self._unmarshaled_dispatch(data, self._simple_dispatch)

        except NoMulticallResult:
            # No result (never happens, but who knows...)
            result = None

        if result is not None:
            # Convert result to Jabsorb
            if 'result' in result:
                result['result'] = jabsorb.to_jabsorb(result['result'])

            # Store JSON
            result = jsonrpclib.jdumps(result)

        else:
            # It was a notification
            result = ''

        # Send the result
        response.send_content(200, result, 'application/json-rpc')
Пример #7
0
    def _simple_dispatch(self, name, params):
        """
        Dispatch method
        """
        # Normalize parameters
        if params:
            if isinstance(params, (list, tuple)):
                params = [jabsorb.from_jabsorb(param) for param in params]
            else:
                params = {
                    key: jabsorb.from_jabsorb(value)
                    for key, value in params.items()
                }

        # Dispatch like JSON-RPC
        return super(JabsorbRpcDispatcher, self)._simple_dispatch(name, params)
Пример #8
0
    def do_POST(self, request, response):
        """
        Handle a POST request

        :param request: The HTTP request bean
        :param request: The HTTP response handler
        """
        # Get the request JSON content
        data = jsonrpclib.loads(to_str(request.read_data()))

        # Convert from Jabsorb
        data = jabsorb.from_jabsorb(data)

        # Dispatch
        try:
            result = self._unmarshaled_dispatch(data, self._simple_dispatch)
        except NoMulticallResult:
            # No result (never happens, but who knows...)
            result = None

        if result is not None:
            # Convert result to Jabsorb
            if 'result' in result:
                result['result'] = jabsorb.to_jabsorb(result['result'])

            # Store JSON
            result = jsonrpclib.jdumps(result)
        else:
            # It was a notification
            result = ''

        # Send the result
        response.send_content(200, result, 'application/json-rpc')
Пример #9
0
def from_json(json_string):
    """
    Returns a new MessageReceived from the provided json_string string
    """
    # parse the provided json_message
    try:
        parsed_msg = json.loads(json_string)
    except ValueError as ex:
        # if the provided json_message is not a valid JSON
        return None
    except TypeError as ex:
        # if json_message not string or buffer
        return None
    herald_version = None
    # check if it is a valid Herald JSON message
    if herald.MESSAGE_HEADERS in parsed_msg:
        if herald.MESSAGE_HERALD_VERSION in parsed_msg[herald.MESSAGE_HEADERS]:
            herald_version = parsed_msg[herald.MESSAGE_HEADERS].get(
                herald.MESSAGE_HERALD_VERSION)
    if herald_version is None or herald_version != herald.HERALD_SPECIFICATION_VERSION:
        _logger.error(
            "Herald specification of the received message is not supported!")
        return None
    # construct new Message object from the provided JSON object
    msg = herald.beans.MessageReceived(
        uid=(parsed_msg[herald.MESSAGE_HEADERS].get(herald.MESSAGE_HEADER_UID)
             or None),
        subject=parsed_msg[herald.MESSAGE_SUBJECT],
        content=None,
        sender_uid=(parsed_msg[herald.MESSAGE_HEADERS].get(
            herald.MESSAGE_HEADER_SENDER_UID) or None),
        reply_to=(parsed_msg[herald.MESSAGE_HEADERS].get(
            herald.MESSAGE_HEADER_REPLIES_TO) or None),
        access=None,
        timestamp=(parsed_msg[herald.MESSAGE_HEADERS].get(
            herald.MESSAGE_HEADER_TIMESTAMP) or None))
    # set content
    try:
        if herald.MESSAGE_CONTENT in parsed_msg:
            parsed_content = parsed_msg[herald.MESSAGE_CONTENT]
            if parsed_content is not None:
                if isinstance(parsed_content, str):
                    msg.set_content(parsed_content)
                else:
                    msg.set_content(jabsorb.from_jabsorb(parsed_content))
    except KeyError as ex:
        _logger.error("Error retrieving message content! " + str(ex))
    # other headers
    if herald.MESSAGE_HEADERS in parsed_msg:
        for key in parsed_msg[herald.MESSAGE_HEADERS]:
            if key not in msg._headers:
                msg._headers[key] = parsed_msg[herald.MESSAGE_HEADERS][key]
    # metadata
    if herald.MESSAGE_METADATA in parsed_msg:
        for key in parsed_msg[herald.MESSAGE_METADATA]:
            if key not in msg._metadata:
                msg._metadata[key] = parsed_msg[herald.MESSAGE_METADATA][key]

    return msg
    def _simple_dispatch(self, name, params):
        """
        Dispatch method
        """
        # Normalize parameters
        if params:
            params = [jabsorb.from_jabsorb(param) for param in params]

        # Dispatch like JSON-RPC
        return super(JabsorbRpcDispatcher, self)._simple_dispatch(name, params)
Пример #11
0
    def _simple_dispatch(self, name, params):
        """
        Dispatch method
        """
        # Normalize parameters
        if params:
            params = [jabsorb.from_jabsorb(param) for param in params]

        # Dispatch like JSON-RPC
        return super(JabsorbRpcDispatcher, self)._simple_dispatch(name, params)
Пример #12
0
def from_json(json_string):
    """
    Returns a new MessageReceived from the provided json_string string
    """
    # parse the provided json_message
    try:            
        parsed_msg = json.loads(json_string)            
    except ValueError as ex:            
        # if the provided json_message is not a valid JSON
        _logger.error('ValueError')
        return None
    except TypeError as ex:
        _logger.error('TypeError')
        # if json_message not string or buffer
        return None
    herald_version = None
    # check if it is a valid Herald JSON message
    if herald.MESSAGE_HEADERS in parsed_msg:
        if herald.MESSAGE_HERALD_VERSION in parsed_msg[herald.MESSAGE_HEADERS]:
            herald_version = parsed_msg[herald.MESSAGE_HEADERS].get(herald.MESSAGE_HERALD_VERSION)                         
    if herald_version is None or herald_version != herald.HERALD_SPECIFICATION_VERSION:
        _logger.error("Herald specification of the received message is not supported!")
        return None   
    # construct new Message object from the provided JSON object    
    msg = herald.beans.MessageReceived(uid=(parsed_msg[herald.MESSAGE_HEADERS].get(herald.MESSAGE_HEADER_UID) or None), 
                          subject=parsed_msg[herald.MESSAGE_SUBJECT], 
                          content=None, 
                          sender_uid=(parsed_msg[herald.MESSAGE_HEADERS].get(herald.MESSAGE_HEADER_SENDER_UID) or None), 
                          reply_to=(parsed_msg[herald.MESSAGE_HEADERS].get(herald.MESSAGE_HEADER_REPLIES_TO) or None), 
                          access=None,
                          timestamp=(parsed_msg[herald.MESSAGE_HEADERS].get(herald.MESSAGE_HEADER_TIMESTAMP) or None) 
                          )                           
    # set content
    try:
        if herald.MESSAGE_CONTENT in parsed_msg:
            parsed_content = parsed_msg[herald.MESSAGE_CONTENT]                              
            if parsed_content is not None:
                if isinstance(parsed_content, str):
                    msg.set_content(parsed_content)
                else:
                    msg.set_content(jabsorb.from_jabsorb(parsed_content))
    except KeyError as ex:
        _logger.error("Error retrieving message content! " + str(ex)) 
    # other headers
    if herald.MESSAGE_HEADERS in parsed_msg:
        for key in parsed_msg[herald.MESSAGE_HEADERS]:
            if key not in msg._headers:
                msg._headers[key] = parsed_msg[herald.MESSAGE_HEADERS][key]         
    # metadata
    if herald.MESSAGE_METADATA in parsed_msg:
        for key in parsed_msg[herald.MESSAGE_METADATA]:
            if key not in msg._metadata:
                msg._metadata[key] = parsed_msg[herald.MESSAGE_METADATA][key] 
                       
    return msg
Пример #13
0
        def wrapped_call(*args, **kwargs):
            """
            Wrapped call
            """
            # Get the method from the proxy
            method = getattr(proxy, "{0}.{1}".format(self.__name, name))

            # Convert arguments
            args = [jabsorb.to_jabsorb(arg) for arg in args]
            kwargs = dict((key, jabsorb.to_jabsorb(value))
                          for key, value in kwargs.items())

            result = method(*args, **kwargs)
            return jabsorb.from_jabsorb(result)
Пример #14
0
        def wrapped_call(*args, **kwargs):
            """
            Wrapped call
            """
            # Get the method from the proxy
            method = getattr(proxy, "{0}.{1}".format(self.__name, name))

            # Convert arguments
            args = [jabsorb.to_jabsorb(arg) for arg in args]
            kwargs = dict((key, jabsorb.to_jabsorb(value))
                          for key, value in kwargs.items())

            result = method(*args, **kwargs)
            return jabsorb.from_jabsorb(result)
Пример #15
0
    def __call__(self, *args):
        """
        Method is being called
        """
        # Forge the request
        if args:
            args = [jabsorb.to_jabsorb(arg) for arg in args]

        request = jsonrpclib.dumps(args, self.__name, encoding='utf-8')

        # Send it
        reply_message = self.__send(self.__peer, self.__subject, request)

        # Parse the reply and check for errors
        result = jabsorb.from_jabsorb(jsonrpclib.loads(reply_message.content))
        jsonrpclib.jsonrpc.check_for_errors(result)
        return result['result']
Пример #16
0
    def testJsonAndJavaClass(self):
        """
        Tests the conservation of the __jsonclass__ attribute
        """
        for has_json in (True, False):
            for has_java in (True, False):
                if not any((has_json, has_java)):
                    # Out of the scope of this test
                    continue

                # Prepare a fake bean
                value = {
                    "list": [1, 2, 3],
                    "tuple": (1, 2, 3),
                    "set": set((1, 2, 3)),
                    "dict": {
                        "a": "b",
                        "c": "d"
                    },
                    "int": 42,
                    "float": 3.14,
                    None: None,
                    3.10: 51
                }

                if has_json:
                    value[jabsorb.JSON_CLASS] = [1, 2, 3, [4, 5]]

                if has_java:
                    value[jabsorb.JAVA_CLASS] = 'test.Bean'

                # Convert it
                jabsorb_value = jabsorb.to_jabsorb(value)

                # Check the value of the JSON class
                if has_json:
                    self.assertEqual(jabsorb_value[jabsorb.JSON_CLASS],
                                     value[jabsorb.JSON_CLASS])

                if has_java:
                    self.assertEqual(jabsorb_value[jabsorb.JAVA_CLASS],
                                     value[jabsorb.JAVA_CLASS])

                # Revert
                revert = jabsorb.from_jabsorb(jabsorb_value)
                self.assertDictEqual(revert, value)
    def __call__(self, *args):
        """
        Method is being called
        """
        # Forge the request
        if args:
            args = [jabsorb.to_jabsorb(arg) for arg in args]

        request = jsonrpclib.dumps(args, self.__name, encoding='utf-8')

        # Send it
        reply_message = self.__send(self.__peer, self.__subject, request)

        # Parse the reply and check for errors
        result = jabsorb.from_jabsorb(jsonrpclib.loads(reply_message.content))
        jsonrpclib.jsonrpc.check_for_errors(result)
        return result['result']
Пример #18
0
    def testJsonAndJavaClass(self):
        """
        Tests the conservation of the __jsonclass__ attribute
        """
        for has_json in (True, False):
            for has_java in (True, False):
                if not any((has_json, has_java)):
                    # Out of the scope of this test
                    continue

                # Prepare a fake bean
                value = {"list": [1, 2, 3],
                         "tuple": (1, 2, 3),
                         "set": {1, 2, 3},
                         "dict": {"a": "b", "c": "d"},
                         "int": 42,
                         "float": 3.14,
                         None: None,
                         3.10: 51}

                if has_json:
                    value[jabsorb.JSON_CLASS] = [1, 2, 3, [4, 5]]

                if has_java:
                    value[jabsorb.JAVA_CLASS] = 'test.Bean'

                # Convert it
                jabsorb_value = jabsorb.to_jabsorb(value)

                # Check the value of the JSON class
                if has_json:
                    self.assertEqual(jabsorb_value[jabsorb.JSON_CLASS],
                                     value[jabsorb.JSON_CLASS])

                if has_java:
                    self.assertEqual(jabsorb_value[jabsorb.JAVA_CLASS],
                                     value[jabsorb.JAVA_CLASS])

                # Revert
                revert = jabsorb.from_jabsorb(jabsorb_value)
                self.assertDictEqual(revert, value)
Пример #19
0
    def testMirror(self):
        """
        Tests the result of to_jabsorb + from_jabsorb
        """
        value = {"list": [1, 2, 3],
                 "tuple": (1, 2, 3),
                 "set": {1, 2, 3},
                 "dict": {"a": "b", "c": "d"},
                 "int": 42,
                 "float": 3.14,
                 None: None,
                 3.10: 51}

        # Convert to Jabsorb
        jabsorb_value = jabsorb.to_jabsorb(value)

        # ... back to "normal" Python
        revert_value = jabsorb.from_jabsorb(jabsorb_value)

        # Check content
        self.assertDictEqual(revert_value, value)
Пример #20
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')
        raw_content = to_unicode(request.read_data())

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

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

            # Store sender information
            port = int(request.get_header('herald-port', 80))
            extra = {'host': host, 'port': port,
                     'path': request.get_header('herald-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
        message = herald.beans.MessageReceived(uid, subject, msg_content,
                                               sender_uid, reply_to,
                                               ACCESS_ID, timestamp, extra)

        # 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)
Пример #21
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:
            content = jabsorb.from_jabsorb(json.loads(msg['body']))
        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}

        # Call back the core service
        message = beans.MessageReceived(uid, subject, content, sender_uid,
                                        reply_to, self._access_id, extra=extra)

        # 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)
Пример #22
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 = ""

        # Check content type
        content_type = request.get_header('content-type')
        if content_type not in (None, CONTENT_TYPE_JSON):
            # Unknown content type -> Error 412 "Precondition failed"
            _logger.critical("Bad content type: %s", content_type)
            code, content = _make_json_result(412, "Unknown content type")

        else:
            # Extract headers
            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')
            json_content = to_unicode(request.read_data())
            msg_content = jabsorb.from_jabsorb(json.loads(json_content))

            # Store sender information
            host = request.get_client_address()[0]
            port = int(request.get_header('herald-port', 80))
            extra = {'host': host, 'port': port,
                     'path': request.get_header('herald-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 as ex:
                # Unknown peer UID: keep it as is
                pass

            # Let Herald handle the message
            message = herald.beans.MessageReceived(uid, subject, msg_content,
                                                   sender_uid, reply_to,
                                                   ACCESS_ID, timestamp, extra)
            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)
Пример #23
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 = ""

        # Check content type
        content_type = request.get_header('content-type')
        if content_type not in (None, CONTENT_TYPE_JSON):
            # Unknown content type -> Error 412 "Precondition failed"
            _logger.critical("Bad content type: %s", content_type)
            code, content = _make_json_result(412, "Unknown content type")

        else:
            # Extract headers
            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')
            json_content = to_unicode(request.read_data())
            msg_content = jabsorb.from_jabsorb(json.loads(json_content))

            # Store sender information
            host = request.get_client_address()[0]
            port = int(request.get_header('herald-port', 80))
            extra = {
                'host': host,
                'port': port,
                'path': request.get_header('herald-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 as ex:
                # Unknown peer UID: keep it as is
                pass

            # Let Herald handle the message
            message = herald.beans.MessageReceived(uid, subject, msg_content,
                                                   sender_uid, reply_to,
                                                   ACCESS_ID, timestamp, extra)
            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)