def test_equality(self): # LinkProtocols should be comparable with both other LinkProtocols and # integers. protocol = LinkProtocol(1) self.assertEqual(LinkProtocol(1), protocol) self.assertNotEqual(LinkProtocol(2), protocol) self.assertEqual(1, protocol) self.assertNotEqual(2, protocol)
def test_attributes(self): protocol = LinkProtocol(1) self.assertEqual(1, protocol.version) self.assertEqual(Size.SHORT, protocol.circ_id_size) self.assertEqual(512, protocol.fixed_cell_length) self.assertEqual(0x01, protocol.first_circ_id) protocol = LinkProtocol(10) self.assertEqual(10, protocol.version) self.assertEqual(Size.LONG, protocol.circ_id_size) self.assertEqual(514, protocol.fixed_cell_length) self.assertEqual(0x80000000, protocol.first_circ_id)
def pop( content: bytes, link_protocol: 'stem.client.datatype.LinkProtocol' ) -> Tuple['stem.client.cell.Cell', bytes]: """ Unpacks the first cell. :param content: payload to decode :param link_protocol: link protocol version :returns: (:class:`~stem.client.cell.Cell`, remainder) tuple :raises: * ValueError if content is malformed * NotImplementedError if unable to unpack this cell type """ link_protocol = LinkProtocol(link_protocol) circ_id, content = link_protocol.circ_id_size.pop(content) command, content = CELL_TYPE_SIZE.pop(content) cls = Cell.by_value(command) if cls.IS_FIXED_SIZE: payload_len = FIXED_PAYLOAD_LEN else: payload_len, content = PAYLOAD_LEN_SIZE.pop(content) if len(content) < payload_len: raise ValueError( '%s cell should have a payload of %i bytes, but only had %i' % (cls.NAME, payload_len, len(content))) payload, content = split(content, payload_len) return cls._unpack(payload, circ_id, link_protocol), content
def __init__(self, orport: stem.socket.RelaySocket, link_protocol: int) -> None: self.link_protocol = LinkProtocol(link_protocol) self._orport = orport self._orport_buffer = b'' # unread bytes self._orport_lock = threading.RLock() self._circuits = {} # type: Dict[int, stem.client.Circuit]
def test_use_as_int(self): protocol = LinkProtocol(5) self.assertEqual(7, protocol + 2) self.assertEqual(3, protocol - 2) self.assertEqual(15, protocol * 3) self.assertEqual(1, protocol // 3)
def _pack(cls, link_protocol, payload, circ_id=None): """ Provides bytes that can be used on the wire for these cell attributes. Format of a properly packed cell depends on if it's fixed or variable sized... :: Fixed: [ CircuitID ][ Command ][ Payload ][ Padding ] Variable: [ CircuitID ][ Command ][ Size ][ Payload ] :param str name: cell command :param int link_protocol: link protocol version :param bytes payload: cell payload :param int circ_id: circuit id, if a CircuitCell :return: **bytes** with the encoded payload :raise: **ValueError** if cell type invalid or payload makes cell too large """ if issubclass(cls, CircuitCell): if circ_id is None: raise ValueError('%s cells require a circuit identifier' % cls.NAME) elif circ_id < 1: raise ValueError( 'Circuit identifiers must a positive integer, not %s' % circ_id) else: if circ_id is not None: raise ValueError( '%s cells should not specify a circuit identifier' % cls.NAME) circ_id = 0 # cell doesn't concern a circuit, default field to zero link_protocol = LinkProtocol.for_version(link_protocol) cell = bytearray() cell += link_protocol.circ_id_size.pack(circ_id) cell += Size.CHAR.pack(cls.VALUE) cell += b'' if cls.IS_FIXED_SIZE else Size.SHORT.pack(len(payload)) cell += payload # pad fixed sized cells to the required length if cls.IS_FIXED_SIZE: if len(cell) > link_protocol.fixed_cell_len: raise ValueError( 'Cell of type %s is too large (%i bytes), must not be more than %i. Check payload size (was %i bytes)' % (cls.NAME, len(cell), link_protocol.fixed_cell_len, len(payload))) cell += ZERO * (link_protocol.fixed_cell_len - len(cell)) return bytes(cell)
def __init__(self, orport, link_protocol): # TODO: Python 3.x adds a getbuffer() method which # lets us get the size... # # https://stackoverflow.com/questions/26827055/python-how-to-get-iobytes-allocated-memory-length # # When we drop python 2.x support we should replace # self._orport_buffer with an io.BytesIO. self.link_protocol = LinkProtocol(link_protocol) self._orport = orport self._orport_buffer = b'' # unread bytes self._orport_lock = threading.RLock() self._circuits = {}
def __init__(self, orport, link_protocol): self.link_protocol = LinkProtocol(link_protocol) self._orport = orport self._orport_lock = threading.RLock() self._circuits = {}