diff mercurial/httpconnection.py @ 15152:94b200a11cf7 stable

http: handle push of bundles > 2 GB again (issue3017) It was very elegant that httpsendfile implemented __len__ like a string. It was however also dangerous because that protocol can't handle sizes bigger than 2 GB. Mercurial tried to work around that, but it turned out to be too easy to introduce new errors in this area. With this change __len__ is no longer implemented at all and the code will work the same way for short and long posts.
author Mads Kiilerich <mads@kiilerich.com>
date Wed, 21 Sep 2011 22:52:00 +0200
parents 0593e8f81c71
children b3083042bdda
line wrap: on
line diff
--- a/mercurial/httpconnection.py	Tue Sep 13 17:01:07 2011 -0500
+++ b/mercurial/httpconnection.py	Wed Sep 21 22:52:00 2011 +0200
@@ -22,8 +22,9 @@
 class httpsendfile(object):
     """This is a wrapper around the objects returned by python's "open".
 
-    Its purpose is to send file-like objects via HTTP and, to do so, it
-    defines a __len__ attribute to feed the Content-Length header.
+    Its purpose is to send file-like objects via HTTP.
+    It do however not define a __len__ attribute because the length
+    might be more than Py_ssize_t can handle.
     """
 
     def __init__(self, ui, *args, **kwargs):
@@ -35,9 +36,9 @@
         self.seek = self._data.seek
         self.close = self._data.close
         self.write = self._data.write
-        self._len = os.fstat(self._data.fileno()).st_size
+        self.length = os.fstat(self._data.fileno()).st_size
         self._pos = 0
-        self._total = self._len / 1024 * 2
+        self._total = self.length / 1024 * 2
 
     def read(self, *args, **kwargs):
         try:
@@ -54,9 +55,6 @@
                          unit=_('kb'), total=self._total)
         return ret
 
-    def __len__(self):
-        return self._len
-
 # moved here from url.py to avoid a cycle
 def readauthforuri(ui, uri, user):
     # Read configuration