'get_hidden_service_conf(default = UNDEFINED)
This provides a mapping of hidden service directories to their
attribute\'s key/value pairs. All hidden services are assured to have a
\'HiddenServicePort\', but other entries may or may not exist.
"/var/lib/tor/hidden_service_empty/": {
"HiddenServicePort": [
"/var/lib/tor/hidden_service_with_two_ports/": {
"HiddenServiceAuthorizeClient": "stealth a, b",
"HiddenServicePort": [
(8020, "127.0.0.1", 8020),  # the ports order is kept
(8021, "127.0.0.1", 8021)
"HiddenServiceVersion": "2"
.. versionadded:: 1.3.0
:param object default: response if the query fails
:returns: **dict** with the hidden service configuration
:raises: :class:`stem.ControllerError` if the call fails and we weren\'t
provided a default response'

@with_default()
def get_hidden_service_conf(self, default=UNDEFINED):

    start_time = time.time()
    try:
        response = self.msg('GETCONF    HiddenServiceOptions')
        stem.response.convert('GETCONF', response)
        log.debug(('GETCONF    HiddenServiceOptions    (runtime:    %0.4f)' % (time.time() - start_time)))
    except stem.ControllerError as exc:
        log.debug(('GETCONF    HiddenServiceOptions    (failed:    %s)' % exc))
        raise exc
    service_dir_map = OrderedDict()
    directory = None
    for (status_code, divider, content) in response.content():
        if (content == 'HiddenServiceOptions'):
            continue
        if ('=' not in content):
            continue
        (k, v) = content.split('=', 1)
        if (k == 'HiddenServiceDir'):
            directory = v
            service_dir_map[directory] = {'HiddenServicePort': []}
        elif (k == 'HiddenServicePort'):
            port = target_port = v
            target_address = '127.0.0.1'
            if (not v.isdigit()):
                (port, target) = v.split()
                if target.isdigit():
                    target_port = target
                else:
                    (target_address, target_port) = target.split(':')
            if (not stem.util.connection.is_valid_port(port)):
                raise stem.ProtocolError(('GETCONF    provided    an    invalid    HiddenServicePort    port    (%s):    %s' % (port, content)))
            elif (not stem.util.connection.is_valid_ipv4_address(target_address)):
                raise stem.ProtocolError(('GETCONF    provided    an    invalid    HiddenServicePort    target    address    (%s):    %s' % (target_address, content)))
            elif (not stem.util.connection.is_valid_port(target_port)):
                raise stem.ProtocolError(('GETCONF    provided    an    invalid    HiddenServicePort    target    port    (%s):    %s' % (target_port, content)))
            service_dir_map[directory]['HiddenServicePort'].append((int(port), target_address, int(target_port)))
        else:
            service_dir_map[directory][k] = v
    return service_dir_map
