[tor-commits] [stem/master] Transparently allowing multiple PROTOCOLINFO calls
atagar at torproject.org
atagar at torproject.org
Tue Dec 20 18:02:27 UTC 2011
commit b4ca09871c7650ad6469c3b998ebc174605f4a7d
Author: Damian Johnson <atagar at torproject.org>
Date: Tue Dec 20 09:41:29 2011 -0800
Transparently allowing multiple PROTOCOLINFO calls
Tor hangs up on the socket for multiple reasons prior to authentication. One
of them is if multiple PROTOCOLINFO queries are made. This is annoying and does
not make sense to controller callers, so transparently re-establishing those
socket connections.
---
stem/connection.py | 14 ++++++++++----
test/integ/connection/protocolinfo.py | 21 +++++++++++++++++++++
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/stem/connection.py b/stem/connection.py
index ddfed89..39be31d 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -521,9 +521,6 @@ def get_protocolinfo(control_socket):
Issues a PROTOCOLINFO query to a control socket, getting information about
the tor process running on it.
- Tor hangs up on sockets after receiving a PROTOCOLINFO query if it isn't next
- followed by authentication.
-
Arguments:
control_socket (stem.socket.ControlSocket) - connected tor control socket
@@ -538,6 +535,15 @@ def get_protocolinfo(control_socket):
control_socket.send("PROTOCOLINFO 1")
protocolinfo_response = control_socket.recv()
+
+ # Tor hangs up on sockets after receiving a PROTOCOLINFO query if it isn't
+ # next followed by authentication. Transparently reconnect if that happens.
+
+ if str(protocolinfo_response) == "Authentication required.":
+ control_socket.connect()
+ control_socket.send("PROTOCOLINFO 1")
+ protocolinfo_response = control_socket.recv()
+
ProtocolInfoResponse.convert(protocolinfo_response)
# attempt ot expand relative cookie paths via the control port or socket file
@@ -640,7 +646,7 @@ class ProtocolInfoResponse(stem.socket.ControlMessage):
# sanity check that we're a PROTOCOLINFO response
if not list(self)[0].startswith("PROTOCOLINFO"):
- msg = "Message is not a PROTOCOLINFO response"
+ msg = "Message is not a PROTOCOLINFO response (%s)" % self
raise stem.socket.ProtocolError(msg)
for line in self:
diff --git a/test/integ/connection/protocolinfo.py b/test/integ/connection/protocolinfo.py
index dfc1c01..e37f63b 100644
--- a/test/integ/connection/protocolinfo.py
+++ b/test/integ/connection/protocolinfo.py
@@ -118,6 +118,27 @@ class TestProtocolInfo(unittest.TestCase):
# we don't have a control socket
self.assertRaises(stem.socket.SocketError, stem.socket.ControlSocketFile, test.runner.CONTROL_SOCKET_PATH)
+ def test_multiple_protocolinfo_calls(self):
+ """
+ Tests making repeated PROTOCOLINFO queries. This use case is interesting
+ because tor will shut down the socket and stem should transparently
+ re-establish it.
+ """
+
+ runner = test.runner.get_runner()
+ connection_type = runner.get_connection_type()
+
+ if connection_type == test.runner.TorConnection.NONE:
+ self.skipTest("(no connection)")
+
+ control_socket = runner.get_tor_socket(False)
+
+ for i in range(5):
+ protocolinfo_response = stem.connection.get_protocolinfo(control_socket)
+ self.assert_protocolinfo_attr(protocolinfo_response, connection_type)
+
+ control_socket.close()
+
def assert_protocolinfo_attr(self, protocolinfo_response, connection_type):
"""
Makes assertions that the protocolinfo response's attributes match those of
More information about the tor-commits
mailing list