extras-buildsys/common SSLConnection.py,1.5,1.6
Daniel Williams (dcbw)
fedora-extras-commits at redhat.com
Sun Jan 22 05:59:19 UTC 2006
Author: dcbw
Update of /cvs/fedora/extras-buildsys/common
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv29310/common
Modified Files:
SSLConnection.py
Log Message:
2006-01-22 Dan Williams <dcbw at redhat.com>
* common/SSLConnection.py
- Be smarter about SSL stuff by using pending() where possible in a
vain effort not to hang as much. Cribbed from rhn code by
misa at redhat
Index: SSLConnection.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/SSLConnection.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- SSLConnection.py 25 Nov 2005 04:45:07 -0000 1.5
+++ SSLConnection.py 22 Jan 2006 05:59:12 -0000 1.6
@@ -29,6 +29,12 @@
self.__dict__["close_refcount"] = 0
self.__dict__["closed"] = False
self.__dict__["timeout"] = self.DEFAULT_TIMEOUT
+
+ # Buffer stuff
+ self.__dict__["buffer_size"] = 16384
+ self.__dict__["pos"] = 0
+ self.__dict__["buffer"] = ""
+
def __del__(self):
self.__dict__["conn"].close()
def __getattr__(self,name):
@@ -76,57 +82,76 @@
self.shutdown()
self.__dict__["conn"].close()
self.__dict__["closed"] = True
- def sendall(self, data, flags=0):
- while True:
- # Use select() to simulate a socket timeout without setting the socket
- # to non-blocking mode
- (read, write, error) = select.select([], [self.__dict__["conn"]], [], self.__dict__["timeout"])
- if self.__dict__["conn"] in write:
- starttime = time.time()
- while True:
- try:
- return self.__dict__["conn"].sendall(data, flags)
- except SSL.SysCallError, e:
- if e[0] == 32: # Broken Pipe
- self.close()
- else:
- raise socket.error(e)
- except SSL.WantWriteError:
- time.sleep(0.1)
-
- curtime = time.time()
- if curtime - starttime > self.__dict__["timeout"]:
- raise socket.timeout
- else:
- raise socket.timeout
- if self.__dict__["conn"] in error:
- raise socket.error
- return None
- def recv(self, bufsize, flags=0):
+
+ def write(self, data, flags=0):
+ origlen = len(data)
+ sent = 0
while True:
- # Use select() to simulate a socket timeout without setting the socket
- # to non-blocking mode
- (read, write, error) = select.select([self.__dict__["conn"]], [], [], self.__dict__["timeout"])
- if self.__dict__["conn"] in read:
- starttime = time.time()
- while True:
- try:
- return self.__dict__["conn"].recv(bufsize, flags)
- except SSL.ZeroReturnError:
- return None
- except SSL.WantReadError:
- time.sleep(0.1)
-
- curtime = time.time()
- if curtime - starttime > self.__dict__["timeout"]:
- raise socket.timeout
- else:
- raise socket.timeout
- if self.__dict__["conn"] in error:
- raise socket.error
- return None
+ try:
+ sent = self.__dict__["conn"].send(data)
+ except (SSL.WantReadError, SSL.WantWriteError):
+ continue
+ if sent == len(data):
+ break
+ data = data[sent:]
+
+ return origlen
+
+ def recv(self, amt):
+ return self.read(amt)
+
+ send = write
+
+ sendall = write
+
+ def tell(self):
+ return self.__dict__["pos"]
+
+ def seek(self, pos, mode=0):
+ raise NotImplementedError, "seek"
+
+ def read(self, amt, flags=0):
+ # Initially, the buffer size is the default buffer size.
+ # Unfortunately, pending() does not return meaningful data until
+ # recv() is called, so we only adjust the buffer size after the
+ # first read
+ buffer_size = self.__dict__["buffer_size"]
+ # Read only the specified amount of data
+ while amt is None or len(self.__dict__["buffer"]) < amt:
+ # if amt is None (read till the end), fills in self.__dict__["buffer"]
+ if amt is not None:
+ buffer_size = min(amt - len(self.__dict__["buffer"]), buffer_size)
+
+ try:
+ data = self.__dict__["conn"].recv(buffer_size)
+ except SSL.ZeroReturnError:
+ # Nothing more to be read
+ break
+ except (SSL.WantReadError, SSL.WantWriteError):
+ # Try again
+ continue
+
+ self.__dict__["buffer"] = self.__dict__["buffer"] + data
+
+ # More bytes to read?
+ pending = self.__dict__["conn"].pending()
+ if pending == 0:
+ # we're done here
+ break
+
+ if amt:
+ ret = self.__dict__["buffer"][:amt]
+ self.__dict__["buffer"] = self.__dict__["buffer"][amt:]
+ else:
+ ret = self.__dict__["buffer"]
+ self.__dict__["buffer"] = ""
+
+ self.__dict__["pos"] = self.__dict__["pos"] + len(ret)
+ return ret
class PlgFileObject(socket._fileobject):
+ def read(self, bufsize, flags=0):
+ return self._sock.read(bufsize, flags)
def close(self):
"""
socket._fileobject doesn't actually _close_ the socket,
More information about the fedora-extras-commits
mailing list