Changeset 1937
- Timestamp:
- 04/03/08 03:07:07
- Files:
-
- trunk/cherrypy/wsgiserver/__init__.py (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/wsgiserver/__init__.py
r1935 r1937 117 117 return dict.fromkeys(nums).keys() 118 118 119 socket_error_eintr = plat_specific_errors("EINTR", "WSAEINTR") 120 119 121 socket_errors_to_ignore = plat_specific_errors( 120 122 "EPIPE", 123 "EBADF", "WSAEBADF", 124 "ENOTSOCK", "WSAENOTSOCK", 121 125 "ETIMEDOUT", "WSAETIMEDOUT", 122 126 "ECONNREFUSED", "WSAECONNREFUSED", … … 692 696 class CP_fileobject(socket._fileobject): 693 697 """Faux file object attached to a socket object.""" 694 695 def recv(self, size): 696 return self._sock.recv(size) 697 698 698 699 def sendall(self, data): 699 700 """Sendall for non-blocking sockets.""" … … 705 706 if e.args[0] not in socket_errors_nonblocking: 706 707 raise 707 708 708 709 def send(self, data): 709 710 return self._sock.send(data) … … 715 716 self.sendall(buffer) 716 717 718 def recv(self, size): 719 while True: 720 try: 721 return self._sock.recv(size) 722 except socket.error, e: 723 if e.args[0] not in socket_errors_nonblocking: 724 raise 725 717 726 def read(self, size=-1): 718 data = self._rbuf719 727 if size < 0: 720 728 # Read until EOF 721 buffers = [] 722 if data: 723 buffers.append(data) 729 buffers = [self._rbuf] 724 730 self._rbuf = "" 725 731 if self._rbufsize <= 1: … … 736 742 else: 737 743 # Read until size bytes or EOF seen, whichever comes first 744 data = self._rbuf 738 745 buf_len = len(data) 739 746 if buf_len >= size: … … 846 853 try: 847 854 return call(*args, **kwargs) 848 except (SSL.WantReadError, SSL.WantWriteError):855 except SSL.WantReadError: 849 856 # Sleep and try again. This is dangerous, because it means 850 857 # the rest of the stack has no way of differentiating 851 858 # between a "new handshake" error and "client dropped". 852 859 # Note this isn't an endless loop: there's a timeout below. 860 time.sleep(self.ssl_retry) 861 except SSL.WantWriteError: 853 862 time.sleep(self.ssl_retry) 854 863 except SSL.SysCallError, e: … … 881 890 882 891 def recv(self, *args, **kwargs): 883 return self._safe_call(True, super(SSL_fileobject, self).recv, *args, **kwargs) 884 892 buf = [] 893 r = super(SSL_fileobject, self).recv 894 while True: 895 data = self._safe_call(True, r, *args, **kwargs) 896 buf.append(data) 897 p = self._sock.pending() 898 if not p: 899 return "".join(buf) 900 885 901 def sendall(self, *args, **kwargs): 886 902 return self._safe_call(False, super(SSL_fileobject, self).sendall, *args, **kwargs) … … 1406 1422 return 1407 1423 except socket.error, x: 1408 if hasattr(errno, "EINTR") and x.args[0] == errno.EINTR:1424 if x.args[0] in socket_error_eintr: 1409 1425 # I *think* this is right. EINTR should occur when a signal 1410 1426 # is received during the accept() call; all docs say retry … … 1413 1429 # elsewhere. See http://www.cherrypy.org/ticket/707. 1414 1430 return 1415 msg = x.args[1] 1416 if msg in ("Bad file descriptor", "Socket operation on non-socket"): 1417 # Our socket was closed. 1418 return 1419 if msg == "Resource temporarily unavailable": 1431 if x.args[0] in socket_errors_nonblocking: 1420 1432 # Just try again. See http://www.cherrypy.org/ticket/479. 1421 1433 return 1422 if msg == "Software caused connection abort": 1434 if x.args[0] in socket_errors_to_ignore: 1435 # Our socket was closed. 1423 1436 # See http://www.cherrypy.org/ticket/686. 1424 1437 return

