tag 719520 patch
thanks

[ Cyril Brulebois ]
> Eric Evans <eev...@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
eev...@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 <eev...@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 <aque...@debian.org>
-Uploaders: Loic Minier <l...@dooz.org>, Charlie Smotherman <cj...@cableone.net>,
- Debian Python Modules Team <python-modules-t...@lists.alioth.debian.org>
+Maintainer: Eric Evans <eev...@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 <eev...@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 via email to