def _unpack_string(self, data):
        """
        Unpacks the next string from the given data

        :param data: A datagram, starting at a string size
        :return: A (string, unread_data) tuple
        """
        # Get the size of the string
        result, data = self._unpack("<H", data)
        size = result[0]

        # Read it
        string_bytes = data[:size]

        # Convert it
        return to_unicode(string_bytes), data[size:]
    def _unpack_string(self, data):
        """
        Unpacks the next string from the given data

        :param data: A datagram, starting at a string size
        :return: A (string, unread_data) tuple
        """
        # Get the size of the string
        result, data = self._unpack("<H", data)
        size = result[0]

        # Read it
        string_bytes = data[:size]

        # Convert it
        return to_unicode(string_bytes), data[size:]
    def _grab_broker_configuration(access):
        """
        Retrieves the isolate configuration from the configuration broker, if
        any

        :param access: A (host, HTTP port, servlet path) tuple
        :return: The raw content returned by the broker
        :raise ValueError: Invalid server address or path
        """
        # First request : retrieve the configuration
        try:
            conn = httplib.HTTPConnection(access[0], access[1])
        except httplib.HTTPException as ex:
            raise ValueError("Invalid server address: {0}".format(ex))

        try:
            # Get the configuration
            conn.request("GET", access[2])
            response = conn.getresponse()
            data = to_unicode(response.read())
            if response.status != 200:
                raise ValueError("Bad result from server: {0}"
                                 .format(response.status))

            # Delete it once retrieved
            conn.request("DELETE", access[2])

            # Be nice, even if we don't care of the result
            conn.getresponse().read()

            # Configuration has been correctly read
            return data
        except IOError as ex:
            raise ValueError("Error requesting the broker: {0}".format(ex))
        finally:
            # Close the connection in any case
            conn.close()
Exemple #4
0
    def _grab_broker_configuration(access):
        """
        Retrieves the isolate configuration from the configuration broker, if
        any

        :param access: A (host, HTTP port, servlet path) tuple
        :return: The raw content returned by the broker
        :raise ValueError: Invalid server address or path
        """
        # First request : retrieve the configuration
        try:
            conn = httplib.HTTPConnection(access[0], access[1])
        except httplib.HTTPException as ex:
            raise ValueError("Invalid server address: {0}".format(ex))

        try:
            # Get the configuration
            conn.request("GET", access[2])
            response = conn.getresponse()
            data = to_unicode(response.read())
            if response.status != 200:
                raise ValueError("Bad result from server: {0}"
                                 .format(response.status))

            # Delete it once retrieved
            conn.request("DELETE", access[2])

            # Be nice, even if we don't care of the result
            conn.getresponse().read()

            # Configuration has been correctly read
            return data
        except IOError as ex:
            raise ValueError("Error requesting the broker: {0}".format(ex))
        finally:
            # Close the connection in any case
            conn.close()
    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)
    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)
    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)
Exemple #8
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)
Exemple #9
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)