def __discover_peer(self, host, port, path): """ Grabs the description of a peer using the Herald servlet :param host: Address which sent the heart beat :param port: Port of the Herald HTTP server :param path: Path to the Herald HTTP servlet """ if path.startswith('/'): # Remove the starting /, as it is added while forging the URL path = path[1:] # Normalize the address of the sender host = utils.normalize_ip(host) # Prepare the "extra" information, like for a reply extra = {'host': host, 'port': port, 'path': path} local_dump = self._directory.get_local_peer().dump() try: self._transport.fire( None, beans.Message(peer_contact.SUBJECT_DISCOVERY_STEP_1, local_dump), extra) except Exception as ex: _logger.exception("Error contacting peer: %s", ex)
def __discover_neighbor(self, peer_dump): """ Discover local neighbor Peer """ host = peer_dump['accesses']['http'][0] port = peer_dump['accesses']['http'][1] path = peer_dump['accesses']['http'][2] if path.startswith('/'): # Remove the starting /, as it is added while forging the URL path = path[1:] # Normalize the address of the sender host = utils.normalize_ip(host) # Prepare the "extra" information, like for a reply extra = {'host': host, 'port': port, 'path': path} local_dump = self._directory.get_local_peer().dump() try: self._transport.fire( None, beans.Message(peer_contact.SUBJECT_DISCOVERY_STEP_1, local_dump), extra) except Exception as ex: _logger.exception("Error contacting peer: %s", ex)
def __discover_forker(self): """ Discover the forker of this local Peer by sending to him the contact message """ host = self._forker_host port = self._forker_port path = self._forker_path if path.startswith('/'): # Remove the starting /, as it is added while forging the URL path = path[1:] # Normalize the address of the sender host = utils.normalize_ip(host) # Prepare the "extra" information, like for a reply extra = {'host': host, 'port': port, 'path': path} local_dump = self._directory.get_local_peer().dump() try: self._transport.fire( None, beans.Message(peer_contact.SUBJECT_DISCOVERY_STEP_1, local_dump), extra) except Exception as ex: _logger.exception("Error contacting peer: %s", ex)
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 = "" # 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)
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)