[Python-checkins] r68532 - in python/trunk/Lib: httplib.py test/test_xmlrpc.py urllib2.py xmlrpclib.py

kristjan.jonsson python-checkins at python.org
Sun Jan 11 17:23:37 CET 2009


Author: kristjan.jonsson
Date: Sun Jan 11 17:23:37 2009
New Revision: 68532

Log:
Issue 4879: Allow buffering for HTTPResponse

Modified:
   python/trunk/Lib/httplib.py
   python/trunk/Lib/test/test_xmlrpc.py
   python/trunk/Lib/urllib2.py
   python/trunk/Lib/xmlrpclib.py

Modified: python/trunk/Lib/httplib.py
==============================================================================
--- python/trunk/Lib/httplib.py	(original)
+++ python/trunk/Lib/httplib.py	Sun Jan 11 17:23:37 2009
@@ -325,13 +325,18 @@
 
     # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
 
-    def __init__(self, sock, debuglevel=0, strict=0, method=None):
-        # The buffer size is specified as zero, because the headers of
-        # the response are read with readline().  If the reads were
-        # buffered the readline() calls could consume some of the
-        # response, which make be read via a recv() on the underlying
-        # socket.
-        self.fp = sock.makefile('rb', 0)
+    def __init__(self, sock, debuglevel=0, strict=0, method=None, buffering=False):
+        if buffering:
+            # The caller won't be using any sock.recv() calls, so buffering
+            # is fine and recommendef for performance
+            self.fp = sock.makefile('rb')
+        else:
+            # The buffer size is specified as zero, because the headers of
+            # the response are read with readline().  If the reads were
+            # buffered the readline() calls could consume some of the
+            # response, which make be read via a recv() on the underlying
+            # socket.
+            self.fp = sock.makefile('rb', 0)
         self.debuglevel = debuglevel
         self.strict = strict
         self._method = method
@@ -935,7 +940,7 @@
             self.putheader(hdr, value)
         self.endheaders(body)
 
-    def getresponse(self):
+    def getresponse(self, buffering=False):
         "Get the response from the server."
 
         # if a prior response has been completed, then forget about it.
@@ -961,13 +966,15 @@
         if self.__state != _CS_REQ_SENT or self.__response:
             raise ResponseNotReady()
 
+        args = (self.sock,)
+        kwds = {"strict":self.strict, "method":self._method}
         if self.debuglevel > 0:
-            response = self.response_class(self.sock, self.debuglevel,
-                                           strict=self.strict,
-                                           method=self._method)
-        else:
-            response = self.response_class(self.sock, strict=self.strict,
-                                           method=self._method)
+            args += (self.debuglevel,)
+        if buffering:
+            #only add this keyword if non-default, for compatibility with
+            #other response_classes.
+            kwds["buffering"] = True;
+        response = self.response_class(*args, **kwds)
 
         response.begin()
         assert response.will_close != _UNKNOWN
@@ -1031,7 +1038,7 @@
         "Provide a getfile, since the superclass' does not use this concept."
         return self.file
 
-    def getreply(self):
+    def getreply(self, buffering=False):
         """Compat definition since superclass does not define it.
 
         Returns a tuple consisting of:
@@ -1040,7 +1047,12 @@
         - any RFC822 headers in the response from the server
         """
         try:
-            response = self._conn.getresponse()
+            if not buffering:
+                response = self._conn.getresponse()
+            else:
+                #only add this keyword if non-default for compatibility
+                #with other connection classes
+                response = self._conn.getresponse(buffering)
         except BadStatusLine, e:
             ### hmm. if getresponse() ever closes the socket on a bad request,
             ### then we are going to have problems with self.sock

Modified: python/trunk/Lib/test/test_xmlrpc.py
==============================================================================
--- python/trunk/Lib/test/test_xmlrpc.py	(original)
+++ python/trunk/Lib/test/test_xmlrpc.py	Sun Jan 11 17:23:37 2009
@@ -655,7 +655,7 @@
     def getvalue(self):
         return self.data.getvalue()
 
-    def makefile(self, x, y):
+    def makefile(self, x='r', y=-1):
         raise RuntimeError
 
 class FakeTransport(xmlrpclib.Transport):

Modified: python/trunk/Lib/urllib2.py
==============================================================================
--- python/trunk/Lib/urllib2.py	(original)
+++ python/trunk/Lib/urllib2.py	Sun Jan 11 17:23:37 2009
@@ -1100,7 +1100,10 @@
             (name.title(), val) for name, val in headers.items())
         try:
             h.request(req.get_method(), req.get_selector(), req.data, headers)
-            r = h.getresponse()
+            try:
+                r = h.getresponse(buffering=True)
+            except TypeError: #buffering kw not supported
+                r = h.getresponse()
         except socket.error, err: # XXX what error?
             raise URLError(err)
 

Modified: python/trunk/Lib/xmlrpclib.py
==============================================================================
--- python/trunk/Lib/xmlrpclib.py	(original)
+++ python/trunk/Lib/xmlrpclib.py	Sun Jan 11 17:23:37 2009
@@ -1234,7 +1234,7 @@
         self.send_user_agent(h)
         self.send_content(h, request_body)
 
-        errcode, errmsg, headers = h.getreply()
+        errcode, errmsg, headers = h.getreply(buffering=True)
 
         if errcode != 200:
             raise ProtocolError(
@@ -1245,12 +1245,7 @@
 
         self.verbose = verbose
 
-        try:
-            sock = h._conn.sock
-        except AttributeError:
-            sock = None
-
-        return self._parse_response(h.getfile(), sock)
+        return self._parse_response(h.getfile())
 
     ##
     # Create parser.
@@ -1355,29 +1350,12 @@
     # @return Response tuple and target method.
 
     def parse_response(self, file):
-        # compatibility interface
-        return self._parse_response(file, None)
-
-    ##
-    # Parse response (alternate interface).  This is similar to the
-    # parse_response method, but also provides direct access to the
-    # underlying socket object (where available).
-    #
-    # @param file Stream.
-    # @param sock Socket handle (or None, if the socket object
-    #    could not be accessed).
-    # @return Response tuple and target method.
-
-    def _parse_response(self, file, sock):
         # read response from input file/socket, and parse it
 
         p, u = self.getparser()
 
         while 1:
-            if sock:
-                response = sock.recv(1024)
-            else:
-                response = file.read(1024)
+            response = file.read(1024)
             if not response:
                 break
             if self.verbose:


More information about the Python-checkins mailing list