0001 import httplib 0002 import StringIO 0003 import sys 0004 0005 from unittest import TestCase 0006 0007 from test import test_support 0008 0009 class FakeSocket: 0010 def __init__(self, text, fileclass=StringIO.StringIO): 0011 self.text = text 0012 self.fileclass = fileclass 0013 0014 def sendall(self, data): 0015 self.data = data 0016 0017 def makefile(self, mode, bufsize=None): 0018 if mode != 'r' and mode != 'rb': 0019 raise httplib.UnimplementedFileMode() 0020 return self.fileclass(self.text) 0021 0022 class NoEOFStringIO(StringIO.StringIO): 0023 """Like StringIO, but raises AssertionError on EOF. 0024 0025 This is used below to test that httplib doesn't try to read 0026 more from the underlying file than it should. 0027 """ 0028 def read(self, n=-1): 0029 data = StringIO.StringIO.read(self, n) 0030 if data == '': 0031 raise AssertionError('caller tried to read past EOF') 0032 return data 0033 0034 def readline(self, length=None): 0035 data = StringIO.StringIO.readline(self, length) 0036 if data == '': 0037 raise AssertionError('caller tried to read past EOF') 0038 return data 0039 0040 0041 class HeaderTests(TestCase): 0042 def test_auto_headers(self): 0043 # Some headers are added automatically, but should not be added by 0044 # .request() if they are explicitly set. 0045 0046 import httplib 0047 0048 class HeaderCountingBuffer(list): 0049 def __init__(self): 0050 self.count = {} 0051 def append(self, item): 0052 kv = item.split(':') 0053 if len(kv) > 1: 0054 # item is a 'Key: Value' header string 0055 lcKey = kv[0].lower() 0056 self.count.setdefault(lcKey, 0) 0057 self.count[lcKey] += 1 0058 list.append(self, item) 0059 0060 for explicit_header in True, False: 0061 for header in 'Content-length', 'Host', 'Accept-encoding': 0062 conn = httplib.HTTPConnection('example.com') 0063 conn.sock = FakeSocket('blahblahblah') 0064 conn._buffer = HeaderCountingBuffer() 0065 0066 body = 'spamspamspam' 0067 headers = {} 0068 if explicit_header: 0069 headers[header] = str(len(body)) 0070 conn.request('POST', '/', body, headers) 0071 self.assertEqual(conn._buffer.count[header.lower()], 1) 0072 0073 # Collect output to a buffer so that we don't have to cope with line-ending 0074 # issues across platforms. Specifically, the headers will have \r\n pairs 0075 # and some platforms will strip them from the output file. 0076 0077 def test(): 0078 buf = StringIO.StringIO() 0079 _stdout = sys.stdout 0080 try: 0081 sys.stdout = buf 0082 _test() 0083 finally: 0084 sys.stdout = _stdout 0085 0086 # print individual lines with endings stripped 0087 s = buf.getvalue() 0088 for line in s.split("\n"): 0089 print line.strip() 0090 0091 def _test(): 0092 # Test HTTP status lines 0093 0094 body = "HTTP/1.1 200 Ok\r\n\r\nText" 0095 sock = FakeSocket(body) 0096 resp = httplib.HTTPResponse(sock, 1) 0097 resp.begin() 0098 print resp.read() 0099 resp.close() 0100 0101 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText" 0102 sock = FakeSocket(body) 0103 resp = httplib.HTTPResponse(sock, 1) 0104 try: 0105 resp.begin() 0106 except httplib.BadStatusLine: 0107 print "BadStatusLine raised as expected" 0108 else: 0109 print "Expect BadStatusLine" 0110 0111 # Check invalid host_port 0112 0113 for hp in ("www.python.org:abc", "www.python.org:"): 0114 try: 0115 h = httplib.HTTP(hp) 0116 except httplib.InvalidURL: 0117 print "InvalidURL raised as expected" 0118 else: 0119 print "Expect InvalidURL" 0120 0121 for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000), 0122 ("www.python.org:80", "www.python.org", 80), 0123 ("www.python.org", "www.python.org", 80), 0124 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)): 0125 try: 0126 http = httplib.HTTP(hp) 0127 except httplib.InvalidURL: 0128 print "InvalidURL raised erroneously" 0129 c = http._conn 0130 if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host) 0131 if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host) 0132 0133 # test response with multiple message headers with the same field name. 0134 text = ('HTTP/1.1 200 OK\r\n' 0135 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n' 0136 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";' 0137 ' Path="/acme"\r\n' 0138 '\r\n' 0139 'No body\r\n') 0140 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"' 0141 ', ' 0142 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"') 0143 s = FakeSocket(text) 0144 r = httplib.HTTPResponse(s, 1) 0145 r.begin() 0146 cookies = r.getheader("Set-Cookie") 0147 if cookies != hdr: 0148 raise AssertionError, "multiple headers not combined properly" 0149 0150 # Test that the library doesn't attempt to read any data 0151 # from a HEAD request. (Tickles SF bug #622042.) 0152 sock = FakeSocket( 0153 'HTTP/1.1 200 OK\r\n' 0154 'Content-Length: 14432\r\n' 0155 '\r\n', 0156 NoEOFStringIO) 0157 resp = httplib.HTTPResponse(sock, 1, method="HEAD") 0158 resp.begin() 0159 if resp.read() != "": 0160 raise AssertionError, "Did not expect response from HEAD request" 0161 resp.close() 0162 0163 0164 def test_main(verbose=None): 0165 tests = [HeaderTests,] 0166 test_support.run_unittest(*tests) 0167 0168 test() 0169
Generated by PyXR 0.9.4