Controller Responses¶
Parses replies from the control socket.
Module Overview:
convert - translates a ControlMessage into a particular response subclass
ControlMessage - Message that's read from the control socket.
|- SingleLineResponse - Simple tor response only including a single line of information.
|
|- from_str - provides a ControlMessage for the given string
|- is_ok - response had a 250 status
|- content - provides the parsed message content
+- raw_content - unparsed socket data
ControlLine - String subclass with methods for parsing controller responses.
|- remainder - provides the unparsed content
|- is_empty - checks if the remaining content is empty
|- is_next_quoted - checks if the next entry is a quoted value
|- is_next_mapping - checks if the next entry is a KEY=VALUE mapping
|- peek_key - provides the key of the next entry
|- pop - removes and returns the next entry
+- pop_mapping - removes and returns the next entry as a KEY=VALUE mapping
- stem.response.convert(response_type, message, **kwargs)[source]¶
Converts a ControlMessage into a particular kind of tor response. This does an in-place conversion of the message from being a ControlMessage to a subclass for its response type. Recognized types include...
response_type Class ADD_ONION stem.response.add_onion.AddOnionResponse AUTHCHALLENGE stem.response.authchallenge.AuthChallengeResponse EVENT stem.response.events.Event subclass GETCONF stem.response.getconf.GetConfResponse GETINFO stem.response.getinfo.GetInfoResponse MAPADDRESS stem.response.mapaddress.MapAddressResponse PROTOCOLINFO stem.response.protocolinfo.ProtocolInfoResponse SINGLELINE stem.response.SingleLineResponse Parameters: - response_type (str) -- type of tor response to convert to
- message (stem.response.ControlMessage) -- message to be converted
- kwargs -- optional keyword arguments to be passed to the parser method
Raises : - stem.ProtocolError the message isn't a proper response of that type
- stem.InvalidArguments the arguments given as input are invalid, this is can only be raised if the response_type is: GETINFO, GETCONF
- stem.InvalidRequest the arguments given as input are invalid, this is can only be raised if the response_type is: MAPADDRESS
- stem.OperationFailed if the action the event represents failed, this is can only be raised if the response_type is: MAPADDRESS
- TypeError if argument isn't a ControlMessage or response_type isn't supported
- class stem.response.ControlMessage(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: object
Message from the control socket. This is iterable and can be stringified for individual message components stripped of protocol formatting. Messages are never empty.
Variables: arrived_at (int) -- unix timestamp for when the message arrived Changed in version 1.7.0: Implemented equality and hashing.
Changed in version 1.8.0: Moved arrived_at from the Event class up to this base ControlMessage.
- static from_str(content, msg_type=None, normalize=False, **kwargs)[source]¶
Provides a ControlMessage for the given content.
New in version 1.1.0.
Changed in version 1.6.0: Added the normalize argument.
Parameters: - content (str) -- message to construct the message from
- msg_type (str) -- type of tor reply to parse the content as
- normalize (bool) -- ensures expected carriage return and ending newline are present
- kwargs -- optional keyword arguments to be passed to the parser method
Returns: stem.response.ControlMessage instance
- is_ok()[source]¶
Checks if any of our lines have a 250 response.
Returns: True if any lines have a 250 response code, False otherwise
- content(get_bytes=False)[source]¶
Provides the parsed message content. These are entries of the form...
(status_code, divider, content)
- status_code
- Three character code for the type of response (defined in section 4 of the control-spec).
- divider
- Single character to indicate if this is mid-reply, data, or an end to the message (defined in section 2.3 of the control-spec).
- content
- The following content is the actual payload of the line.
For data entries the content is the full multi-line payload with newline linebreaks and leading periods unescaped.
The status_code and divider are both strings (bytes in python 2.x and unicode in python 3.x). The content however is bytes if get_bytes is True.
Changed in version 1.1.0: Added the get_bytes argument.
Parameters: get_bytes (bool) -- provides bytes for the content rather than a str Returns: list of (str, str, str) tuples for the components of this message
- class stem.response.ControlLine(value)[source]¶
Bases: str
String subclass that represents a line of controller output. This behaves as a normal string with additional methods for parsing and popping entries from a space delimited series of elements like a stack.
None of these additional methods effect ourselves as a string (which is still immutable). All methods are thread safe.
- remainder()[source]¶
Provides our unparsed content. This is an empty string after we've popped all entries.
Returns: str of the unparsed content
- is_empty()[source]¶
Checks if we have further content to pop or not.
Returns: True if we have additional content, False otherwise
- is_next_quoted(escaped=False)[source]¶
Checks if our next entry is a quoted value or not.
Parameters: escaped (bool) -- unescapes the string Returns: True if the next entry can be parsed as a quoted value, False otherwise
- is_next_mapping(key=None, quoted=False, escaped=False)[source]¶
Checks if our next entry is a KEY=VALUE mapping or not.
Parameters: - key (str) -- checks that the key matches this value, skipping the check if None
- quoted (bool) -- checks that the mapping is to a quoted value
- escaped (bool) -- unescapes the string
Returns: True if the next entry can be parsed as a key=value mapping, False otherwise
- peek_key()[source]¶
Provides the key of the next entry, providing None if it isn't a key/value mapping.
Returns: str with the next entry's key
- pop(quoted=False, escaped=False)[source]¶
Parses the next space separated entry, removing it and the space from our remaining content. Examples...
>>> line = ControlLine("\"We're all mad here.\" says the grinning cat.") >>> print line.pop(True) "We're all mad here." >>> print line.pop() "says" >>> print line.remainder() "the grinning cat." >>> line = ControlLine("\"this has a \\\" and \\\\ in it\" foo=bar more_data") >>> print line.pop(True, True) "this has a \" and \\ in it"
Parameters: - quoted (bool) -- parses the next entry as a quoted value, removing the quotes
- escaped (bool) -- unescapes the string
Returns: str of the next space separated entry
Raises : - ValueError if quoted is True without the value being quoted
- IndexError if we don't have any remaining content left to parse
- pop_mapping(quoted=False, escaped=False, get_bytes=False)[source]¶
Parses the next space separated entry as a KEY=VALUE mapping, removing it and the space from our remaining content.
Changed in version 1.6.0: Added the get_bytes argument.
Parameters: - quoted (bool) -- parses the value as being quoted, removing the quotes
- escaped (bool) -- unescapes the string
- get_bytes (bool) -- provides bytes for the value rather than a str
Returns: tuple of the form (key, value)
Raises : ValueError if this isn't a KEY=VALUE mapping or if quoted is True without the value being quoted
Raises : IndexError if there's nothing to parse from the line
- class stem.response.SingleLineResponse(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: stem.response.ControlMessage
Reply to a request that performs an action rather than querying data. These requests only contain a single line, which is 'OK' if successful, and a description of the problem if not.
Variables: - code (str) -- status code for our line
- message (str) -- content of the line
- is_ok(strict=False)[source]¶
Checks if the response code is "250". If strict is True then this checks if the response is "250 OK"
Parameters: strict (bool) -- checks for a "250 OK" message if True Returns: - If strict is False: True if the response code is "250", False otherwise
- If strict is True: True if the response is "250 OK", False otherwise
Responses¶
- class stem.response.add_onion.AddOnionResponse(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: stem.response.ControlMessage
ADD_ONION response.
Variables: - service_id (str) -- hidden service address without the '.onion' suffix
- private_key (str) -- base64 encoded hidden service private key
- private_key_type (str) -- crypto used to generate the hidden service private key (such as RSA1024)
- client_auth (dict) -- newly generated client credentials the service accepts
- class stem.response.authchallenge.AuthChallengeResponse(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: stem.response.ControlMessage
AUTHCHALLENGE query response.
Variables: - server_hash (str) -- server hash provided by tor
- server_nonce (str) -- server nonce provided by tor
- class stem.response.getconf.GetConfResponse(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: stem.response.ControlMessage
Reply for a GETCONF query.
Note that configuration parameters won't match what we queried for if it's one of the special mapping options (ex. 'HiddenServiceOptions').
Variables: entries (dict) -- mapping between the config parameter (str) and their values (list of str)
- class stem.response.getinfo.GetInfoResponse(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: stem.response.ControlMessage
Reply for a GETINFO query.
Variables: entries (dict) -- mapping between the queried options and their bytes values
- class stem.response.mapaddress.MapAddressResponse(parsed_content, raw_content, arrived_at=None)[source]¶
Bases: stem.response.ControlMessage
Reply for a MAPADDRESS query. Doesn't raise an exception unless no addresses were mapped successfully.
Variables: entries (dict) -- mapping between the original and replacement addresses
Raises : - stem.OperationFailed if Tor was unable to satisfy the request
- stem.InvalidRequest if the addresses provided were invalid