r46812 - Apply 8191_2.patch.

adiroiban-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: adiroiban
Date: Wed Feb 17 15:05:43 2016
New Revision: 46812

Modified:
   branches/hide-request-transport-8191-2/twisted/web/http.py
   branches/hide-request-transport-8191-2/twisted/web/server.py
   branches/hide-request-transport-8191-2/twisted/web/test/requesthelper.py
   branches/hide-request-transport-8191-2/twisted/web/test/test_http.py
   branches/hide-request-transport-8191-2/twisted/web/test/test_proxy.py
   branches/hide-request-transport-8191-2/twisted/web/test/test_web.py
   branches/hide-request-transport-8191-2/twisted/web/wsgi.py

Log:
Apply 8191_2.patch.

Modified: branches/hide-request-transport-8191-2/twisted/web/http.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/http.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/http.py	Wed Feb 17 15:05:43 2016
@@ -562,6 +562,16 @@
         which this request was received is closed and which is C{True} after
         that.
     @type _disconnected: C{bool}
+
+    @ivar _queuedHeaders: A C{tuple} of items that would normally be passed to
+        L{HTTPChannel.writeHeaders}. Used when the response is queued to store
+        the eventual headers.
+    @type _queuedHeaders: A C{tuple} of HTTP version (C{bytes}), status code
+        (C{int}), reason phrase (C{bytes}), and headers (C{list} of C{tuple}s
+        of C{(bytes, bytes)}.
+
+    @ivar _send100: Whether to send a 100-Continue response when unqueued.
+    @type _send100: C{bool}
     """
     producer = None
     finished = 0
@@ -580,6 +590,8 @@
     content = None
     _forceSSL = 0
     _disconnected = False
+    _queuedHeaders = None
+    _send100 = False
 
     def __init__(self, channel, queued):
         """
@@ -588,7 +600,7 @@
             the transport?
         """
         self.notifications = []
-        self.channel = channel
+        self._channel = channel
         self.queued = queued
         self.requestHeaders = Headers()
         self.received_cookies = {}
@@ -596,9 +608,53 @@
         self.cookies = [] # outgoing cookies
 
         if queued:
-            self.transport = StringTransport()
+            self._transport = StringTransport()
         else:
-            self.transport = self.channel.transport
+            self._transport = self._channel
+
+
+    @property
+    def transport(self):
+        warnings.warn(
+            "Request.transport is deprecated in Twisted 16.0. Call directly "
+            "into the Request object instead.",
+            category=DeprecationWarning,
+            stacklevel=2
+        )
+        return self._transport
+
+
+    @transport.setter
+    def transport(self, value):
+        warnings.warn(
+            "Request.transport is deprecated in Twisted 16.0. Call directly "
+            "into the Request object instead.",
+            category=DeprecationWarning,
+            stacklevel=2
+        )
+        self._transport = value
+
+
+    @property
+    def channel(self):
+        warnings.warn(
+            "Request.channel is deprecated in Twisted 16.0. Call directly "
+            "into the Request object instead.",
+            category=DeprecationWarning,
+            stacklevel=2
+        )
+        return self._channel
+
+
+    @channel.setter
+    def channel(self, value):
+        warnings.warn(
+            "Request.channel is deprecated in Twisted 16.0. Call directly "
+            "into the Request object instead",
+            category=DeprecationWarning,
+            stacklevel=2
+        )
+        self._channel = value
 
 
     def _cleanup(self):
@@ -608,8 +664,8 @@
         if self.producer:
             log.err(RuntimeError("Producer was not unregistered for %s" % self.uri))
             self.unregisterProducer()
-        self.channel.requestDone(self)
-        del self.channel
+        self._channel.requestDone(self)
+        del self._channel
         try:
             self.content.close()
         except OSError:
@@ -636,14 +692,19 @@
         self.queued = 0
 
         # set transport to real one and send any buffer data
-        data = self.transport.getvalue()
-        self.transport = self.channel.transport
+        data = self._transport.getvalue()
+        self._transport = self._channel
+        if self._send100:
+            self.channel.send100Continue()
+        if self._queuedHeaders:
+            self._transport.writeHeaders(*self._queuedHeaders)
+            self._queuedHeaders = None
         if data:
-            self.transport.write(data)
+            self._transport.write(data)
 
         # if we have producer, register it with transport
         if (self.producer is not None) and not self.finished:
-            self.transport.registerProducer(self.producer, self.streamingProducer)
+            self._transport.registerProducer(self.producer, self.streamingProducer)
 
         # if we're finished, clean up
         if self.finished:
@@ -727,8 +788,8 @@
 
         # cache the client and server information, we'll need this later to be
         # serialized and sent with the request so CGIs will work remotely
-        self.client = self.channel.transport.getPeer()
-        self.host = self.channel.transport.getHost()
+        self.client = self._channel.getPeer()
+        self.host = self._channel.getHost()
 
         # Argument processing
         args = self.args
@@ -755,7 +816,7 @@
                         self.args.update(cgiArgs)
                 except:
                     # It was a bad request.
-                    _respondToBadRequestAndDisconnect(self.channel.transport)
+                    _respondToBadRequestAndDisconnect(self._channel)
                     return
             self.content.seek(0, 0)
 
@@ -805,14 +866,14 @@
             if streaming:
                 producer.pauseProducing()
         else:
-            self.transport.registerProducer(producer, streaming)
+            self._channel.registerProducer(producer, streaming)
 
     def unregisterProducer(self):
         """
         Unregister the producer.
         """
         if not self.queued:
-            self.transport.unregisterProducer()
+            self._channel.unregisterProducer()
         self.producer = None
 
 
@@ -870,15 +931,15 @@
 
         if not self.startedWriting:
             # write headers
-            self.write('')
+            self.write(b'')
 
         if self.chunked:
             # write last chunk and closing CRLF
-            self.transport.write(b"0\r\n\r\n")
+            self._transport.write(b"0\r\n\r\n")
 
         # log request
-        if hasattr(self.channel, "factory"):
-            self.channel.factory.log(self)
+        if hasattr(self._channel, "factory"):
+            self._channel.factory.log(self)
 
         self.finished = 1
         if not self.queued:
@@ -899,11 +960,10 @@
         if not self.startedWriting:
             self.startedWriting = 1
             version = self.clientproto
-            l = []
-            l.append(
-                version + b" " +
-                intToBytes(self.code) + b" " +
-                self.code_message + b"\r\n")
+            code = intToBytes(self.code)
+            reason = self.code_message
+
+            headers = []
 
             # if we don't have a content length, we send data in
             # chunked mode, so that we can support pipelining in
@@ -911,7 +971,7 @@
             if ((version == b"HTTP/1.1") and
                 (self.responseHeaders.getRawHeaders(b'content-length') is None) and
                 self.method != b"HEAD" and self.code not in NO_BODY_CODES):
-                l.append(b'Transfer-Encoding: chunked\r\n')
+                headers.append((b'Transfer-Encoding', 'chunked'))
                 self.chunked = 1
 
             if self.lastModified is not None:
@@ -935,14 +995,15 @@
                             category=DeprecationWarning, stacklevel=2)
                         # Backward compatible cast for non-bytes values
                         value = networkString('%s' % (value,))
-                    l.extend([name, b": ", value, b"\r\n"])
+                    headers.append((name, value))
 
             for cookie in self.cookies:
-                l.append(networkString('Set-Cookie: %s\r\n' % (cookie,)))
+                headers.append((b'Set-Cookie', networkString(cookie)))
 
-            l.append(b"\r\n")
-
-            self.transport.writeSequence(l)
+            if self.queued:
+                self._queuedHeaders = (version, code, reason, headers)
+            else:
+                self._channel.writeHeaders(version, code, reason, headers)
 
             # if this is a "HEAD" request, we shouldn't return any data
             if self.method == b"HEAD":
@@ -957,9 +1018,9 @@
         self.sentLength = self.sentLength + len(data)
         if data:
             if self.chunked:
-                self.transport.writeSequence(toChunk(data))
+                self._transport.writeSequence(toChunk(data))
             else:
-                self.transport.write(data)
+                self._transport.write(data)
 
     def addCookie(self, k, v, expires=None, domain=None, path=None,
                   max_age=None, comment=None, secure=None, httpOnly=False):
@@ -1233,7 +1294,9 @@
         """
         if self._forceSSL:
             return True
-        transport = getattr(getattr(self, 'channel', None), 'transport', None)
+        transport = getattr(
+            getattr(self, '_channel', None), 'transport', None
+        )
         if interfaces.ISSLTransport(transport, None) is not None:
             return True
         return False
@@ -1308,13 +1371,31 @@
         Clean up anything which can't be useful anymore.
         """
         self._disconnected = True
-        self.channel = None
+        self._channel = None
         if self.content is not None:
             self.content.close()
         for d in self.notifications:
             d.errback(reason)
         self.notifications = []
 
+
+    def loseConnection(self):
+        """
+        Pass the loseConnection through to the underlying channel.
+        """
+        self._channel.loseConnection()
+
+
+    def send100Continue(self):
+        """
+        Sends a "100 Continue" status code, where 100 Continue is supported.
+        """
+        if not self.queued:
+            self._channel.send100Continue()
+        else:
+            self._send100 = True
+
+
 Request.getClient = deprecated(
     Version("Twisted", 15, 0, 0),
     "Twisted Names to resolve hostnames")(Request.getClient)
@@ -1754,7 +1835,7 @@
         expectContinue = req.requestHeaders.getRawHeaders(b'expect')
         if (expectContinue and expectContinue[0].lower() == b'100-continue' and
             self._version == b'HTTP/1.1'):
-            req.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n")
+            req.send100Continue()
 
 
     def checkPersistence(self, request, version):
@@ -1828,6 +1909,103 @@
             request.connectionLost(reason)
 
 
+    def writeHeaders(self, version, code, reason, headers):
+        """
+        Called by C{Request} objects to write a complete set of HTTP headers to
+        a transport.
+
+        @param version: The HTTP version in use.
+        @type version: C{bytes}
+
+        @param code: The HTTP status code to write.
+        @type code: C{bytes}
+
+        @param reason: The HTTP reason phrase to write.
+        @type reason: C{bytes}
+
+        @param headers: The headers to write to the transport.
+        @type headers: L{twisted.web.http_headers.Headers}
+        """
+        response_line = version + b" " + code + b" " + reason + b"\r\n"
+        headerSequence = [response_line]
+        headerSequence.extend(
+            name + b': ' + value + b"\r\n" for name, value in headers
+        )
+        headerSequence.append("\r\n")
+        self.transport.writeSequence(headerSequence)
+
+
+    def registerProducer(self, producer, streaming):
+        """
+        @see L{IConsumer.registerProducer}
+        """
+        return self.transport.registerProducer(producer, streaming)
+
+
+    def unregisterProducer(self):
+        """
+        @see L{IConsumer.unregisterProducer}
+        """
+        return self.transport.unregisterProducer()
+
+
+    def write(self, data):
+        """
+        Called by C{Request} objects to write response data.
+
+        @param data: The data chunk to write to the stream.
+        @type data: C{bytes}
+        """
+        self.transport.write(data)
+
+
+    def writeSequence(self, iovec):
+        """
+        Write a list of strings to the HTTP response.
+
+        @param iovec: A list of byte strings to write to the stream.
+        @type data: C{list} of C{bytes}
+        """
+        self.transport.writeSequence(iovec)
+
+
+    def getPeer(self):
+        """
+        Get the remote address of this connection.
+
+        @return: An L{IAddress} provider.
+        """
+        return self.transport.getPeer()
+
+
+    def getHost(self):
+        """
+        Get the local address of this connection.
+
+        @return: An L{IAddress} provider.
+        """
+        return self.transport.getHost()
+
+
+    def loseConnection(self):
+        """
+        Closes the connection. Will write any data that is pending to be sent
+        on the network, but if this response has not yet been written to the
+        network will not write anything.
+        """
+        # TODO: Does this need to be smarter, particularly about queued
+        # responses?
+        return self.transport.loseConnection()
+
+
+    def send100Continue(self):
+        """
+        Sends a 100 Continue response, used to signal to clients that further
+        processing will be performed.
+        """
+        self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n")
+
+
 
 def _respondToBadRequestAndDisconnect(transport):
     """

Modified: branches/hide-request-transport-8191-2/twisted/web/server.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/server.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/server.py	Wed Feb 17 15:05:43 2016
@@ -110,10 +110,10 @@
 
     def getStateToCopyFor(self, issuer):
         x = self.__dict__.copy()
-        del x['transport']
+        del x['_transport']
         # XXX refactor this attribute out; it's from protocol
         # del x['server']
-        del x['channel']
+        del x['_channel']
         del x['content']
         del x['site']
         self.content.seek(0, 0)
@@ -164,7 +164,7 @@
         """
 
         # get site from channel
-        self.site = self.channel.site
+        self.site = self._channel.site
 
         # set various default headers
         self.setHeader(b'server', version)

Modified: branches/hide-request-transport-8191-2/twisted/web/test/requesthelper.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/test/requesthelper.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/test/requesthelper.py	Wed Feb 17 15:05:43 2016
@@ -53,6 +53,9 @@
         def registerProducer(self, producer, streaming):
             self.producers.append((producer, streaming))
 
+        def unregisterProducer(self):
+            pass
+
         def loseConnection(self):
             self.disconnected = True
 
@@ -71,6 +74,53 @@
         pass
 
 
+    def writeHeaders(self, version, code, reason, headers):
+        response_line = version + b" " + code + b" " + reason + b"\r\n"
+        headerSequence = [response_line]
+        headerSequence.extend(
+            name + b': ' + value + b"\r\n" for name, value in headers
+        )
+        headerSequence.append("\r\n")
+        self.transport.writeSequence(headerSequence)
+
+
+    def getPeer(self):
+        return self.transport.getPeer()
+
+
+    def getHost(self):
+        return self.transport.getHost()
+
+
+    def registerProducer(self, producer, streaming):
+        self.transport.registerProducer(producer, streaming)
+
+
+    def unregisterProducer(self):
+        self.transport.unregisterProducer()
+
+
+    def write(self, data):
+        self.transport.write(data)
+
+
+    def writeSequence(self, iovec):
+        self.transport.writeSequence(iovec)
+
+
+    def loseConnection(self):
+        self.transport.loseConnection()
+
+
+    def endRequest(self):
+        pass
+
+
+    @property
+    def producers(self):
+        return self.transport.producers
+
+
 
 class DummyRequest(object):
     """

Modified: branches/hide-request-transport-8191-2/twisted/web/test/test_http.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/test/test_http.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/test/test_http.py	Wed Feb 17 15:05:43 2016
@@ -235,6 +235,7 @@
         self.assertEqual(response, expectedResponse)
 
 
+
 class HTTPLoopbackTests(unittest.TestCase):
 
     expectedHeaders = {b'request': b'/foo/bar',
@@ -1146,7 +1147,7 @@
                 content.append(self.content.read())
                 method.append(self.method)
                 path.append(self.path)
-                decoder.append(self.channel._transferDecoder)
+                decoder.append(self._channel._transferDecoder)
                 testcase.didRequest = True
                 self.finish()
 
@@ -1556,10 +1557,12 @@
         For an HTTP 1.0 request, L{http.Request.write} sends an HTTP 1.0
         Response-Line and whatever response headers are set.
         """
-        req = http.Request(DummyChannel(), False)
+        channel = DummyChannel()
         trans = StringTransport()
+        channel.transport = trans
+        req = http.Request(channel, False)
 
-        req.transport = trans
+        req._transport = trans
 
         req.setResponseCode(200)
         req.clientproto = b"HTTP/1.0"
@@ -1578,10 +1581,12 @@
         L{http.Request.write} casts non-bytes header value to bytes
         transparently.
         """
-        req = http.Request(DummyChannel(), False)
+        channel = DummyChannel()
         trans = StringTransport()
+        channel.transport = trans
+        req = http.Request(channel, False)
 
-        req.transport = trans
+        req._transport = trans
 
         req.setResponseCode(200)
         req.clientproto = b"HTTP/1.0"
@@ -1610,10 +1615,12 @@
         Response-Line, whatever response headers are set, and uses chunked
         encoding for the response body.
         """
-        req = http.Request(DummyChannel(), False)
+        channel = DummyChannel()
         trans = StringTransport()
+        channel.transport = trans
+        req = http.Request(channel, False)
 
-        req.transport = trans
+        req._transport = trans
 
         req.setResponseCode(200)
         req.clientproto = b"HTTP/1.1"
@@ -1635,10 +1642,12 @@
         L{http.Request.write} sends an HTTP Response-Line, whatever response
         headers are set, and a last-modified header with that time.
         """
-        req = http.Request(DummyChannel(), False)
+        channel = DummyChannel()
         trans = StringTransport()
+        channel.transport = trans
+        req = http.Request(channel, False)
 
-        req.transport = trans
+        req._transport = trans
 
         req.setResponseCode(200)
         req.clientproto = b"HTTP/1.0"
@@ -1793,7 +1802,7 @@
         # Then something goes wrong and content should get closed.
         req.connectionLost(Failure(ConnectionLost("Finished")))
         self.assertTrue(content.closed)
-        self.assertIdentical(req.channel, None)
+        self.assertIdentical(req._channel, None)
 
 
     def test_registerProducerTwiceFails(self):
@@ -1846,7 +1855,7 @@
         # This is a roundabout assertion: http.StringTransport doesn't
         # implement registerProducer, so Request.registerProducer can't have
         # tried to call registerProducer on the transport.
-        self.assertIsInstance(req.transport, http.StringTransport)
+        self.assertIsInstance(req._transport, http.StringTransport)
 
 
     def test_registerProducerWhenQueuedDoesntRegisterPullProducer(self):
@@ -1865,7 +1874,7 @@
         # This is a roundabout assertion: http.StringTransport doesn't
         # implement registerProducer, so Request.registerProducer can't have
         # tried to call registerProducer on the transport.
-        self.assertIsInstance(req.transport, http.StringTransport)
+        self.assertIsInstance(req._transport, http.StringTransport)
 
 
     def test_registerProducerWhenNotQueuedRegistersPushProducer(self):
@@ -1877,7 +1886,7 @@
         req = http.Request(DummyChannel(), False)
         producer = DummyProducer()
         req.registerProducer(producer, True)
-        self.assertEqual([(producer, True)], req.transport.producers)
+        self.assertEqual([(producer, True)], req._transport.producers)
 
 
     def test_registerProducerWhenNotQueuedRegistersPullProducer(self):
@@ -1889,7 +1898,7 @@
         req = http.Request(DummyChannel(), False)
         producer = DummyProducer()
         req.registerProducer(producer, False)
-        self.assertEqual([(producer, False)], req.transport.producers)
+        self.assertEqual([(producer, False)], req._transport.producers)
 
 
     def test_connectionLostNotification(self):
@@ -1901,7 +1910,7 @@
         request = http.Request(d, True)
         finished = request.notifyFinish()
         request.connectionLost(Failure(ConnectionLost("Connection done")))
-        self.assertIdentical(request.channel, None)
+        self.assertIdentical(request._channel, None)
         return self.assertFailure(finished, ConnectionLost)
 
 
@@ -1997,10 +2006,10 @@
         producer from the request and the request's transport.
         """
         req = http.Request(DummyChannel(), False)
-        req.transport = StringTransport()
+        req._transport = StringTransport()
         req.registerProducer(DummyProducer(), False)
         req.unregisterProducer()
-        self.assertEqual((None, None), (req.producer, req.transport.producer))
+        self.assertEqual((None, None), (req.producer, req._transport.producer))
 
 
     def test_unregisterNonQueuedStreamingProducer(self):
@@ -2009,10 +2018,10 @@
         producer from the request and the request's transport.
         """
         req = http.Request(DummyChannel(), False)
-        req.transport = StringTransport()
+        req._transport = StringTransport()
         req.registerProducer(DummyProducer(), True)
         req.unregisterProducer()
-        self.assertEqual((None, None), (req.producer, req.transport.producer))
+        self.assertEqual((None, None), (req.producer, req._transport.producer))
 
 
     def test_unregisterQueuedNonStreamingProducer(self):

Modified: branches/hide-request-transport-8191-2/twisted/web/test/test_proxy.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/test/test_proxy.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/test/test_proxy.py	Wed Feb 17 15:05:43 2016
@@ -123,6 +123,14 @@
         self.lostReason = reason
 
 
+    def getPeer(self):
+        return self.transport.getPeer()
+
+
+    def getHost(self):
+        return self.transport.getHost()
+
+
 
 class ProxyClientTests(TestCase):
     """

Modified: branches/hide-request-transport-8191-2/twisted/web/test/test_web.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/test/test_web.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/test/test_web.py	Wed Feb 17 15:05:43 2016
@@ -505,8 +505,8 @@
         fail = failure.Failure(Exception("Oh no!"))
         request.processingFailed(fail)
 
-        self.assertNotIn(b"Oh no!", request.transport.getvalue())
-        self.assertIn(b"Processing Failed", request.transport.getvalue())
+        self.assertNotIn(b"Oh no!", request._transport.getvalue())
+        self.assertIn(b"Processing Failed", request._transport.getvalue())
 
         # Since we didn't "handle" the exception, flush it to prevent a test
         # failure
@@ -525,7 +525,7 @@
         fail = failure.Failure(Exception("Oh no!"))
         request.processingFailed(fail)
 
-        self.assertIn(b"Oh no!", request.transport.getvalue())
+        self.assertIn(b"Oh no!", request._transport.getvalue())
 
         # Since we didn't "handle" the exception, flush it to prevent a test
         # failure
@@ -545,7 +545,7 @@
         fail = failure.Failure(Exception(u"\u2603"))
         request.processingFailed(fail)
 
-        self.assertIn(b"&#9731;", request.transport.getvalue())
+        self.assertIn(b"&#9731;", request._transport.getvalue())
 
         # Since we didn't "handle" the exception, flush it to prevent a test
         # failure
@@ -774,11 +774,11 @@
     def testGoodMethods(self):
         req = self._getReq()
         req.requestReceived(b'GET', b'/newrender', b'HTTP/1.0')
-        self.assertEqual(req.transport.getvalue().splitlines()[-1], b'hi hi')
+        self.assertEqual(req._transport.getvalue().splitlines()[-1], b'hi hi')
 
         req = self._getReq()
         req.requestReceived(b'HEH', b'/newrender', b'HTTP/1.0')
-        self.assertEqual(req.transport.getvalue().splitlines()[-1], b'ho ho')
+        self.assertEqual(req._transport.getvalue().splitlines()[-1], b'ho ho')
 
     def testBadMethods(self):
         req = self._getReq()
@@ -806,7 +806,7 @@
         req = self._getReq()
         req.requestReceived(b'HEAD', b'/newrender', b'HTTP/1.0')
         self.assertEqual(req.code, 200)
-        self.assertEqual(-1, req.transport.getvalue().find(b'hi hi'))
+        self.assertEqual(-1, req._transport.getvalue().find(b'hi hi'))
 
 
     def test_unsupportedHead(self):
@@ -817,7 +817,7 @@
         resource = HeadlessResource()
         req = self._getReq(resource)
         req.requestReceived(b"HEAD", b"/newrender", b"HTTP/1.0")
-        headers, body = req.transport.getvalue().split(b'\r\n\r\n')
+        body = req._transport.getvalue()
         self.assertEqual(req.code, 200)
         self.assertEqual(body, b'')
 
@@ -838,7 +838,7 @@
 
         request.requestReceived(b"GET", b"/newrender", b"HTTP/1.0")
 
-        headers, body = request.transport.getvalue().split(b'\r\n\r\n')
+        body = request._transport.getvalue()
         self.assertEqual(request.code, 500)
         expected = [
             '',
@@ -939,7 +939,7 @@
         req.requestReceived(b'POST', b'/gettableresource?'
                             b'value=<script>bad', b'HTTP/1.0')
         self.assertEqual(req.code, 405)
-        renderedPage = req.transport.getvalue()
+        renderedPage = req._transport.getvalue()
         self.assertNotIn(b"<script>bad", renderedPage)
         self.assertIn(b'&lt;script&gt;bad', renderedPage)
 
@@ -954,7 +954,7 @@
         req = self._getReq()
         req.requestReceived(b'<style>bad', b'/gettableresource', b'HTTP/1.0')
         self.assertEqual(req.code, 501)
-        renderedPage = req.transport.getvalue()
+        renderedPage = req._transport.getvalue()
         self.assertNotIn(b"<style>bad", renderedPage)
         self.assertIn(b'&lt;style&gt;bad', renderedPage)
 
@@ -1262,7 +1262,7 @@
         """
         self.site._logDateTime = "[%02d/%3s/%4d:%02d:%02d:%02d +0000]" % (
             25, 'Oct', 2004, 12, 31, 59)
-        self.request.requestHeaders.addRawHeader(b'user-agent', 
+        self.request.requestHeaders.addRawHeader(b'user-agent',
                                                  b'Malicious Web" Evil')
         self.assertLogs(
             b'"1.2.3.4" - - [25/Oct/2004:12:31:59 +0000] '

Modified: branches/hide-request-transport-8191-2/twisted/web/wsgi.py
==============================================================================
--- branches/hide-request-transport-8191-2/twisted/web/wsgi.py	(original)
+++ branches/hide-request-transport-8191-2/twisted/web/wsgi.py	Wed Feb 17 15:05:43 2016
@@ -506,7 +506,7 @@
             def wsgiError(started, type, value, traceback):
                 err(Failure(value, type, traceback), "WSGI application error")
                 if started:
-                    self.request.transport.loseConnection()
+                    self.request.loseConnection()
                 else:
                     self.request.setResponseCode(INTERNAL_SERVER_ERROR)
                     self.request.finish()
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.