Source code for stem.response.getinfo
# Copyright 2012-2019, Damian Johnson and The Tor Project
# See LICENSE for licensing information
import stem.response
import stem.socket
[docs]class GetInfoResponse(stem.response.ControlMessage):
"""
Reply for a GETINFO query.
:var dict entries: mapping between the queried options and their bytes values
"""
def _parse_message(self):
# Example:
# 250-version=0.2.3.11-alpha-dev (git-ef0bc7f8f26a917c)
# 250+config-text=
# ControlPort 9051
# DataDirectory /home/atagar/.tor
# ExitPolicy reject *:*
# Log notice stdout
# Nickname Unnamed
# ORPort 9050
# .
# 250 OK
self.entries = {}
remaining_lines = [content for (code, div, content) in self.content(get_bytes = True)]
if not self.is_ok() or not remaining_lines.pop() == b'OK':
unrecognized_keywords = []
error_code, error_msg = None, None
for code, _, line in self.content():
if code != '250':
error_code = code
error_msg = line
if code == '552' and line.startswith('Unrecognized key "') and line.endswith('"'):
unrecognized_keywords.append(line[18:-1])
if unrecognized_keywords:
raise stem.InvalidArguments('552', 'GETINFO request contained unrecognized keywords: %s\n' % ', '.join(unrecognized_keywords), unrecognized_keywords)
elif error_code:
raise stem.OperationFailed(error_code, error_msg)
else:
raise stem.ProtocolError("GETINFO response didn't have an OK status:\n%s" % self)
while remaining_lines:
try:
key, value = remaining_lines.pop(0).split(b'=', 1)
except ValueError:
raise stem.ProtocolError('GETINFO replies should only contain parameter=value mappings:\n%s' % self)
if stem.prereq.is_python_3():
key = stem.util.str_tools._to_unicode(key)
# if the value is a multiline value then it *must* be of the form
# '<key>=\n<value>'
if b'\n' in value:
if not value.startswith(b'\n'):
raise stem.ProtocolError("GETINFO response contained a multi-line value that didn't start with a newline:\n%s" % self)
value = value[1:]
self.entries[key] = value
def _assert_matches(self, params):
"""
Checks if we match a given set of parameters, and raise a ProtocolError if not.
:param set params: parameters to assert that we contain
:raises:
* :class:`stem.ProtocolError` if parameters don't match this response
"""
reply_params = set(self.entries.keys())
if params != reply_params:
requested_label = ', '.join(params)
reply_label = ', '.join(reply_params)
raise stem.ProtocolError("GETINFO reply doesn't match the parameters that we requested. Queried '%s' but got '%s'." % (requested_label, reply_label))