[tor-commits] [stem/master] Implement use_feature wrapper method

atagar at torproject.org atagar at torproject.org
Sun Aug 26 20:36:53 UTC 2012


commit 9a70131cf2bf0b25f89faa89c62fb70d5e891ee1
Author: Ravi Chandra Padmala <neenaoffline at gmail.com>
Date:   Tue Jul 3 01:34:46 2012 +0530

    Implement use_feature wrapper method
---
 stem/control.py                  |   38 ++++++++++++++++++++++++++++++++++++++
 stem/version.py                  |    1 +
 test/integ/control/controller.py |   19 +++++++++++++++++++
 3 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index dd5f812..f2eb47a 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -24,6 +24,7 @@ interacting at a higher level.
     |- set_options - sets or resets the values of multiple configuration options
     |- load_conf - loads configuration information as if it was in the torrc
     |- save_conf - saves configuration information to the torrc
+    |- enable_feature - enables control protocol features that have been disabled by default
     |- get_version - convenience method to get tor version
     |- authenticate - convenience method to authenticate the controller
     +- protocolinfo - convenience method to get the protocol info
@@ -962,6 +963,43 @@ class Controller(BaseController):
       raise stem.socket.OperationFailed(response.code, response.message)
     else:
       raise stem.socket.ProtocolError("SAVECONF returned unexpected response code")
+  
+  def enable_feature(self, features):
+    """
+    Enables features that are disabled by default to maintain backward
+    compatibility. Once enabled, a feature cannot be disabled and a new
+    control connection must be opened to get a connection with the feature
+    disabled. Feature names are case-insensitive.
+    
+    The following features are currently accepted:
+      * EXTENDED_EVENTS - Requests the extended event syntax. Has the same
+          effect as calling SETEVENTS with EXTENDED. Introduced in
+          0.1.2.3-alpha, always-on since Tor 0.2.2.1-alpha
+      * VERBOSE_NAMES - Replaces ServerID with LongName in events and GETINFO
+          results. LongName provides a Fingerprint for all routers, an indication
+          of Named status, and a Nickname if one is known. LongName is strictly
+          more informative than ServerID, which only provides either a Fingerprint
+          or a Nickname. Introduced in 0.1.2.2-alpha, always-on since Tor
+          0.2.2.1-alpha.
+    
+    :param str,list features: a single feature or a list of features to be enabled
+    
+    :raises:
+      :class:`stem.socket.ControllerError` if the call fails
+      :class:`stem.socket.InvalidArguments` if features passed were invalid
+    """
+    
+    if type(features) == str: features = [features]
+    response = self.msg("USEFEATURE %s" % " ".join(features))
+    stem.response.convert("SINGLELINE", response)
+    
+    if not response.is_ok():
+      if response.code == "552":
+        invalid_feature = []
+        if response.message.startswith("Unrecognized feature \""):
+          invalid_feature = [response.message[22:response.message.find("\"", 22)]]
+        raise stem.socket.InvalidArguments(response.code, response.message, invalid_feature)
+      raise stem.socket.ProtocolError("USEFEATURE returned invalid response code")
 
 def _case_insensitive_lookup(entries, key, default = UNDEFINED):
   """
diff --git a/stem/version.py b/stem/version.py
index 08f5ca2..e17d63b 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -249,5 +249,6 @@ Requirement = stem.util.enum.Enum(
   ("LOADCONF", Version("0.2.1.1")),
   ("TORRC_CONTROL_SOCKET", Version("0.2.0.30")),
   ("TORRC_DISABLE_DEBUGGER_ATTACHMENT", Version("0.2.3.9")),
+  ("FEATURE_VERBOSENAMES", Version("0.1.2.2-alpha")),
 )
 
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 54f2626..88ef642 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -316,4 +316,23 @@ class TestController(unittest.TestCase):
       finally:
         controller.load_conf(oldconf)
         controller.save_conf()
+  
+  def test_enable_feature(self):
+    """
+    Test Controller.enable_feature with valid and invalid inputs.
+    """
+    
+    if test.runner.require_control(self): return
+    
+    runner = test.runner.get_runner()
+    
+    with runner.get_tor_controller() as controller:
+      if test.runner.require_version(self, stem.version.Requirement.FEATURE_VERBOSENAMES):
+        controller.enable_feature("VERBOSE_NAMES")
+      self.assertRaises(stem.socket.InvalidArguments, controller.enable_feature, ["NOT", "A", "FEATURE"])
+      try:
+        controller.enable_feature(["NOT", "A", "FEATURE"])
+      except stem.socket.InvalidArguments, exc:
+        self.assertEqual(["NOT"], exc.arguments)
+      else: self.fail()
 





More information about the tor-commits mailing list