All pastes #950497 Raw Edit

Stuff

public text v1 · immutable
·published 2008-03-20 16:58 UTC
rendered paste body
=== modified file 'twisted/web2/channel/http.py'
--- twisted/web2/channel/http.py	2007-01-01 23:41:33 +0000
+++ twisted/web2/channel/http.py	2008-03-20 16:58:30 +0000
@@ -10,7 +10,7 @@
 from twisted.web2 import http_headers
 from twisted.web2 import http
 
-PERSIST_NO_PIPELINE, PERSIST_PIPELINE = (1,2)
+PERSIST_NO_PIPELINE, PERSIST_PIPELINE = (False, True)
 
 _cachedHostNames = {}
 def _cachedGetHostByAddr(hostaddr):
@@ -55,7 +55,7 @@
     inHeaders = None
     partialHeader = ''
     connHeaders = None
-    finishedReading = False
+    finishedReading = True
 
     channel = None
 
@@ -371,6 +371,7 @@
 
 
     def gotInitialLine(self, initialLine):
+        self.finishedReading = False
         parts = initialLine.split()
         
         # Parse the initial request line

=== modified file 'twisted/web2/client/http.py'
--- twisted/web2/client/http.py	2007-10-19 08:16:52 +0000
+++ twisted/web2/client/http.py	2008-03-20 15:56:06 +0000
@@ -9,6 +9,7 @@
 from zope.interface import implements
 
 from twisted.internet.defer import Deferred
+from twisted.internet import error
 from twisted.protocols.basic import LineReceiver
 from twisted.protocols.policies import TimeoutMixin
 
@@ -168,6 +169,7 @@
         self._error(reason)
 
     def gotInitialLine(self, initialLine):
+        self.finishedReading = False
         parts = initialLine.split(' ', 2)
 
         # Parse the initial request line
@@ -350,7 +352,7 @@
         if not persist:
             # Tell all requests but first to abort.
             for request in self.inRequests[1:]:
-                request.connectionLost(None)
+                request.connectionLost(error.ConnectionDone())
             del self.inRequests[1:]
 
     def connectionLost(self, reason):

=== modified file 'twisted/web2/test/test_client.py'
--- twisted/web2/test/test_client.py	2007-10-19 08:16:52 +0000
+++ twisted/web2/test/test_client.py	2008-03-20 16:53:23 +0000
@@ -5,7 +5,7 @@
 Tests for HTTP client.
 """
 
-from twisted.internet import protocol, defer
+from twisted.internet import protocol, defer, error
 
 from twisted.web2.client import http
 from twisted.web2 import http_headers
@@ -61,8 +61,10 @@
     def assertReceived(self, cxn, expectedStatus, expectedHeaders,
                        expectedContent=None):
         self.iterate(cxn)
-
-        headers, content = cxn.server.data.split('\r\n\r\n', 1)
+    
+        data = cxn.server.data
+        cxn.server.data = ''
+        headers, content = data.split('\r\n\r\n', 1)
         status, headers = headers.split('\r\n', 1)
         headers = headers.split('\r\n')
 
@@ -188,6 +190,54 @@
 
         return d
 
+    def test_abortPipelining(self):
+        """
+        Ensure that pending requests are aborted if the server closes the
+        connection.
+        """
+
+        cxn = self.connect(inputTimeOut=None)
+        deferreds = []
+        
+        req1 = http.ClientRequest('GET', '/', None, None)
+        d1 = cxn.client.submitRequest(req1, closeAfter=False).addCallback(
+            self.checkResponse, 200, [], 0, None)
+        deferreds.append(d1)
+
+        self.assertReceived(cxn, 'GET / HTTP/1.1',
+                            ['Connection: Keep-Alive'])
+
+        self.writeLines(cxn, ('HTTP/1.1 200 OK',
+                              'Content-Length: 0',
+                              'Connection: Keep-Alive',
+                              '\r\n'))
+        
+        # pipeline two requests, after the first one the server closes the
+        # connection
+        req2 = http.ClientRequest('GET', '/', None, None)
+        d2 = cxn.client.submitRequest(req2, closeAfter=False).addCallback(
+            self.checkResponse, 200, [], 0, None)
+        deferreds.append(d2)
+        
+        self.assertReceived(cxn, 'GET / HTTP/1.1',
+                            ['Connection: Keep-Alive'])
+
+        req3 = http.ClientRequest('GET', '/', None, None)
+        d3 = cxn.client.submitRequest(req3, closeAfter=False)
+        self.failUnlessFailure(d3, error.ConnectionDone)
+        deferreds.append(d3)
+
+        self.assertReceived(cxn, 'GET / HTTP/1.1',
+                            ['Connection: Keep-Alive'])
+       
+        # close the connection, the client should cancel req3
+        self.writeLines(cxn, ('HTTP/1.1 200 OK',
+                              'Content-Length: 0',
+                              'Connection: close',
+                              '\r\n'))
+
+        return defer.DeferredList(deferreds)
+
     def test_userHeaders(self):
         """
         Make sure that headers get through in both directions.