Bug#719520: pu: package coherence/0.6.6.2-6
tag 719520 patch
thanks
[ Cyril Brulebois ]
> Eric Evans <eevans@debian.org> (2013-08-12):
> > In python-coherence, coherence.upnp.core.utils.HeaderAwareHTTPClientFactory
> > (coherence/upnp/core/utils.py) sub-classes twisted.web.client.HTTPDownloader
> > (from package python-twisted-web), and in the process (uselessly )overrides
> > the __init__ method and makes use of a "private" attribute. As a result, it
> > broke when that attribute was dropped in a major release of Twisted.
> >
> > I think this bug is grave. Anything that uses utils.getPage is affected,
> > which includes the internal control point; The default config and all of
> > the examples fail predictably.
> >
> > It was reported in 664027[1] in March of 2012, but went unfixed and was
> > released as part of wheezy, (the bug priority was "important").
> >
> > The attached patch came from the corresponding upstream bug report[2], and
> > has been well tested by myself and others (see replies to [1] and [2]).
> >
> > I just adopted coherence and have uploaded the fix to unstable, is there any
> > chance a fix could make its way to stable-proposed-updates as well?
>
> it looks reasonable to me; please post a debdiff with that patch applied
> on top of 0.6.6.2-6, versioned as 0.6.6.2-6+deb7u1 (I don't mind updated
> Maintainer/Uploaders in the process), targeting 'wheezy' for a last review.
Great; debdiff attached
Thanks!
--
Eric Evans
eevans@sym-link.com
diff -Nru coherence-0.6.6.2/debian/changelog coherence-0.6.6.2/debian/changelog
--- coherence-0.6.6.2/debian/changelog 2011-07-31 21:52:04.000000000 -0500
+++ coherence-0.6.6.2/debian/changelog 2013-09-23 15:41:41.000000000 -0500
@@ -1,3 +1,9 @@
+coherence (0.6.6.2-6+deb7u1) unstable; urgency=low
+
+ * Patch to fix tracebacks for missing attribute (Closes: #664027).
+
+ -- Eric Evans <eevans@debian.org> Mon, 23 Sep 2013 15:41:28 -0500
+
coherence (0.6.6.2-6) unstable; urgency=low
* added pydist-overrided for dhp2 error concerning python-configobj.
diff -Nru coherence-0.6.6.2/debian/control coherence-0.6.6.2/debian/control
--- coherence-0.6.6.2/debian/control 2011-08-03 12:17:27.000000000 -0500
+++ coherence-0.6.6.2/debian/control 2013-09-23 15:44:54.000000000 -0500
@@ -1,9 +1,7 @@
Source: coherence
Section: python
Priority: extra
-Maintainer: Arnaud Quette <aquette@debian.org>
-Uploaders: Loic Minier <lool@dooz.org>, Charlie Smotherman <cjsmo@cableone.net>,
- Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>
+Maintainer: Eric Evans <eevans@debian.org>
Build-Depends: debhelper (>= 7.0.50),
python (>= 2.6.6-3),
python-setuptools,
diff -Nru coherence-0.6.6.2/debian/patches/04_missing_attribute_fix coherence-0.6.6.2/debian/patches/04_missing_attribute_fix
--- coherence-0.6.6.2/debian/patches/04_missing_attribute_fix 1969-12-31 18:00:00.000000000 -0600
+++ coherence-0.6.6.2/debian/patches/04_missing_attribute_fix 2013-08-12 08:32:33.000000000 -0500
@@ -0,0 +1,170 @@
+Description: do not override private init
+ A sub-class of HTTPClientFactory overrides the __init__ method without
+ calling super's, and changes in a Twisted major release resulted in
+ breakage.
+ .
+ This patch by "marco" (found attached to issue #360 upstream), solves
+ the bug by eliminating the __init__ override.
+Origin: http://coherence.beebits.net/attachment/ticket/360/getPage.patch
+Bug: http://coherence.beebits.net/ticket/360
+Bug-Debian: http://bugs.debian.org/664027
+Forwarded: not-needed
+Reviewed-By: Eric Evans <eevans@debian.org>
+Last-Update: 2013-08-11
+
+--- coherence-0.6.6.2.orig/coherence/upnp/core/utils.py
++++ coherence-0.6.6.2/coherence/upnp/core/utils.py
+@@ -517,48 +517,14 @@ class HeaderAwareHTTPClientFactory(clien
+ protocol = myHTTPPageGetter
+ noisy = False
+
+- def __init__(self, url, method='GET', postdata=None, headers=None,
+- agent="Twisted PageGetter", timeout=0, cookies=None,
+- followRedirect=True, redirectLimit=20):
+- self.followRedirect = followRedirect
+- self.redirectLimit = redirectLimit
+- self._redirectCount = 0
+- self.timeout = timeout
+- self.agent = agent
+-
+- if cookies is None:
+- cookies = {}
+- self.cookies = cookies
+- if headers is not None:
+- self.headers = InsensitiveDict(headers)
+- else:
+- self.headers = InsensitiveDict()
+- if postdata is not None:
+- self.headers.setdefault('Content-Length', len(postdata))
+- # just in case a broken http/1.1 decides to keep connection alive
+- self.headers.setdefault("connection", "close")
+- self.postdata = postdata
+- self.method = method
+-
+- self.setURL(url)
+-
+- self.waiting = 1
+- self.deferred = defer.Deferred()
+- self.response_headers = None
+-
+ def buildProtocol(self, addr):
+- p = protocol.ClientFactory.buildProtocol(self, addr)
++ p = client.HTTPClientFactory.buildProtocol(self, addr)
+ p.method = self.method
+ p.followRedirect = self.followRedirect
+- if self.timeout:
+- timeoutCall = reactor.callLater(self.timeout, p.timeout)
+- self.deferred.addBoth(self._cancelTimeout, timeoutCall)
+ return p
+
+ def page(self, page):
+- if self.waiting:
+- self.waiting = 0
+- self.deferred.callback((page, self.response_headers))
++ client.HTTPClientFactory.page(self, (page, self.response_headers))
+
+
+ class HeaderAwareHTTPDownloader(client.HTTPDownloader):
+@@ -577,24 +543,22 @@ class HeaderAwareHTTPDownloader(client.H
+ self.requestedPartial = 0
+
+
++
+ def getPage(url, contextFactory=None, *args, **kwargs):
+- """Download a web page as a string.
++ """
++ Download a web page as a string.
+
+ Download a page. Return a deferred, which will callback with a
+ page (as a string) or errback with a description of the error.
+
+ See HTTPClientFactory to see what extra args can be passed.
+ """
+- scheme, host, port, path = client._parse(url)
+- factory = HeaderAwareHTTPClientFactory(url, *args, **kwargs)
+- if scheme == 'https':
+- from twisted.internet import ssl
+- if contextFactory is None:
+- contextFactory = ssl.ClientContextFactory()
+- reactor.connectSSL(host, port, factory, contextFactory)
+- else:
+- reactor.connectTCP(host, port, factory)
+- return factory.deferred
++ kwargs['agent'] = "Coherence PageGetter"
++ return client._makeGetterFactory(
++ url,
++ HeaderAwareHTTPClientFactory,
++ contextFactory=contextFactory,
++ *args, **kwargs).deferred
+
+
+ def downloadPage(url, file, contextFactory=None, *args, **kwargs):
+--- coherence-0.6.6.2.orig/coherence/upnp/core/test/test_utils.py
++++ coherence-0.6.6.2/coherence/upnp/core/test/test_utils.py
+@@ -9,9 +9,14 @@
+ Test cases for L{upnp.core.utils}
+ """
+
++import os
+ from twisted.trial import unittest
++from twisted.python.filepath import FilePath
++from twisted.internet import reactor
++from twisted.web import static, server
++from twisted.protocols import policies
+
+-from coherence.upnp.core.utils import *
++from coherence.upnp.core import utils
+
+ # This data is joined using CRLF pairs.
+ testChunkedData = ['200',
+@@ -121,9 +126,49 @@ class TestUpnpUtils(unittest.TestCase):
+ based on a test and data provided by Lawrence
+ """
+ testData = '\r\n'.join(testChunkedData)
+- newData = de_chunk_payload(testData)
++ newData = utils.de_chunk_payload(testData)
+ # see whether we can parse the result
+ self.assertEqual(newData, '\r\n'.join( testChunkedDataResult))
+
+
++class TestClient(unittest.TestCase):
++
++ def _listen(self, site):
++ return reactor.listenTCP(0, site, interface="127.0.0.1")
++
++ def setUp(self):
++ name = self.mktemp()
++ os.mkdir(name)
++ FilePath(name).child("file").setContent("0123456789")
++ r = static.File(name)
++ self.site = server.Site(r, timeout=None)
++ self.wrapper = policies.WrappingFactory(self.site)
++ self.port = self._listen(self.wrapper)
++ self.portno = self.port.getHost().port
++
++ def tearDown(self):
++ return self.port.stopListening()
++
++ def getURL(self, path):
++ return "http://127.0.0.1:%d/%s" % (self.portno, path)
++
++ def assertResponse(self, original, content, headers):
++ self.assertIsInstance(original, tuple)
++ self.assertEqual(original[0], content)
++ originalHeaders = original[1]
++ for header in headers:
++ self.assertIn(header, originalHeaders)
++ self.assertEqual(originalHeaders[header], headers[header])
++
++ def test_getPage(self):
++ content = '0123456789'
++ headers = {'accept-ranges': ['bytes'],
++ 'content-length': ['10'],
++ 'content-type': ['text/html']}
++ d = utils.getPage(self.getURL("file"))
++ d.addCallback(self.assertResponse, content, headers)
++ return d
++
++
++
+ # $Id:$
diff -Nru coherence-0.6.6.2/debian/patches/series coherence-0.6.6.2/debian/patches/series
--- coherence-0.6.6.2/debian/patches/series 2011-07-31 21:52:04.000000000 -0500
+++ coherence-0.6.6.2/debian/patches/series 2013-09-23 15:39:09.000000000 -0500
@@ -1,4 +1,4 @@
03_last_updated_service_field_workaround
02_string_exception_fix
01_systray_fix
-
+04_missing_attribute_fix
Reply to: