[Pkg-privacy-commits] [txtorcon] 01/04: Imported Upstream version 0.14.2

Iain R. Learmonth irl at moszumanska.debian.org
Sun Dec 27 19:21:56 UTC 2015


This is an automated email from the git hooks/post-receive script.

irl pushed a commit to branch master
in repository txtorcon.

commit 417ee5bbedae90526419e206860b69cd91d9afc8
Author: Iain R. Learmonth <irl at debian.org>
Date:   Sun Dec 27 18:55:31 2015 +0000

    Imported Upstream version 0.14.2
---
 Makefile                       |  9 ++----
 PKG-INFO                       |  2 +-
 docs/releases.rst              | 18 ++++++++++++
 examples/ephemeral_endpoint.py | 62 ++++++++++++++++++++++++++++++++++++++++++
 setup.py                       |  2 +-
 test/test_circuit.py           | 59 +++++++++++++++++++++++++++++++++++++++-
 txtorcon.egg-info/PKG-INFO     |  2 +-
 txtorcon.egg-info/SOURCES.txt  |  2 +-
 txtorcon.egg-info/pbr.json     |  2 +-
 txtorcon/__init__.py           |  2 +-
 txtorcon/_metadata.py          |  6 ----
 txtorcon/circuit.py            | 35 ++++++++++++++++++------
 txtorcon/endpoints.py          | 17 ++++++++++--
 txtorcon/torcontrolprotocol.py |  4 ++-
 txtorcon/torstate.py           |  3 ++
 15 files changed, 194 insertions(+), 31 deletions(-)

diff --git a/Makefile b/Makefile
index 56c8c4e..61f0a56 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 .PHONY: test html counts coverage sdist clean install doc integration
 default: test
-VERSION = 0.14.0
+VERSION = 0.14.2
 
 test:
 	trial --reporter=text test
@@ -36,7 +36,6 @@ doc: docs/*.rst
 
 coverage:
 	coverage run --source=txtorcon `which trial` test
-	coverage -a -d annotated_coverage
 	coverage report --show-missing
 
 htmlcoverage:
@@ -87,7 +86,7 @@ dist: dist/txtorcon-${VERSION}-py2-none-any.whl dist/txtorcon-${VERSION}.tar.gz
 
 dist-sigs: dist/txtorcon-${VERSION}-py2-none-any.whl.asc dist/txtorcon-${VERSION}.tar.gz.asc
 
-sdist: setup.py
+sdist: setup.py 
 	python setup.py sdist
 
 dist/txtorcon-${VERSION}-py2-none-any.whl:
@@ -100,10 +99,6 @@ dist/txtorcon-${VERSION}.tar.gz.asc: dist/txtorcon-${VERSION}.tar.gz
 	gpg --verify dist/txtorcon-${VERSION}.tar.gz.asc || gpg --no-version --detach-sign --armor --local-user meejah at meejah.ca dist/txtorcon-${VERSION}.tar.gz
 
 release:
-	# XXXXXX FIXME warner in #tahoe-lafs says this doesn't work if
-	# you have "dist/blarg.asc" files for some reason .. but I
-	# think it's worked for me before?
-	# https://github.com/pypa/twine/issues/132
 	twine upload -r pypi -c "txtorcon v${VERSION} tarball" dist/txtorcon-${VERSION}.tar.gz dist/txtorcon-${VERSION}.tar.gz.asc
 	twine upload -r pypi -c "txtorcon v${VERSION} wheel" dist/txtorcon-${VERSION}-py2-none-any.whl dist/txtorcon-${VERSION}-py2-none-any.whl.asc
 
diff --git a/PKG-INFO b/PKG-INFO
index 2581e2d..80d1067 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: txtorcon
-Version: 0.14.0
+Version: 0.14.2
 Summary: Twisted-based Tor controller client, with state-tracking and configuration abstractions.
 Home-page: https://github.com/meejah/txtorcon
 Author: meejah
diff --git a/docs/releases.rst b/docs/releases.rst
index 2e7a620..63f6689 100644
--- a/docs/releases.rst
+++ b/docs/releases.rst
@@ -12,6 +12,24 @@ unreleased
 `git master <https://github.com/meejah/txtorcon>`_ *will likely become v0.15.0*
 
 
+v0.14.1
+-------
+
+*October 25, 2015*
+
+ * `txtorcon-0.14.1.tar.gz <http://timaq4ygg2iegci7.onion/txtorcon-0.14.1.tar.gz>`_ (`PyPI <https://pypi.python.org/pypi/txtorcon/0.14.1>`_ (:download:`local-sig </../signatues/txtorcon-0.14.1.tar.gz.asc>` or `github-sig <https://github.com/meejah/txtorcon/blob/master/signatues/txtorcon-0.14.1.tar.gz.asc?raw=true>`_) (`source <https://github.com/meejah/txtorcon/archive/v0.14.1.tar.gz>`_)
+ * subtle bug with ``.is_built`` on Circuit; changing the API (but
+   with backwards-compatibility until 0.15.0 at least)
+
+
+v0.14.2
+-------
+
+*December 2, 2015*
+
+ * `txtorcon-0.14.2.tar.gz <http://timaq4ygg2iegci7.onion/txtorcon-0.14.2.tar.gz>`_ (`PyPI <https://pypi.python.org/pypi/txtorcon/0.14.2>`_ (:download:`local-sig </../signatues/txtorcon-0.14.2.tar.gz.asc>` or `github-sig <https://github.com/meejah/txtorcon/blob/master/signatues/txtorcon-0.14.2.tar.gz.asc?raw=true>`_) (`source <https://github.com/meejah/txtorcon/archive/v0.14.2.tar.gz>`_)
+ * compatibility for Twisted 15.5.0 (released on 0.14.x for `OONI <http://ooni.io/>`_)
+
 
 v0.14.0
 -------
diff --git a/examples/ephemeral_endpoint.py b/examples/ephemeral_endpoint.py
new file mode 100644
index 0000000..96fca4e
--- /dev/null
+++ b/examples/ephemeral_endpoint.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+# This connects to the system Tor (by default on control port 9151)
+# and adds a new hidden service configuration to it.
+
+import os
+import functools
+import shutil
+
+from twisted.internet import reactor, defer
+from twisted.internet.endpoints import TCP4ClientEndpoint, TCP4ServerEndpoint
+from twisted.web import server, resource
+from twisted.internet.task import react
+
+import txtorcon
+
+# Ephemeral endpoints. You own all the bits.
+securely_stored_keyblob = '''RSA1024:MIICWwIBAAKBgQCsEuaUlvU651/lEl986XfX4QylkQCLhA9Nc19LTTt38oDeHRl3i5VgNsfsXyLrnk2iWapOsc3nmvxMt9vhFFanDB9p/rZTonERnTAw50M7PP4H4E8MDkPm6yZJSES7TPEI9u7WfSdq/HsNk4bsQU9Q3Vndy+hPZtPeGl+rs+3MawIDAQABAoGAGHPDIoBlLs6sWOAIg7almh7X7jsxyaGljwsDEq9R8RSb7XRTJyLFwltmg5dtXfAr9hMp2W745J2olrpV26FJQs4LFQBFawUwytvSV9IanpOew02yjvUQ0zqQUUbuR8rNHhzxJrvfJLDEzCmB8RBb1fE6BcUdv5t8xCu0/BwJdCkCQQDaL1ZJQ4aVHLcqru3IqiAwLsnA62aMNUPOO7twJ4YArX7Q6ZscqOPp8eLLoRzCYpMODcBX7kAOmuHxW8X3AKq [...]
+
+
+class Simple(resource.Resource):
+    isLeaf = True
+
+    def render_GET(self, request):
+        return "<html>Hello, world! I'm a hidden service!</html>"
+
+
+ at defer.inlineCallbacks
+def main(reactor):
+    ep = txtorcon.TCPEphemeralHiddenServiceEndpoint.system_tor(
+        reactor,
+        public_port=8080,
+        control_endpoint=TCP4ClientEndpoint(reactor, 'localhost', 9251),
+        private_key=securely_stored_keyblob,
+    )
+
+    print "Starting site"
+    port = yield ep.listen(server.Site(Simple()))
+    addr = port.address
+
+    print "Site started. Available at http://{}:{}".format(addr.onion_uri, addr.onion_port)
+    print "Private key:\n{}".format(port.private_key)
+
+    # in 5 seconds, remove the hidden service -- obviously this is
+    # where you'd do your "real work" or whatever.
+    d = defer.Deferred()
+
+    @defer.inlineCallbacks
+    def remove():
+        print "Removing the hiddenservice. Private key was"
+        print hs.onion_private_key
+        yield hs.remove_from_tor(tor_protocol)
+        d.callback(None)
+    if False:
+        reactor.callLater(5, remove)
+        print "waiting 5 seconds"
+    else:
+        print "waiting forever"
+    yield d
+
+
+react(main)
diff --git a/setup.py b/setup.py
index f9a1e1f..e19437e 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ from setuptools import setup
 
 # can't just naively import these from txtorcon, as that will only
 # work if you already installed the dependencies :(
-__version__ = '0.14.0'
+__version__ = '0.14.2'
 __author__ = 'meejah'
 __contact__ = 'meejah at meejah.ca'
 __url__ = 'https://github.com/meejah/txtorcon'
diff --git a/test/test_circuit.py b/test/test_circuit.py
index d62d54b..3ec9ece 100644
--- a/test/test_circuit.py
+++ b/test/test_circuit.py
@@ -2,6 +2,7 @@ import datetime
 import time
 from twisted.trial import unittest
 from twisted.internet import defer
+from twisted.python.failure import Failure
 from zope.interface import implements
 
 from txtorcon import Circuit
@@ -13,10 +14,13 @@ from txtorcon.interface import IRouterContainer
 from txtorcon.interface import ICircuitListener
 from txtorcon.interface import ICircuitContainer
 from txtorcon.interface import CircuitListenerMixin
+from txtorcon.interface import ITorControlProtocol
 
 
 class FakeTorController(object):
-    implements(IRouterContainer, ICircuitListener, ICircuitContainer)
+    implements(IRouterContainer, ICircuitListener, ICircuitContainer, ITorControlProtocol)
+
+    post_bootstrap = defer.Deferred()
 
     def __init__(self):
         self.routers = {}
@@ -305,3 +309,56 @@ class CircuitTests(unittest.TestCase):
             "should have been called already"
         )
         return d
+
+    def test_is_built(self):
+        tor = FakeTorController()
+        a = FakeRouter('$E11D2B2269CC25E67CA6C9FB5843497539A74FD0', 'a')
+        b = FakeRouter('$50DD343021E509EB3A5A7FD0D8A4F8364AFBDCB5', 'b')
+        c = FakeRouter('$253DFF1838A2B7782BE7735F74E50090D46CA1BC', 'c')
+        tor.routers['$E11D2B2269CC25E67CA6C9FB5843497539A74FD0'] = a
+        tor.routers['$50DD343021E509EB3A5A7FD0D8A4F8364AFBDCB5'] = b
+        tor.routers['$253DFF1838A2B7782BE7735F74E50090D46CA1BC'] = c
+
+        circuit = Circuit(tor)
+        circuit.listen(tor)
+
+        circuit.update('123 EXTENDED $E11D2B2269CC25E67CA6C9FB5843497539A74FD0=eris,$50DD343021E509EB3A5A7FD0D8A4F8364AFBDCB5=venus,$253DFF1838A2B7782BE7735F74E50090D46CA1BC=chomsky PURPOSE=GENERAL'.split())
+        built0 = circuit.is_built
+        built1 = circuit.when_built()
+
+        self.assertTrue(built0 is not built1)
+        self.assertFalse(built0.called)
+        self.assertFalse(built1.called)
+
+        circuit.update('123 BUILT $E11D2B2269CC25E67CA6C9FB5843497539A74FD0=eris,$50DD343021E509EB3A5A7FD0D8A4F8364AFBDCB5=venus,$253DFF1838A2B7782BE7735F74E50090D46CA1BC=chomsky PURPOSE=GENERAL'.split())
+
+        # create callback when we're alread in BUILT; should be
+        # callback'd already
+        built2 = circuit.when_built()
+
+        self.assertTrue(built2 is not built1)
+        self.assertTrue(built2 is not built0)
+        self.assertTrue(built0.called)
+        self.assertTrue(built1.called)
+        self.assertTrue(built2.called)
+        self.assertTrue(built0.result == circuit)
+        self.assertTrue(built1.result == circuit)
+        self.assertTrue(built2.result == circuit)
+
+    def test_is_built_errback(self):
+        tor = FakeTorController()
+        a = FakeRouter('$E11D2B2269CC25E67CA6C9FB5843497539A74FD0', 'a')
+        tor.routers['$E11D2B2269CC25E67CA6C9FB5843497539A74FD0'] = a
+
+        state = TorState(tor)
+        circuit = Circuit(tor)
+        circuit.listen(tor)
+
+        circuit.update('123 EXTENDED $E11D2B2269CC25E67CA6C9FB5843497539A74FD0=eris PURPOSE=GENERAL'.split())
+        state.circuit_new(circuit)
+        d = circuit.when_built()
+
+        state.circuit_closed(circuit)
+
+        self.assertTrue(d.called)
+        self.assertTrue(isinstance(d.result, Failure))
diff --git a/txtorcon.egg-info/PKG-INFO b/txtorcon.egg-info/PKG-INFO
index 2581e2d..80d1067 100644
--- a/txtorcon.egg-info/PKG-INFO
+++ b/txtorcon.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: txtorcon
-Version: 0.14.0
+Version: 0.14.2
 Summary: Twisted-based Tor controller client, with state-tracking and configuration abstractions.
 Home-page: https://github.com/meejah/txtorcon
 Author: meejah
diff --git a/txtorcon.egg-info/SOURCES.txt b/txtorcon.egg-info/SOURCES.txt
index 0fa2460..61cc154 100644
--- a/txtorcon.egg-info/SOURCES.txt
+++ b/txtorcon.egg-info/SOURCES.txt
@@ -47,6 +47,7 @@ examples/circuit_failure_rates.py
 examples/circuit_for_next_stream.py
 examples/disallow_streams_by_port.py
 examples/dump_config.py
+examples/ephemeral_endpoint.py
 examples/hello_darkweb.py
 examples/hidden-service-systemd.service
 examples/hidden_echo.py
@@ -88,7 +89,6 @@ test/test_util_imports.py
 test/util.py
 twisted/plugins/txtorcon_endpoint_parser.py
 txtorcon/__init__.py
-txtorcon/_metadata.py
 txtorcon/addrmap.py
 txtorcon/circuit.py
 txtorcon/endpoints.py
diff --git a/txtorcon.egg-info/pbr.json b/txtorcon.egg-info/pbr.json
index 28f25f5..e18909d 100644
--- a/txtorcon.egg-info/pbr.json
+++ b/txtorcon.egg-info/pbr.json
@@ -1 +1 @@
-{"is_release": false, "git_version": "e0c3ef4"}
\ No newline at end of file
+{"is_release": false, "git_version": "1ae3aad"}
\ No newline at end of file
diff --git a/txtorcon/__init__.py b/txtorcon/__init__.py
index ecb912f..60d0f8c 100644
--- a/txtorcon/__init__.py
+++ b/txtorcon/__init__.py
@@ -7,7 +7,7 @@ from __future__ import with_statement
 
 # for now, this needs to be changed in setup.py also until I find a
 # better solution
-__version__ = '0.14.0'
+__version__ = '0.14.2'
 __author__ = 'meejah'
 __contact__ = 'meejah at meejah.ca'
 __url__ = 'https://github.com/meejah/txtorcon'
diff --git a/txtorcon/_metadata.py b/txtorcon/_metadata.py
deleted file mode 100644
index 45f41ac..0000000
--- a/txtorcon/_metadata.py
+++ /dev/null
@@ -1,6 +0,0 @@
-__version__ = '0.14.0'
-__author__ = 'meejah'
-__contact__ = 'meejah at meejah.ca'
-__url__ = 'https://github.com/meejah/txtorcon'
-__license__ = 'MIT'
-__copyright__ = 'Copyright 2012-2015'
diff --git a/txtorcon/circuit.py b/txtorcon/circuit.py
index 42f3873..21a6db8 100644
--- a/txtorcon/circuit.py
+++ b/txtorcon/circuit.py
@@ -66,9 +66,6 @@ class Circuit(object):
 
     :ivar id:
         The ID of this circuit, a number (or None if unset).
-
-    :ivar is_built:
-        A Deferred that will callback() when this Circuit hits BUILT state.
     """
 
     def __init__(self, routercontainer):
@@ -87,9 +84,6 @@ class Circuit(object):
         self.build_flags = []
         self.flags = {}
 
-        #: callback()d when this circuit hits BUILT
-        self.is_built = defer.Deferred()
-
         # this is used to hold a Deferred that will callback() when
         # this circuit is being CLOSED or FAILED.
         self._closing_deferred = None
@@ -97,6 +91,30 @@ class Circuit(object):
         # caches parsed value for time_created()
         self._time_created = None
 
+        # all notifications for when_built
+        self._when_built = []
+
+    # XXX backwards-compat for old .is_built for now
+    @property
+    def is_built(self):
+        return self.when_built()
+
+    def when_built(self):
+        """
+        Returns a Deferred that is callback()'d (with this Circuit
+        instance) when this circuit hits BUILT.
+
+        If it's already BUILT when this is called, you get an
+        already-successful Deferred; otherwise, the state must change
+        to BUILT.
+        """
+        d = defer.Deferred()
+        if self.state == 'BUILT':
+            d.callback(self)
+        else:
+            self._when_built.append(d)
+        return d
+
     @property
     def time_created(self):
         if self._time_created is not None:
@@ -190,8 +208,9 @@ class Circuit(object):
 
         if self.state == 'BUILT':
             [x.circuit_built(self) for x in self.listeners]
-            if not self.is_built.called:
-                self.is_built.callback(self)
+            for d in self._when_built:
+                d.callback(self)
+            self._when_built = []
 
         elif self.state == 'CLOSED':
             if len(self.streams) > 0:
diff --git a/txtorcon/endpoints.py b/txtorcon/endpoints.py
index 1c749ac..8042e69 100644
--- a/txtorcon/endpoints.py
+++ b/txtorcon/endpoints.py
@@ -12,10 +12,19 @@ import functools
 
 from txtorcon.util import available_tcp_port
 
+# backwards-compatibility dance: we "should" be using the
+# ...WithReactor class, but in Twisted prior to 14, there is no such
+# class (and the parse() doesn't provide a 'reactor' argument).
+try:
+    from twisted.internet.interfaces import IStreamClientEndpointStringParserWithReactor
+    _HAVE_TX_14 = True
+except ImportError:
+    from twisted.internet.interfaces import IStreamClientEndpointStringParser as IStreamClientEndpointStringParserWithReactor
+    _HAVE_TX_14 = False
+
 from twisted.internet import defer, reactor
 from twisted.python import log
 from twisted.internet.interfaces import IStreamServerEndpointStringParser
-from twisted.internet.interfaces import IStreamClientEndpointStringParser
 from twisted.internet.interfaces import IStreamServerEndpoint
 from twisted.internet.interfaces import IStreamClientEndpoint
 from twisted.internet.interfaces import IListeningPort
@@ -688,7 +697,7 @@ class TorClientEndpoint(object):
         return d
 
 
- at implementer(IPlugin, IStreamClientEndpointStringParser)
+ at implementer(IPlugin, IStreamClientEndpointStringParserWithReactor)
 class TorClientEndpointStringParser(object):
     """
     This provides a twisted IPlugin and
@@ -739,4 +748,8 @@ class TorClientEndpointStringParser(object):
         )
 
     def parseStreamClient(self, *args, **kwargs):
+        # for Twisted 14 and 15 (and more) the first argument is
+        # 'reactor', for older Twisteds it's not
+        if _HAVE_TX_14:
+            return self._parseClient(*args[1:], **kwargs)
         return self._parseClient(*args, **kwargs)
diff --git a/txtorcon/torcontrolprotocol.py b/txtorcon/torcontrolprotocol.py
index ad8b8d0..410e14d 100644
--- a/txtorcon/torcontrolprotocol.py
+++ b/txtorcon/torcontrolprotocol.py
@@ -602,7 +602,9 @@ class TorControlProtocol(LineOnlyReceiver):
             self.debuglog.write(cmd + '\n')
             self.debuglog.flush()
 
-            self.transport.write(cmd + '\r\n')
+            data = cmd + '\r\n'
+            txtorlog.msg("cmd: {}".format(data.strip()))
+            self.transport.write(data.encode('utf8'))
 
     def _auth_failed(self, fail):
         """
diff --git a/txtorcon/torstate.py b/txtorcon/torstate.py
index 2861e92..394cdb6 100644
--- a/txtorcon/torstate.py
+++ b/txtorcon/torstate.py
@@ -632,6 +632,7 @@ class TorState(object):
         #    2. DO_NOT_ATTACH: don't attach the stream at all
         #    3. Circuit instance: attach to the provided circuit
         def issue_stream_attach(circ):
+            txtorlog.msg("circuit:", circ)
             if circ is None:
                 # tell Tor to do what it likes
                 return self.protocol.queue_command("ATTACHSTREAM %d 0" % stream.id)
@@ -905,6 +906,8 @@ class TorState(object):
     def circuit_destroy(self, circuit):
         "Used by circuit_closed and circuit_failed (below)"
         txtorlog.msg("circuit_destroy:", circuit.id)
+        for d in circuit._when_built:
+            d.errback(Exception("Destroying circuit; will never hit BUILT"))
         del self.circuits[circuit.id]
 
     def circuit_closed(self, circuit, **kw):

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/txtorcon.git



More information about the Pkg-privacy-commits mailing list