File: getinfo.py

package info (click to toggle)
python-stem 1.2.2-1.1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 4,568 kB
  • ctags: 2,036
  • sloc: python: 20,108; makefile: 127; sh: 3
file content (78 lines) | stat: -rw-r--r-- 2,591 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Copyright 2012-2014, Damian Johnson and The Tor Project
# See LICENSE for licensing information

import stem.response
import stem.socket


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 = []
      for code, _, line in self.content():
        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)
      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))