[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