commit 08fa765d219b24a8c0bb0142b71a940cd6fd7bf2 Author: Damian Johnson atagar@torproject.org Date: Sat Oct 27 17:42:38 2012 -0700
Revised API docs for stem.socket --- docs/api.rst | 1 + docs/api/connection.rst | 4 +- docs/api/socket.rst | 5 +++ docs/contents.rst | 1 + stem/connection.py | 64 +++++++++++++++++++------------------- stem/socket.py | 80 +++++++++++++++++++++------------------------- 6 files changed, 78 insertions(+), 77 deletions(-)
diff --git a/docs/api.rst b/docs/api.rst index 65fa524..a893677 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -7,6 +7,7 @@ Controller * **Core**
* `stem.connection <api/connection.html>`_ - Connection and authentication to the Tor control port or socket. + * `stem.socket <api/socket.html>`_ - Low level control socket used to talk with Tor.
* **Types**
diff --git a/docs/api/connection.rst b/docs/api/connection.rst index 115ba26..ae3c7c7 100644 --- a/docs/api/connection.rst +++ b/docs/api/connection.rst @@ -1,5 +1,5 @@ -Connection -========== +Controller Connection +=====================
.. automodule:: stem.connection
diff --git a/docs/api/socket.rst b/docs/api/socket.rst new file mode 100644 index 0000000..33b7c51 --- /dev/null +++ b/docs/api/socket.rst @@ -0,0 +1,5 @@ +Control Socket +============== + +.. automodule:: stem.socket + diff --git a/docs/contents.rst b/docs/contents.rst index 467a122..ca93591 100644 --- a/docs/contents.rst +++ b/docs/contents.rst @@ -9,6 +9,7 @@ Contents tutorial
api/connection + api/socket
api/exit_policy api/version diff --git a/stem/connection.py b/stem/connection.py index 85b318a..730ad27 100644 --- a/stem/connection.py +++ b/stem/connection.py @@ -209,75 +209,75 @@ def authenticate(controller, password = None, chroot_path = None, protocolinfo_r try multiple authentication methods it may encounter multiple exceptions. If so then the exception this raises is prioritized as follows...
- * :class:`~stem.connection.IncorrectSocketType` + * :class:`stem.connection.IncorrectSocketType`
The controller does not speak the tor control protocol. Most often this happened because the user confused the SocksPort or ORPort with the ControlPort.
- * :class:`~stem.connection.UnrecognizedAuthMethods` + * :class:`stem.connection.UnrecognizedAuthMethods`
All of the authentication methods tor will accept are new and unrecognized. Please upgrade stem and, if that doesn't work, file a ticket on 'trac.torproject.org' and I'd be happy to add support.
- * :class:`~stem.connection.MissingPassword` + * :class:`stem.connection.MissingPassword`
We were unable to authenticate but didn't attempt password authentication because none was provided. You should prompt the user for a password and try again via 'authenticate_password'.
- * :class:`~stem.connection.IncorrectPassword` + * :class:`stem.connection.IncorrectPassword`
We were provided with a password but it was incorrect.
- * :class:`~stem.connection.IncorrectCookieSize` + * :class:`stem.connection.IncorrectCookieSize`
Tor allows for authentication by reading it a cookie file, but that file is the wrong size to be an authentication cookie.
- * :class:`~stem.connection.UnreadableCookieFile` + * :class:`stem.connection.UnreadableCookieFile`
Tor allows for authentication by reading it a cookie file, but we can't read that file (probably due to permissions).
- * *****:class:`~stem.connection.IncorrectCookieValue` + * *****:class:`stem.connection.IncorrectCookieValue`
Tor allows for authentication by reading it a cookie file, but rejected the contents of that file.
- * *****:class:`~stem.connection.AuthChallengeUnsupported` + * *****:class:`stem.connection.AuthChallengeUnsupported`
Tor doesn't recognize the AUTHCHALLENGE command. This is probably a Tor version prior to SAFECOOKIE being implement, but this exception shouldn't arise because we won't attempt SAFECOOKIE auth unless Tor claims to support it.
- * *****:class:`~stem.connection.UnrecognizedAuthChallengeMethod` + * *****:class:`stem.connection.UnrecognizedAuthChallengeMethod`
Tor couldn't recognize the AUTHCHALLENGE method Stem sent to it. This shouldn't happen at all.
- * *****:class:`~stem.connection.InvalidClientNonce` + * *****:class:`stem.connection.InvalidClientNonce`
Tor says that the client nonce provided by Stem during the AUTHCHALLENGE process is invalid.
- * *****:class:`~stem.connection.AuthSecurityFailure` + * *****:class:`stem.connection.AuthSecurityFailure`
Nonce value provided by the server was invalid.
- * *****:class:`~stem.connection.OpenAuthRejected` + * *****:class:`stem.connection.OpenAuthRejected`
Tor says that it allows for authentication without any credentials, but then rejected our authentication attempt.
- * *****:class:`~stem.connection.MissingAuthInfo` + * *****:class:`stem.connection.MissingAuthInfo`
Tor provided us with a PROTOCOLINFO reply that is technically valid, but missing the information we need to authenticate.
- * *****:class:`~stem.connection.AuthenticationFailure` + * *****:class:`stem.connection.AuthenticationFailure`
There are numerous other ways that authentication could have failed including socket failures, malformed controller responses, etc. These @@ -413,7 +413,7 @@ def authenticate_none(controller, suppress_ctl_errors = True): :class:`~stem.socket.ControllerError` as authentication rejection if **True**, otherwise they're re-raised
- :raises: :class:`~stem.connection.OpenAuthRejected` if the empty authentication credentials aren't accepted + :raises: :class:`stem.connection.OpenAuthRejected` if the empty authentication credentials aren't accepted """
try: @@ -460,9 +460,9 @@ def authenticate_password(controller, password, suppress_ctl_errors = True): **True**, otherwise they're re-raised
:raises: - * :class:`~stem.connection.PasswordAuthRejected` if the socket doesn't + * :class:`stem.connection.PasswordAuthRejected` if the socket doesn't accept password authentication - * :class:`~stem.connection.IncorrectPassword` if the authentication + * :class:`stem.connection.IncorrectPassword` if the authentication credentials aren't accepted """
@@ -530,11 +530,11 @@ def authenticate_cookie(controller, cookie_path, suppress_ctl_errors = True): **True**, otherwise they're re-raised
:raises: - * :class:`~stem.connection.IncorrectCookieSize` if the cookie file's size + * :class:`stem.connection.IncorrectCookieSize` if the cookie file's size is wrong - * :class:`~stem.connection.UnreadableCookieFile` if the cookie file doesn't + * :class:`stem.connection.UnreadableCookieFile` if the cookie file doesn't exist or we're unable to read it - * :class:`~stem.connection.CookieAuthRejected` if cookie authentication is + * :class:`stem.connection.CookieAuthRejected` if cookie authentication is attempted but the socket doesn't accept it * :class:`stem.connection.IncorrectCookieValue` if the cookie file's value is rejected @@ -609,21 +609,21 @@ def authenticate_safecookie(controller, cookie_path, suppress_ctl_errors = True) **True**, otherwise they're re-raised
:raises: - * :class:`~stem.connection.IncorrectCookieSize` if the cookie file's size + * :class:`stem.connection.IncorrectCookieSize` if the cookie file's size is wrong - * :class:`~stem.connection.UnreadableCookieFile` if the cookie file doesn't + * :class:`stem.connection.UnreadableCookieFile` if the cookie file doesn't exist or we're unable to read it - * :class:`~stem.connection.CookieAuthRejected` if cookie authentication is + * :class:`stem.connection.CookieAuthRejected` if cookie authentication is attempted but the socket doesn't accept it - * :class:`~stem.connection.IncorrectCookieValue` if the cookie file's value + * :class:`stem.connection.IncorrectCookieValue` if the cookie file's value is rejected - * :class:`~stem.connection.UnrecognizedAuthChallengeMethod` if the Tor + * :class:`stem.connection.UnrecognizedAuthChallengeMethod` if the Tor client fails to recognize the AuthChallenge method - * :class:`~stem.connection.AuthChallengeUnsupported` if AUTHCHALLENGE is + * :class:`stem.connection.AuthChallengeUnsupported` if AUTHCHALLENGE is unimplemented, or if unable to parse AUTHCHALLENGE response - * :class:`~stem.connection.AuthSecurityFailure` if AUTHCHALLENGE's response + * :class:`stem.connection.AuthSecurityFailure` if AUTHCHALLENGE's response looks like a security attack - * :class:`~stem.connection.InvalidClientNonce` if stem's AUTHCHALLENGE + * :class:`stem.connection.InvalidClientNonce` if stem's AUTHCHALLENGE client nonce is rejected for being invalid """
@@ -713,9 +713,9 @@ def get_protocolinfo(controller): :returns: :class:`~stem.response.protocolinfo.ProtocolInfoResponse` provided by tor
:raises: - * :class:`~stem.socket.ProtocolError` if the PROTOCOLINFO response is + * :class:`stem.socket.ProtocolError` if the PROTOCOLINFO response is malformed - * :class:`~stem.socket.SocketError` if problems arise in establishing or + * :class:`stem.socket.SocketError` if problems arise in establishing or using the socket """
@@ -780,9 +780,9 @@ def _read_cookie(cookie_path, is_safecookie): authentication, **False** if for COOKIE
:raises: - * :class:`~stem.connection.UnreadableCookieFile` if the cookie file is + * :class:`stem.connection.UnreadableCookieFile` if the cookie file is unreadable - * :class:`~stem.connection.IncorrectCookieSize` if the cookie size is + * :class:`stem.connection.IncorrectCookieSize` if the cookie size is incorrect (not 32 bytes) """
diff --git a/stem/socket.py b/stem/socket.py index e76e841..58dc5e2 100644 --- a/stem/socket.py +++ b/stem/socket.py @@ -1,7 +1,7 @@ """ Supports message based communication with sockets speaking the tor control protocol. This lets users send messages as basic strings and receive responses -as instances of the :class:`stem.response.ControlMessage` class. +as instances of the :class:`~stem.response.ControlMessage` class.
**Module Overview:**
@@ -54,7 +54,7 @@ class ControlSocket(object): receiving complete messages. All methods are thread safe.
Callers should not instantiate this class directly, but rather use subclasses - which are expected to implement the ``_make_socket()`` method. + which are expected to implement the **_make_socket()** method. """
def __init__(self): @@ -71,7 +71,7 @@ class ControlSocket(object): def send(self, message, raw = False): """ Formats and sends a message to the control socket. For more information see - the :func:`stem.socket.send_message` function. + the :func:`~stem.socket.send_message` function.
:param str message: message to be formatted and sent to the socket :param bool raw: leaves the message formatting untouched, passing it to the socket as-is @@ -94,9 +94,9 @@ class ControlSocket(object): def recv(self): """ Receives a message from the control socket, blocking until we've received - one. For more information see the :func:`stem.socket.recv_message` function. + one. For more information see the :func:`~stem.socket.recv_message` function.
- :returns: :class:`stem.response.ControlMessage` for the message received + :returns: :class:`~stem.response.ControlMessage` for the message received
:raises: * :class:`stem.socket.ProtocolError` the content from the socket is malformed @@ -140,12 +140,14 @@ class ControlSocket(object): until we either use it or have explicitily shut it down.
In practice a socket derived from a port knows about its disconnection - after a failed ``recv()`` call. Socket file derived connections know after - either a ``send()`` or ``recv()``. + after a failed :func:`~stem.socket.ControlSocket.recv` call. Socket file + derived connections know after either a + :func:`~stem.socket.ControlSocket.send` or + :func:`~stem.socket.ControlSocket.recv`.
This means that to have reliable detection for when we're disconnected you need to continually pull from the socket (which is part of what the - :class:`stem.control.BaseController` does). + :class:`~stem.control.BaseController` does).
:returns: bool that's True if we're known to be shut down and False otherwise """ @@ -222,10 +224,12 @@ class ControlSocket(object): def _get_send_lock(self): """ The send lock is useful to classes that interact with us at a deep level - because it's used to lock connect() / close(), and by extension our - is_alive() state changes. + because it's used to lock :func:`stem.socket.ControlSocket.connect` / + :func:`stem.socket.ControlSocket.close`, and by extension our + :func:`stem.socket.ControlSocket.is_alive` state changes.
- :returns: threading.RLock that governs sending messages to our socket and state changes + :returns: **threading.RLock** that governs sending messages to our socket + and state changes """
return self._send_lock @@ -254,11 +258,11 @@ class ControlSocket(object): """ Constructs and connects new socket. This is implemented by subclasses.
- :returns: socket.socket for our configuration + :returns: **socket.socket** for our configuration
:raises: * :class:`stem.socket.SocketError` if unable to make a socket - * NotImplementedError if not implemented by a subclass + * **NotImplementedError** if not implemented by a subclass """
raise NotImplementedError("Unsupported Operation: this should be implemented by the ControlSocket subclass") @@ -277,7 +281,8 @@ class ControlPort(ControlSocket): :param int control_port: port number of the controller :param bool connect: connects to the socket if True, leaves it unconnected otherwise
- :raises: :class:`stem.socket.SocketError` if connect is True and we're unable to establish a connection + :raises: :class:`stem.socket.SocketError` if connect is **True** and we're + unable to establish a connection """
super(ControlPort, self).__init__() @@ -325,7 +330,8 @@ class ControlSocketFile(ControlSocket): :param str socket_path: path where the control socket is located :param bool connect: connects to the socket if True, leaves it unconnected otherwise
- :raises: :class:`stem.socket.SocketError` if connect is True and we're unable to establish a connection + :raises: :class:`stem.socket.SocketError` if connect is **True** and we're + unable to establish a connection """
super(ControlSocketFile, self).__init__() @@ -371,9 +377,11 @@ def send_message(control_file, message, raw = False): <line 3>\r\n .\r\n
- :param file control_file: file derived from the control socket (see the socket's makefile() method for more information) + :param file control_file: file derived from the control socket (see the + socket's makefile() method for more information) :param str message: message to be sent on the control socket - :param bool raw: leaves the message formatting untouched, passing it to the socket as-is + :param bool raw: leaves the message formatting untouched, passing it to the + socket as-is
:raises: * :class:`stem.socket.SocketError` if a problem arises in using the socket @@ -411,13 +419,15 @@ def recv_message(control_file): Pulls from a control socket until we either have a complete message or encounter a problem.
- :param file control_file: file derived from the control socket (see the socket's makefile() method for more information) + :param file control_file: file derived from the control socket (see the + socket's makefile() method for more information)
- :returns: :class:`stem.response.ControlMessage` read from the socket + :returns: :class:`~stem.response.ControlMessage` read from the socket
:raises: * :class:`stem.socket.ProtocolError` the content from the socket is malformed - * :class:`stem.socket.SocketClosed` if the socket closes before we receive a complete message + * :class:`stem.socket.SocketClosed` if the socket closes before we receive + a complete message """
parsed_content, raw_content = [], "" @@ -522,11 +532,12 @@ def recv_message(control_file): def send_formatting(message): """ Performs the formatting expected from sent control messages. For more - information see the :func:`stem.socket.send_message` function. + information see the :func:`~stem.socket.send_message` function.
:param str message: message to be formatted
- :returns: str of the message wrapped by the formatting expected from controllers + :returns: **str** of the message wrapped by the formatting expected from + controllers """
# From control-spec section 2.2... @@ -557,19 +568,11 @@ class OperationFailed(ControllerError): Base exception class for failed operations that return an error code
:var str code: error code returned by Tor - :var str message: error message returned by Tor or a human readable error message + :var str message: error message returned by Tor or a human readable error + message """
def __init__(self, code = None, message = None): - """ - Initializes an OperationFailed object. - - :param str code: error code returned by Tor - :param str message: error message returned by Tor or a human readable error message - - :returns: object of OperationFailed class - """ - super(ControllerError, self).__init__(message) self.code = code self.message = message @@ -589,21 +592,12 @@ class InvalidArguments(InvalidRequest): Exception class for requests which had invalid arguments.
:var str code: error code returned by Tor - :var str message: error message returned by Tor or a human readable error message + :var str message: error message returned by Tor or a human readable error + message :var list arguments: a list of arguments which were invalid """
def __init__(self, code = None, message = None, arguments = None): - """ - Initializes an InvalidArguments object. - - :param str code: error code returned by Tor - :param str message: error message returned by Tor or a human readable error message - :param list arguments: a list of arguments which were invalid - - :returns: object of InvalidArguments class - """ - super(InvalidArguments, self).__init__(code, message) self.arguments = arguments
tor-commits@lists.torproject.org