r46785 - Apply 8191_1.patch

glyph-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: glyph
Date: Sat Feb 13 17:59:12 2016
New Revision: 46785

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

Log:
Apply 8191_1.patch

Modified: branches/hide-request-transport-8191/twisted/web/http.py
==============================================================================
--- branches/hide-request-transport-8191/twisted/web/http.py	(original)
+++ branches/hide-request-transport-8191/twisted/web/http.py	Sat Feb 13 17:59:12 2016
@@ -562,6 +562,13 @@
         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)}.
     """
     producer = None
     finished = 0
@@ -580,6 +587,7 @@
     content = None
     _forceSSL = 0
     _disconnected = False
+    _queuedHeaders = None
 
     def __init__(self, channel, queued):
         """
@@ -598,7 +606,7 @@
         if queued:
             self.transport = StringTransport()
         else:
-            self.transport = self.channel.transport
+            self.transport = self.channel
 
 
     def _cleanup(self):
@@ -637,7 +645,10 @@
 
         # set transport to real one and send any buffer data
         data = self.transport.getvalue()
-        self.transport = self.channel.transport
+        self.transport = self.channel
+        if self._queuedHeaders:
+            self.transport.writeHeaders(*self._queuedHeaders)
+            self._queuedHeaders = None
         if data:
             self.transport.write(data)
 
@@ -727,8 +738,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 +766,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 +816,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,7 +881,7 @@
 
         if not self.startedWriting:
             # write headers
-            self.write('')
+            self.write(b'')
 
         if self.chunked:
             # write last chunk and closing CRLF
@@ -899,11 +910,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 +921,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 +945,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":
@@ -1828,6 +1839,94 @@
             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 _respondToBadRequestAndDisconnect(transport):
     """

Modified: branches/hide-request-transport-8191/twisted/web/test/requesthelper.py
==============================================================================
--- branches/hide-request-transport-8191/twisted/web/test/requesthelper.py	(original)
+++ branches/hide-request-transport-8191/twisted/web/test/requesthelper.py	Sat Feb 13 17:59:12 2016
@@ -52,6 +52,9 @@
         def registerProducer(self, producer, streaming):
             self.producers.append((producer, streaming))
 
+        def unregisterProducer(self):
+            pass
+
         def loseConnection(self):
             self.disconnected = True
 
@@ -70,6 +73,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/twisted/web/test/test_http.py
==============================================================================
--- branches/hide-request-transport-8191/twisted/web/test/test_http.py	(original)
+++ branches/hide-request-transport-8191/twisted/web/test/test_http.py	Sat Feb 13 17:59:12 2016
@@ -235,6 +235,7 @@
         self.assertEqual(response, expectedResponse)
 
 
+
 class HTTPLoopbackTests(unittest.TestCase):
 
     expectedHeaders = {b'request': b'/foo/bar',
@@ -1556,8 +1557,10 @@
         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
 
@@ -1578,8 +1581,10 @@
         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
 
@@ -1610,8 +1615,10 @@
         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
 
@@ -1635,8 +1642,10 @@
         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
 

Modified: branches/hide-request-transport-8191/twisted/web/test/test_proxy.py
==============================================================================
--- branches/hide-request-transport-8191/twisted/web/test/test_proxy.py	(original)
+++ branches/hide-request-transport-8191/twisted/web/test/test_proxy.py	Sat Feb 13 17:59:12 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/twisted/web/test/test_web.py
==============================================================================
--- branches/hide-request-transport-8191/twisted/web/test/test_web.py	(original)
+++ branches/hide-request-transport-8191/twisted/web/test/test_web.py	Sat Feb 13 17:59:12 2016
@@ -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 = [
             '',
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.