blob: 8d9a7068332ff39f6a5ee09abd361c63d1f18592 [file] [log] [blame]
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00001import httplib
2import StringIO
Jeremy Hylton121d34a2003-07-08 12:36:58 +00003import sys
4
Jeremy Hylton2c178252004-08-07 16:28:14 +00005from unittest import TestCase
6
7from test import test_support
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00008
9class FakeSocket:
Jeremy Hylton121d34a2003-07-08 12:36:58 +000010 def __init__(self, text, fileclass=StringIO.StringIO):
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000011 self.text = text
Jeremy Hylton121d34a2003-07-08 12:36:58 +000012 self.fileclass = fileclass
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000013
Jeremy Hylton2c178252004-08-07 16:28:14 +000014 def sendall(self, data):
15 self.data = data
16
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000017 def makefile(self, mode, bufsize=None):
18 if mode != 'r' and mode != 'rb':
Neal Norwitz28bb5722002-04-01 19:00:50 +000019 raise httplib.UnimplementedFileMode()
Jeremy Hylton121d34a2003-07-08 12:36:58 +000020 return self.fileclass(self.text)
21
22class NoEOFStringIO(StringIO.StringIO):
23 """Like StringIO, but raises AssertionError on EOF.
24
25 This is used below to test that httplib doesn't try to read
26 more from the underlying file than it should.
27 """
28 def read(self, n=-1):
29 data = StringIO.StringIO.read(self, n)
30 if data == '':
31 raise AssertionError('caller tried to read past EOF')
32 return data
33
34 def readline(self, length=None):
35 data = StringIO.StringIO.readline(self, length)
36 if data == '':
37 raise AssertionError('caller tried to read past EOF')
38 return data
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000039
Jeremy Hylton2c178252004-08-07 16:28:14 +000040
41class HeaderTests(TestCase):
42 def test_auto_headers(self):
43 # Some headers are added automatically, but should not be added by
44 # .request() if they are explicitly set.
45
46 import httplib
47
48 class HeaderCountingBuffer(list):
49 def __init__(self):
50 self.count = {}
51 def append(self, item):
52 kv = item.split(':')
53 if len(kv) > 1:
54 # item is a 'Key: Value' header string
55 lcKey = kv[0].lower()
56 self.count.setdefault(lcKey, 0)
57 self.count[lcKey] += 1
58 list.append(self, item)
59
60 for explicit_header in True, False:
61 for header in 'Content-length', 'Host', 'Accept-encoding':
62 conn = httplib.HTTPConnection('example.com')
63 conn.sock = FakeSocket('blahblahblah')
64 conn._buffer = HeaderCountingBuffer()
65
66 body = 'spamspamspam'
67 headers = {}
68 if explicit_header:
69 headers[header] = str(len(body))
70 conn.request('POST', '/', body, headers)
71 self.assertEqual(conn._buffer.count[header.lower()], 1)
72
Georg Brandl71a20892006-10-29 20:24:01 +000073class BasicTest(TestCase):
74 def test_status_lines(self):
75 # Test HTTP status lines
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000076
Georg Brandl71a20892006-10-29 20:24:01 +000077 body = "HTTP/1.1 200 Ok\r\n\r\nText"
78 sock = FakeSocket(body)
79 resp = httplib.HTTPResponse(sock)
Jeremy Hyltonba603192003-01-23 18:02:20 +000080 resp.begin()
Georg Brandl71a20892006-10-29 20:24:01 +000081 self.assertEqual(resp.read(), 'Text')
82 resp.close()
Jeremy Hyltonba603192003-01-23 18:02:20 +000083
Georg Brandl71a20892006-10-29 20:24:01 +000084 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
85 sock = FakeSocket(body)
86 resp = httplib.HTTPResponse(sock)
87 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +000088
Georg Brandl71a20892006-10-29 20:24:01 +000089 def test_host_port(self):
90 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +000091
Georg Brandl71a20892006-10-29 20:24:01 +000092 for hp in ("www.python.org:abc", "www.python.org:"):
93 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
94
95 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
96 ("www.python.org:80", "www.python.org", 80),
97 ("www.python.org", "www.python.org", 80),
98 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Martin v. Löwis74a249e2004-09-14 21:45:36 +000099 http = httplib.HTTP(hp)
Georg Brandl71a20892006-10-29 20:24:01 +0000100 c = http._conn
101 if h != c.host: self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
102 if p != c.port: self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000103
Georg Brandl71a20892006-10-29 20:24:01 +0000104 def test_response_headers(self):
105 # test response with multiple message headers with the same field name.
106 text = ('HTTP/1.1 200 OK\r\n'
107 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
108 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
109 ' Path="/acme"\r\n'
110 '\r\n'
111 'No body\r\n')
112 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
113 ', '
114 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
115 s = FakeSocket(text)
116 r = httplib.HTTPResponse(s)
117 r.begin()
118 cookies = r.getheader("Set-Cookie")
119 if cookies != hdr:
120 self.fail("multiple headers not combined properly")
Jeremy Hyltonba603192003-01-23 18:02:20 +0000121
Georg Brandl71a20892006-10-29 20:24:01 +0000122 def test_read_head(self):
123 # Test that the library doesn't attempt to read any data
124 # from a HEAD request. (Tickles SF bug #622042.)
125 sock = FakeSocket(
126 'HTTP/1.1 200 OK\r\n'
127 'Content-Length: 14432\r\n'
128 '\r\n',
129 NoEOFStringIO)
130 resp = httplib.HTTPResponse(sock, method="HEAD")
131 resp.begin()
132 if resp.read() != "":
133 self.fail("Did not expect response from HEAD request")
134 resp.close()
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000135
Jeremy Hylton2c178252004-08-07 16:28:14 +0000136
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000137class OfflineTest(TestCase):
138 def test_responses(self):
139 self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
140
Jeremy Hylton2c178252004-08-07 16:28:14 +0000141def test_main(verbose=None):
Georg Brandl71a20892006-10-29 20:24:01 +0000142 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000143
Georg Brandl71a20892006-10-29 20:24:01 +0000144if __name__ == '__main__':
145 test_main()