def _parse_file(descriptor_file, validate=False, **kwargs): """ Iterates over the hidden service descriptors in a file. :param file descriptor_file: file with descriptor content :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for :class:`~stem.descriptor.hidden_service_descriptor.HiddenServiceDescriptor` instances in the file :raises: * **ValueError** if the contents is malformed and validate is **True** * **IOError** if the file can't be read """ while True: descriptor_content = _read_until_keywords('signature', descriptor_file) # we've reached the 'signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if descriptor_content: if descriptor_content[0].startswith(b'@type'): descriptor_content = descriptor_content[1:] yield HiddenServiceDescriptor(bytes.join(b'', descriptor_content), validate, **kwargs) else: break # done parsing file
def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs): """ Iterates over the extra-info descriptors in a file. :param file descriptor_file: file with descriptor content :param bool is_bridge: parses the file as being a bridge descriptor :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for :class:`~stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor` instances in the file :raises: * **ValueError** if the contents is malformed and validate is **True** * **IOError** if the file can't be read """ while True: extrainfo_content = _read_until_keywords('router-signature', descriptor_file) # we've reached the 'router-signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] extrainfo_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if extrainfo_content: if extrainfo_content[0].startswith(b'@type'): extrainfo_content = extrainfo_content[1:] if is_bridge: yield BridgeExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate, **kwargs) else: yield RelayExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate, **kwargs) else: break # done parsing file
def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs): """ Iterates over the extra-info descriptors in a file. :param file descriptor_file: file with descriptor content :param bool is_bridge: parses the file as being a bridge descriptor :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for :class:`~stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor` instances in the file :raises: * **ValueError** if the contents is malformed and validate is **True** * **IOError** if the file can't be read """ while True: extrainfo_content = _read_until_keywords("router-signature", descriptor_file) # we've reached the 'router-signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] extrainfo_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if extrainfo_content: if is_bridge: yield BridgeExtraInfoDescriptor(bytes.join(b"", extrainfo_content), validate, **kwargs) else: yield RelayExtraInfoDescriptor(bytes.join(b"", extrainfo_content), validate, **kwargs) else: break # done parsing file
def _parse_file(descriptor_file, validate = False, **kwargs): """ Iterates over the hidden service descriptors in a file. :param file descriptor_file: file with descriptor content :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for :class:`~stem.descriptor.hidden_service_descriptor.HiddenServiceDescriptor` instances in the file :raises: * **ValueError** if the contents is malformed and validate is **True** * **IOError** if the file can't be read """ while True: descriptor_content = _read_until_keywords('signature', descriptor_file) # we've reached the 'signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if descriptor_content: if descriptor_content[0].startswith(b'@type'): descriptor_content = descriptor_content[1:] yield HiddenServiceDescriptor(bytes.join(b'', descriptor_content), validate, **kwargs) else: break # done parsing file
def _parse_file(descriptor_file, validate=False, onion_address=None, **kwargs): while True: descriptor_content = _read_until_keywords('signature', descriptor_file) # we've reached the 'signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if descriptor_content: if descriptor_content[0].startswith(b'@type'): descriptor_content = descriptor_content[1:] yield Hsv3Descriptor(bytes.join(b'', descriptor_content), validate, onion_address=onion_address, **kwargs) else: break # done parsing file
def _parse_file(descriptor_file: BinaryIO, is_bridge = False, validate = False, **kwargs: Any) -> Iterator['stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor']: """ Iterates over the extra-info descriptors in a file. :param descriptor_file: file with descriptor content :param is_bridge: parses the file as being a bridge descriptor :param validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param kwargs: additional arguments for the descriptor constructor :returns: iterator for :class:`~stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor` instances in the file :raises: * **ValueError** if the contents is malformed and validate is **True** * **IOError** if the file can't be read """ if kwargs: raise ValueError('BUG: keyword arguments unused by extrainfo descriptors') while True: if not is_bridge: extrainfo_content = _read_until_keywords('router-signature', descriptor_file) # we've reached the 'router-signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] extrainfo_content += _read_until_keywords(block_end_prefix, descriptor_file, True) else: extrainfo_content = _read_until_keywords('router-digest', descriptor_file, True) if extrainfo_content: if extrainfo_content[0].startswith(b'@type'): extrainfo_content = extrainfo_content[1:] if is_bridge: yield BridgeExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate) else: yield RelayExtraInfoDescriptor(bytes.join(b'', extrainfo_content), validate) else: break # done parsing file
def _parse_file(descriptor_file, desc_type=None, validate=False, **kwargs): """ Iterates over the hidden service descriptors in a file. :param file descriptor_file: file with descriptor content :param class desc_type: BaseHiddenServiceDescriptor subclass :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for :class:`~stem.descriptor.hidden_service.HiddenServiceDescriptorV2` instances in the file :raises: * **ValueError** if the contents is malformed and validate is **True** * **IOError** if the file can't be read """ if desc_type is None: desc_type = HiddenServiceDescriptorV2 # Hidden service v3 ends with a signature line, whereas v2 has a pgp style # block following it. while True: descriptor_content = _read_until_keywords('signature', descriptor_file, True) if desc_type == HiddenServiceDescriptorV2: block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if descriptor_content: if descriptor_content[0].startswith(b'@type'): descriptor_content = descriptor_content[1:] yield desc_type(bytes.join(b'', descriptor_content), validate, **kwargs) else: break # done parsing file
def _parse_file(descriptor_file, is_bridge=False, validate=True, **kwargs): """ Iterates over the server descriptors in a file. :param file descriptor_file: file with descriptor content :param bool is_bridge: parses the file as being a bridge descriptor :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for ServerDescriptor instances in the file :raises: * **ValueError** if the contents is malformed and validate is True * **IOError** if the file can't be read """ # Handler for relay descriptors # # Cached descriptors consist of annotations followed by the descriptor # itself. For instance... # # @downloaded-at 2012-03-14 16:31:05 # @source "145.53.65.130" # router caerSidi 71.35.143.157 9001 0 0 # platform Tor 0.2.1.30 on Linux x86_64 # <rest of the descriptor content> # router-signature # -----BEGIN SIGNATURE----- # <signature for the above descriptor> # -----END SIGNATURE----- # # Metrics descriptor files are the same, but lack any annotations. The # following simply does the following... # # - parse as annotations until we get to "router" # - parse as descriptor content until we get to "router-signature" followed # by the end of the signature block # - construct a descriptor and provide it back to the caller # # Any annotations after the last server descriptor is ignored (never provided # to the caller). while True: annotations = _read_until_keywords("router", descriptor_file) descriptor_content = _read_until_keywords("router-signature", descriptor_file) # we've reached the 'router-signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if descriptor_content: # strip newlines from annotations annotations = map(bytes.strip, annotations) descriptor_text = bytes.join(b"", descriptor_content) if is_bridge: yield BridgeDescriptor(descriptor_text, validate, annotations, **kwargs) else: yield RelayDescriptor(descriptor_text, validate, annotations, **kwargs) else: if validate and annotations: orphaned_annotations = stem.util.str_tools._to_unicode( b'\n'.join(annotations)) raise ValueError( 'Content conform to being a server descriptor:\n%s' % orphaned_annotations) break # done parsing descriptors
def _parse_file(descriptor_file, is_bridge = False, validate = True, **kwargs): """ Iterates over the server descriptors in a file. :param file descriptor_file: file with descriptor content :param bool is_bridge: parses the file as being a bridge descriptor :param bool validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param dict kwargs: additional arguments for the descriptor constructor :returns: iterator for ServerDescriptor instances in the file :raises: * **ValueError** if the contents is malformed and validate is True * **IOError** if the file can't be read """ # Handler for relay descriptors # # Cached descriptors consist of annotations followed by the descriptor # itself. For instance... # # @downloaded-at 2012-03-14 16:31:05 # @source "145.53.65.130" # router caerSidi 71.35.143.157 9001 0 0 # platform Tor 0.2.1.30 on Linux x86_64 # <rest of the descriptor content> # router-signature # -----BEGIN SIGNATURE----- # <signature for the above descriptor> # -----END SIGNATURE----- # # Metrics descriptor files are the same, but lack any annotations. The # following simply does the following... # # - parse as annotations until we get to 'router' # - parse as descriptor content until we get to 'router-signature' followed # by the end of the signature block # - construct a descriptor and provide it back to the caller # # Any annotations after the last server descriptor is ignored (never provided # to the caller). while True: annotations = _read_until_keywords('router', descriptor_file) descriptor_content = _read_until_keywords('router-signature', descriptor_file) # we've reached the 'router-signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) if descriptor_content: if descriptor_content[0].startswith(b'@type'): descriptor_content = descriptor_content[1:] # strip newlines from annotations annotations = map(bytes.strip, annotations) descriptor_text = bytes.join(b'', descriptor_content) if is_bridge: yield BridgeDescriptor(descriptor_text, validate, annotations, **kwargs) else: yield RelayDescriptor(descriptor_text, validate, annotations, **kwargs) else: if validate and annotations: orphaned_annotations = stem.util.str_tools._to_unicode(b'\n'.join(annotations)) raise ValueError('Content conform to being a server descriptor:\n%s' % orphaned_annotations) break # done parsing descriptors
def _parse_file( descriptor_file: BinaryIO, is_bridge: bool = False, validate: bool = False, **kwargs: Any ) -> Iterator['stem.descriptor.server_descriptor.ServerDescriptor']: """ Iterates over the server descriptors in a file. :param descriptor_file: file with descriptor content :param is_bridge: parses the file as being a bridge descriptor :param validate: checks the validity of the descriptor's content if **True**, skips these checks otherwise :param kwargs: additional arguments for the descriptor constructor :returns: iterator for ServerDescriptor instances in the file :raises: * **ValueError** if the contents is malformed and validate is True * **IOError** if the file can't be read """ # Handler for relay descriptors # # Cached descriptors consist of annotations followed by the descriptor # itself. For instance... # # @downloaded-at 2012-03-14 16:31:05 # @source "145.53.65.130" # router caerSidi 71.35.143.157 9001 0 0 # platform Tor 0.2.1.30 on Linux x86_64 # <rest of the descriptor content> # router-signature # -----BEGIN SIGNATURE----- # <signature for the above descriptor> # -----END SIGNATURE----- # # Metrics descriptor files are the same, but lack any annotations. The # following simply does the following... # # - parse as annotations until we get to 'router' # - parse as descriptor content until we get to 'router-signature' followed # by the end of the signature block # - construct a descriptor and provide it back to the caller # # Any annotations after the last server descriptor is ignored (never provided # to the caller). while True: # skip annotations while True: pos = descriptor_file.tell() if not descriptor_file.readline().startswith(b'@'): descriptor_file.seek(pos) break if not is_bridge: descriptor_content = _read_until_keywords('router-signature', descriptor_file) # we've reached the 'router-signature', now include the pgp style block block_end_prefix = PGP_BLOCK_END.split(' ', 1)[0] descriptor_content += _read_until_keywords(block_end_prefix, descriptor_file, True) else: descriptor_content = _read_until_keywords('router-digest', descriptor_file, True) if descriptor_content: if descriptor_content[0].startswith(b'@type'): descriptor_content = descriptor_content[1:] descriptor_text = bytes.join(b'', descriptor_content) if is_bridge: if kwargs: raise ValueError( 'BUG: keyword arguments unused by bridge descriptors') yield BridgeDescriptor(descriptor_text, validate) else: yield RelayDescriptor(descriptor_text, validate, **kwargs) else: break # done parsing descriptors