Ticket #837: 837.2049.patch
-
cherrypy/test/test_tools.py
old new 3 3 import gzip 4 4 import StringIO 5 5 import sys 6 from httplib import IncompleteRead 6 7 import time 7 8 timeout = 0.2 8 9 … … 272 273 # Because this error is raised after the response body has 273 274 # started, and because it's chunked output, an error is raised by 274 275 # the HTTP client when it encounters incomplete output. 275 self.assertRaises(ValueError, self.getPage, 276 "/demo/errinstream?id=5") 276 if sys.version_info[:2] >= (2, 6): 277 self.assertRaises(IncompleteRead, self.getPage, 278 "/demo/errinstream?id=5") 279 else: 280 self.assertRaises(ValueError, self.getPage, 281 "/demo/errinstream?id=5") 277 282 # If this fails, then on_end_request isn't being called at all. 278 283 time.sleep(0.1) 279 284 self.getPage("/demo/ended/5") -
cherrypy/test/webtest.py
old new 491 491 # IN6ADDR_ANY, which should respond on localhost. 492 492 host = "::1" 493 493 conn = http_conn(host, port) 494 494 495 495 conn._http_vsn_str = protocol 496 496 conn._http_vsn = int("".join([x for x in protocol if x.isdigit()])) 497 497 -
cherrypy/test/test_encoding.py
old new 1 1 from cherrypy.test import test 2 2 test.prefer_parent_path() 3 3 4 import sys 4 5 import gzip, StringIO 6 from httplib import IncompleteRead 5 7 import cherrypy 6 8 europoundUnicode = u'\x80\xa3' 7 9 europoundUtf8 = u'\x80\xa3'.encode('utf-8') … … 160 162 else: 161 163 # The wsgiserver will simply stop sending data, and the HTTP client 162 164 # will error due to an incomplete chunk-encoded stream. 163 self.assertRaises(ValueError, self.getPage, '/gzip/noshow_stream', 164 headers=[("Accept-Encoding", "gzip")]) 165 if sys.version_info[:2] >= (2, 6): 166 self.assertRaises(IncompleteRead, self.getPage, '/gzip/noshow_stream', 167 headers=[("Accept-Encoding", "gzip")]) 168 else: 169 self.assertRaises(ValueError, self.getPage, '/gzip/noshow_stream', 170 headers=[("Accept-Encoding", "gzip")]) 165 171 166 167 172 if __name__ == "__main__": 168 173 setup_server() 169 174 helper.testmain() -
cherrypy/test/test_core.py
old new 7 7 localDir = os.path.dirname(__file__) 8 8 import sys 9 9 import types 10 from httplib import IncompleteRead 10 11 11 12 import cherrypy 12 13 from cherrypy import _cptools, tools … … 760 761 else: 761 762 # Under HTTP/1.1, the chunked transfer-coding is used. 762 763 # The HTTP client will choke when the output is incomplete. 763 self.assertRaises(ValueError, self.getPage, 764 "/error/page_streamed") 764 if sys.version_info[:2] >= (2, 6): 765 self.assertRaises(IncompleteRead, self.getPage, 766 "/error/page_streamed") 767 else: 768 self.assertRaises(ValueError, self.getPage, 769 "/error/page_streamed") 765 770 766 771 # No traceback should be present 767 772 self.getPage("/error/cause_err_in_finalize") -
cherrypy/wsgiserver/__init__.py
old new 713 713 """Exception raised when the SSL implementation signals a fatal alert.""" 714 714 pass 715 715 716 if sys.version_info[:2] >= (2, 6) or sys.version_info[:3] >= (2, 5, 2): 717 class CP_fileobject(socket._fileobject): 718 """Faux file object attached to a socket object.""" 716 719 717 class CP_fileobject(socket._fileobject): 718 """Faux file object attached to a socket object.""" 719 720 def sendall(self, data): 721 """Sendall for non-blocking sockets.""" 722 while data: 723 try: 724 bytes_sent = self.send(data) 725 data = data[bytes_sent:] 726 except socket.error, e: 727 if e.args[0] not in socket_errors_nonblocking: 728 raise 729 730 def send(self, data): 731 return self._sock.send(data) 732 733 def flush(self): 734 if self._wbuf: 735 buffer = "".join(self._wbuf) 736 self._wbuf = [] 737 self.sendall(buffer) 738 739 def recv(self, size): 740 while True: 741 try: 742 return self._sock.recv(size) 743 except socket.error, e: 744 if e.args[0] not in socket_errors_nonblocking: 745 raise 746 747 def read(self, size=-1): 748 if size < 0: 749 # Read until EOF 750 buffers = [self._rbuf] 751 self._rbuf = "" 752 if self._rbufsize <= 1: 753 recv_size = self.default_bufsize 720 def sendall(self, data): 721 """Sendall for non-blocking sockets.""" 722 while data: 723 try: 724 bytes_sent = self.send(data) 725 data = data[bytes_sent:] 726 except socket.error, e: 727 if e.args[0] not in socket_errors_nonblocking: 728 raise 729 730 def send(self, data): 731 return self._sock.send(data) 732 733 def flush(self): 734 if self._wbuf: 735 buffer = "".join(self._wbuf) 736 self._wbuf = [] 737 self.sendall(buffer) 738 739 def recv(self, size): 740 while True: 741 try: 742 return self._sock.recv(size) 743 except socket.error, e: 744 if e.args[0] not in socket_errors_nonblocking: 745 raise 746 747 def read(self, size=-1): 748 # Use max, disallow tiny reads in a loop as they are very inefficient. 749 # We never leave read() with any leftover data from a new recv() call 750 # in our internal buffer. 751 rbufsize = max(self._rbufsize, self.default_bufsize) 752 # Our use of StringIO rather than lists of string objects returned by 753 # recv() minimizes memory usage and fragmentation that occurs when 754 # rbufsize is large compared to the typical return value of recv(). 755 buf = self._rbuf 756 buf.seek(0, 2) # seek end 757 if size < 0: 758 # Read until EOF 759 self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. 760 while True: 761 data = self.recv(rbufsize) 762 if not data: 763 break 764 buf.write(data) 765 return buf.getvalue() 754 766 else: 755 recv_size = self._rbufsize 756 767 # Read until size bytes or EOF seen, whichever comes first 768 buf_len = buf.tell() 769 if buf_len >= size: 770 # Already have size bytes in our buffer? Extract and return. 771 buf.seek(0) 772 rv = buf.read(size) 773 self._rbuf = StringIO.StringIO() 774 self._rbuf.write(buf.read()) 775 return rv 776 777 self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. 778 while True: 779 left = size - buf_len 780 # recv() will malloc the amount of memory given as its 781 # parameter even though it often returns much less data 782 # than that. The returned data string is short lived 783 # as we copy it into a StringIO and free it. This avoids 784 # fragmentation issues on many platforms. 785 data = self.recv(left) 786 if not data: 787 break 788 n = len(data) 789 if n == size and not buf_len: 790 # Shortcut. Avoid buffer data copies when: 791 # - We have no data in our buffer. 792 # AND 793 # - Our call to recv returned exactly the 794 # number of bytes we were asked to read. 795 return data 796 if n == left: 797 buf.write(data) 798 del data # explicit free 799 break 800 assert n <= left, "recv(%d) returned %d bytes" % (left, n) 801 buf.write(data) 802 buf_len += n 803 del data # explicit free 804 #assert buf_len == buf.tell() 805 return buf.getvalue() 806 807 def readline(self, size=-1): 808 buf = self._rbuf 809 buf.seek(0, 2) # seek end 810 if buf.tell() > 0: 811 # check if we already have it in our buffer 812 buf.seek(0) 813 bline = buf.readline(size) 814 if bline.endswith('\n') or len(bline) == size: 815 self._rbuf = StringIO.StringIO() 816 self._rbuf.write(buf.read()) 817 return bline 818 del bline 819 if size < 0: 820 # Read until \n or EOF, whichever comes first 821 if self._rbufsize <= 1: 822 # Speed up unbuffered case 823 buf.seek(0) 824 buffers = [buf.read()] 825 self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. 826 data = None 827 recv = self.recv 828 while data != "\n": 829 data = recv(1) 830 if not data: 831 break 832 buffers.append(data) 833 return "".join(buffers) 834 835 buf.seek(0, 2) # seek end 836 self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. 837 while True: 838 data = self.recv(self._rbufsize) 839 if not data: 840 break 841 nl = data.find('\n') 842 if nl >= 0: 843 nl += 1 844 buf.write(data[:nl]) 845 self._rbuf.write(data[nl:]) 846 del data 847 break 848 buf.write(data) 849 return buf.getvalue() 850 else: 851 # Read until size bytes or \n or EOF seen, whichever comes first 852 buf.seek(0, 2) # seek end 853 buf_len = buf.tell() 854 if buf_len >= size: 855 buf.seek(0) 856 rv = buf.read(size) 857 self._rbuf = StringIO.StringIO() 858 self._rbuf.write(buf.read()) 859 return rv 860 self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. 861 while True: 862 data = self.recv(self._rbufsize) 863 if not data: 864 break 865 left = size - buf_len 866 # did we just receive a newline? 867 nl = data.find('\n', 0, left) 868 if nl >= 0: 869 nl += 1 870 # save the excess data to _rbuf 871 self._rbuf.write(data[nl:]) 872 if buf_len: 873 buf.write(data[:nl]) 874 break 875 else: 876 # Shortcut. Avoid data copy through buf when returning 877 # a substring of our first recv(). 878 return data[:nl] 879 n = len(data) 880 if n == size and not buf_len: 881 # Shortcut. Avoid data copy through buf when 882 # returning exactly all of our first recv(). 883 return data 884 if n >= left: 885 buf.write(data[:left]) 886 self._rbuf.write(data[left:]) 887 break 888 buf.write(data) 889 buf_len += n 890 #assert buf_len == buf.tell() 891 return buf.getvalue() 892 893 else: 894 class CP_fileobject(socket._fileobject): 895 """Faux file object attached to a socket object.""" 896 897 def sendall(self, data): 898 """Sendall for non-blocking sockets.""" 899 while data: 900 try: 901 bytes_sent = self.send(data) 902 data = data[bytes_sent:] 903 except socket.error, e: 904 if e.args[0] not in socket_errors_nonblocking: 905 raise 906 907 def send(self, data): 908 return self._sock.send(data) 909 910 def flush(self): 911 if self._wbuf: 912 buffer = "".join(self._wbuf) 913 self._wbuf = [] 914 self.sendall(buffer) 915 916 def recv(self, size): 757 917 while True: 758 data = self.recv(recv_size) 759 if not data: 760 break 761 buffers.append(data) 762 return "".join(buffers) 763 else: 764 # Read until size bytes or EOF seen, whichever comes first 765 data = self._rbuf 766 buf_len = len(data) 767 if buf_len >= size: 768 self._rbuf = data[size:] 769 return data[:size] 770 buffers = [] 771 if data: 772 buffers.append(data) 773 self._rbuf = "" 774 while True: 775 left = size - buf_len 776 recv_size = max(self._rbufsize, left) 777 data = self.recv(recv_size) 778 if not data: 779 break 780 buffers.append(data) 781 n = len(data) 782 if n >= left: 783 self._rbuf = data[left:] 784 buffers[-1] = data[:left] 785 break 786 buf_len += n 787 return "".join(buffers) 918 try: 919 return self._sock.recv(size) 920 except socket.error, e: 921 if e.args[0] not in socket_errors_nonblocking: 922 raise 788 923 789 def readline(self, size=-1): 790 data = self._rbuf 791 if size < 0: 792 # Read until \n or EOF, whichever comes first 793 if self._rbufsize <= 1: 794 # Speed up unbuffered case 795 assert data == "" 924 def read(self, size=-1): 925 if size < 0: 926 # Read until EOF 927 buffers = [self._rbuf] 928 self._rbuf = "" 929 if self._rbufsize <= 1: 930 recv_size = self.default_bufsize 931 else: 932 recv_size = self._rbufsize 933 934 while True: 935 data = self.recv(recv_size) 936 if not data: 937 break 938 buffers.append(data) 939 return "".join(buffers) 940 else: 941 # Read until size bytes or EOF seen, whichever comes first 942 data = self._rbuf 943 buf_len = len(data) 944 if buf_len >= size: 945 self._rbuf = data[size:] 946 return data[:size] 796 947 buffers = [] 797 while data != "\n": 798 data = self.recv(1) 948 if data: 949 buffers.append(data) 950 self._rbuf = "" 951 while True: 952 left = size - buf_len 953 recv_size = max(self._rbufsize, left) 954 data = self.recv(recv_size) 799 955 if not data: 800 956 break 801 957 buffers.append(data) 958 n = len(data) 959 if n >= left: 960 self._rbuf = data[left:] 961 buffers[-1] = data[:left] 962 break 963 buf_len += n 802 964 return "".join(buffers) 803 nl = data.find('\n') 804 if nl >= 0: 805 nl += 1 806 self._rbuf = data[nl:] 807 return data[:nl] 808 buffers = [] 809 if data: 810 buffers.append(data) 811 self._rbuf = "" 812 while True: 813 data = self.recv(self._rbufsize) 814 if not data: 815 break 816 buffers.append(data) 965 966 def readline(self, size=-1): 967 data = self._rbuf 968 if size < 0: 969 # Read until \n or EOF, whichever comes first 970 if self._rbufsize <= 1: 971 # Speed up unbuffered case 972 assert data == "" 973 buffers = [] 974 while data != "\n": 975 data = self.recv(1) 976 if not data: 977 break 978 buffers.append(data) 979 return "".join(buffers) 817 980 nl = data.find('\n') 818 981 if nl >= 0: 819 982 nl += 1 820 983 self._rbuf = data[nl:] 821 buffers[-1] = data[:nl] 822 break 823 return "".join(buffers) 824 else: 825 # Read until size bytes or \n or EOF seen, whichever comes first 826 nl = data.find('\n', 0, size) 827 if nl >= 0: 828 nl += 1 829 self._rbuf = data[nl:] 830 return data[:nl] 831 buf_len = len(data) 832 if buf_len >= size: 833 self._rbuf = data[size:] 834 return data[:size] 835 buffers = [] 836 if data: 837 buffers.append(data) 838 self._rbuf = "" 839 while True: 840 data = self.recv(self._rbufsize) 841 if not data: 842 break 843 buffers.append(data) 844 left = size - buf_len 845 nl = data.find('\n', 0, left) 984 return data[:nl] 985 buffers = [] 986 if data: 987 buffers.append(data) 988 self._rbuf = "" 989 while True: 990 data = self.recv(self._rbufsize) 991 if not data: 992 break 993 buffers.append(data) 994 nl = data.find('\n') 995 if nl >= 0: 996 nl += 1 997 self._rbuf = data[nl:] 998 buffers[-1] = data[:nl] 999 break 1000 return "".join(buffers) 1001 else: 1002 # Read until size bytes or \n or EOF seen, whichever comes first 1003 nl = data.find('\n', 0, size) 846 1004 if nl >= 0: 847 1005 nl += 1 848 1006 self._rbuf = data[nl:] 849 buffers[-1] = data[:nl] 850 break 851 n = len(data) 852 if n >= left: 853 self._rbuf = data[left:] 854 buffers[-1] = data[:left] 855 break 856 buf_len += n 857 return "".join(buffers) 1007 return data[:nl] 1008 buf_len = len(data) 1009 if buf_len >= size: 1010 self._rbuf = data[size:] 1011 return data[:size] 1012 buffers = [] 1013 if data: 1014 buffers.append(data) 1015 self._rbuf = "" 1016 while True: 1017 data = self.recv(self._rbufsize) 1018 if not data: 1019 break 1020 buffers.append(data) 1021 left = size - buf_len 1022 nl = data.find('\n', 0, left) 1023 if nl >= 0: 1024 nl += 1 1025 self._rbuf = data[nl:] 1026 buffers[-1] = data[:nl] 1027 break 1028 n = len(data) 1029 if n >= left: 1030 self._rbuf = data[left:] 1031 buffers[-1] = data[:left] 1032 break 1033 buf_len += n 1034 return "".join(buffers) 858 1035 859 1036 860 1037 class SSL_fileobject(CP_fileobject):

