def _validate_envelope(self, envelope_binary: bytes, header: str) -> Union[None, Envelope]: # TODO return/raise custom exceptions in this instead of just logging stuff and returning none # Deserialize envelope env = None try: env = Envelope.from_bytes(envelope_binary) except Exception as e: self.log.error("\n\n\nError deserializing envelope: {}\n\n\n".format(e)) return None # Check seal if not env.verify_seal(): self.log.error("\n\n\nSeal could not be verified for envelope {}\n\n\n".format(env)) return None # If header is not none (meaning this is a ROUTE msg with an ID frame), then verify that the ID frame is # the same as the vk on the seal if header and (header != env.seal.verifying_key): self.log.error("\n\n\nHeader frame {} does not match seal's vk {}\nfor envelope {}\n\n\n" .format(header, env.seal.verifying_key, env)) return None # Make sure we haven't seen this message before if env.meta.uuid in Executor._recently_seen: self.log.warning("Duplicate envelope detect with UUID {}. Ignoring.".format(env.meta.uuid)) return None # TODO -- checks timestamp to ensure this envelope is recv'd in a somewhat reasonable time (within N seconds) # If none of the above checks above return None, this envelope should be good return env
def send_pub(self, filter: str, envelope: bytes): assert isinstance(filter, str), "'id' arg must be a string" assert isinstance(envelope, bytes), "'envelope' arg must be bytes" assert len(self.pubs) > 0, "Attempted to publish data but publisher socket(s) is not configured" for url in self.pubs: self.log.debug("Publishing to URL {} with envelope: {}".format(url, Envelope.from_bytes(envelope))) # self.log.info("Publishing to... {}".format(url)) self.pubs[url].send_multipart([filter.encode(), envelope])
def test_serialize_from_objects(self): """ Tests that serialize/deserialize are inverse operations with from_objects factory function """ sk, vk = W.new() message = self._default_msg() env = Envelope.create_from_message(message=message, signing_key=sk, verifying_key=vk) self.assertEqual(env, Envelope.from_bytes(env.serialize()))
def route(self, msg_binary: bytes): msg = None try: envelope = Envelope.from_bytes(msg_binary) msg = envelope.open() except Exception as e: self.log.error("Error opening envelope: {}".format(e)) if type(msg) in self._receivers: self.log.debug("Routing msg: {}".format(msg)) self._receivers[type(msg)](self, msg) else: self.log.error("Message {} has no implemented receiver in {}".format(msg, self._receivers))
def test_lazy_serialize(self): """ Tests that creating an envelope from_bytes does not try to repack the underlying struct when serialize is called. This is b/c the serialize() func should be 'cached' with the binary data passed into from_bytes """ sk, vk = W.new() message = self._default_msg() env = Envelope.create_from_message(message=message, signing_key=sk, verifying_key=vk) env_binary = env.serialize() clone = Envelope.from_bytes(env_binary) clone._data = MagicMock() clone_binary = clone.serialize() # this should not pack the capnp struct (_data) again # The Envelope Kitchen Sink lol -- make sure no serialization related API is called clone._data.as_builder.assert_not_called() clone._data.to_bytes_packed.assert_not_called() clone._data.to_bytes.assert_not_called()
def envelope(self): if self._data.envelope.which() == 'unset': return None else: return Envelope.from_bytes(self._data.envelope.data)