r47315 - some refactoring and stuff

hawkowl-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org Mon, 25 Apr 2016 02:56:38 -0600 (MDT)
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: hawkowl
Date: Mon Apr 25 02:56:25 2016
New Revision: 47315

Modified:
   branches/proper-upgrade-8301-2/twisted/web/http.py
   branches/proper-upgrade-8301-2/twisted/web/test/test_http.py

Log:
some refactoring and stuff

Modified: branches/proper-upgrade-8301-2/twisted/web/http.py
==============================================================================
--- branches/proper-upgrade-8301-2/twisted/web/http.py	(original)
+++ branches/proper-upgrade-8301-2/twisted/web/http.py	Mon Apr 25 02:56:25 2016
@@ -2175,36 +2175,53 @@
     def dataReceived(self, data):
         """
         A override of L{IProtocol.dataReceived} that checks what protocol we're
-        using.
+        using, and negotiates HTTP/1.1 Upgrade if needed.
         """
         if self._buffering:
             return self._bufferData(data)
 
         elif self._negotiatedProtocol is None:
+
             try:
+                # Does ALPN/NPN/some other transport negotiation have the
+                # protocol the client desires negotiated?
                 negotiatedProtocol = self._channel.transport.negotiatedProtocol
             except AttributeError:
-                # The transport didn't negotiate the protocol (e.g. it's
-                # plaintext non-ALPN), so we should investigate the content.
-                self._buffering = True
-                return self._bufferData(data)
+                negotiatedProtocol = None
 
             if negotiatedProtocol == b'h2':
+                # We can't handle HTTP/2 yet
                 return _respondToBadRequestAndDisconnect(
                     self._channel.transport)
+
             elif negotiatedProtocol in [b"http/1.1", None]:
-                # If it's HTTP/1.1 (which may be an upgrade) or we don't know
-                # yet, look at the request.
-                self._buffering = True
-                return self._bufferData(data)
+
+                if getattr(self.factory, "_upgradeables"):
+                    # We can upgrade to different protocols through HTTP/1.1
+                    # Upgrade, so we need to check the request to see if it
+                    # wants us to do this. We handle it here rather than in
+                    # HTTPChannel so that all the switching between protocols
+                    # is kept in one place.
+                    # In this case, a negotiatedProtocol of None means that the
+                    # transport didn't negotiate it for us, and we have to
+                    # assume HTTP/1.1 or HTTP/1.0. Hence we need to inspect
+                    # this request.
+                    self._buffering = True
+                    return self._bufferData(data)
+                else:
+                    # We can't possibly upgrade to anything (because the HTTP
+                    # factory has no extra protocols configures), so we must
+                    # just assume HTTP/1.1.
+                    negotiatedProtocol = b"http/1.1"
+
             else:
+                # A protocol which we didn't understand was negotiated by ALPN.
                 return _respondToBadRequestAndDisconnect(
                     self._channel.transport)
 
             self._negotiatedProtocol = negotiatedProtocol
 
-        else:
-            return self._channel.dataReceived(data)
+        return self._channel.dataReceived(data)
 
 
 

Modified: branches/proper-upgrade-8301-2/twisted/web/test/test_http.py
==============================================================================
--- branches/proper-upgrade-8301-2/twisted/web/test/test_http.py	(original)
+++ branches/proper-upgrade-8301-2/twisted/web/test/test_http.py	Mon Apr 25 02:56:25 2016
@@ -261,6 +261,7 @@
         negotiated protocol string.
         """
         a = http._genericHTTPChannelProtocolFactory(b'')
+        a.factory = HTTPFactory()
         a.requestFactory = DummyHTTPHandler
         a.makeConnection(t)
         # one byte at a time, to stress it.
@@ -2670,6 +2671,7 @@
         A non-HTTP request returns with a "bad request" error.
         """
         factory = self._makeFactory()
+        factory._addUpgrader(b"unused", None)
         protocol = factory.buildProtocol(None)
 
         trans = StringTransport()
@@ -2692,6 +2694,7 @@
         request" error.
         """
         factory = self._makeFactory()
+        factory._addUpgrader(b"unused", None)
         protocol = factory.buildProtocol(None)
 
         trans = StringTransport()
@@ -2717,6 +2720,29 @@
         "bad request" error.
         """
         factory = self._makeFactory()
+        factory._addUpgrader(b"unused", None)
+        protocol = factory.buildProtocol(None)
+
+        trans = StringTransport()
+        protocol.makeConnection(trans)
+
+        val = [
+            b"GET/ HTTP/1.1\r\n\r\n",
+        ]
+
+        for x in iterbytes(b"".join(val)):
+            protocol.dataReceived(x)
+
+        expectedValue = b"HTTP/1.1 400 Bad Request\r\n\r\n"
+        self.assertEqual(trans.value(), expectedValue)
+
+
+    def test_regularRequest(self):
+        """
+        A regular HTTP/1.1 request (that does not want to upgrade) will be passed right through.
+        """
+        factory = self._makeFactory()
+        factory._addUpgrader(b"unused", None)
         protocol = factory.buildProtocol(None)
 
         trans = StringTransport()