blob: 90a4e550093c138a7e9c3900b2d93d3b34307320 [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
Thomas Wouters89f507f2006-12-13 04:49:30 +000013 self.data = ''
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000014
Jeremy Hylton2c178252004-08-07 16:28:14 +000015 def sendall(self, data):
Thomas Wouters89f507f2006-12-13 04:49:30 +000016 self.data += data
Jeremy Hylton2c178252004-08-07 16:28:14 +000017
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000018 def makefile(self, mode, bufsize=None):
19 if mode != 'r' and mode != 'rb':
Neal Norwitz28bb5722002-04-01 19:00:50 +000020 raise httplib.UnimplementedFileMode()
Jeremy Hylton121d34a2003-07-08 12:36:58 +000021 return self.fileclass(self.text)
22
23class NoEOFStringIO(StringIO.StringIO):
24 """Like StringIO, but raises AssertionError on EOF.
25
26 This is used below to test that httplib doesn't try to read
27 more from the underlying file than it should.
28 """
29 def read(self, n=-1):
30 data = StringIO.StringIO.read(self, n)
31 if data == '':
32 raise AssertionError('caller tried to read past EOF')
33 return data
34
35 def readline(self, length=None):
36 data = StringIO.StringIO.readline(self, length)
37 if data == '':
38 raise AssertionError('caller tried to read past EOF')
39 return data
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000040
Jeremy Hylton2c178252004-08-07 16:28:14 +000041
42class HeaderTests(TestCase):
43 def test_auto_headers(self):
44 # Some headers are added automatically, but should not be added by
45 # .request() if they are explicitly set.
46
47 import httplib
48
49 class HeaderCountingBuffer(list):
50 def __init__(self):
51 self.count = {}
52 def append(self, item):
53 kv = item.split(':')
54 if len(kv) > 1:
55 # item is a 'Key: Value' header string
56 lcKey = kv[0].lower()
57 self.count.setdefault(lcKey, 0)
58 self.count[lcKey] += 1
59 list.append(self, item)
60
61 for explicit_header in True, False:
62 for header in 'Content-length', 'Host', 'Accept-encoding':
63 conn = httplib.HTTPConnection('example.com')
64 conn.sock = FakeSocket('blahblahblah')
65 conn._buffer = HeaderCountingBuffer()
66
67 body = 'spamspamspam'
68 headers = {}
69 if explicit_header:
70 headers[header] = str(len(body))
71 conn.request('POST', '/', body, headers)
72 self.assertEqual(conn._buffer.count[header.lower()], 1)
73
Thomas Wouters89f507f2006-12-13 04:49:30 +000074class BasicTest(TestCase):
75 def test_status_lines(self):
76 # Test HTTP status lines
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000077
Thomas Wouters89f507f2006-12-13 04:49:30 +000078 body = "HTTP/1.1 200 Ok\r\n\r\nText"
79 sock = FakeSocket(body)
80 resp = httplib.HTTPResponse(sock)
Jeremy Hyltonba603192003-01-23 18:02:20 +000081 resp.begin()
Thomas Wouters89f507f2006-12-13 04:49:30 +000082 self.assertEqual(resp.read(), 'Text')
83 resp.close()
Jeremy Hyltonba603192003-01-23 18:02:20 +000084
Thomas Wouters89f507f2006-12-13 04:49:30 +000085 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
86 sock = FakeSocket(body)
87 resp = httplib.HTTPResponse(sock)
88 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +000089
Thomas Wouters89f507f2006-12-13 04:49:30 +000090 def test_host_port(self):
91 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +000092
Thomas Wouters89f507f2006-12-13 04:49:30 +000093 for hp in ("www.python.org:abc", "www.python.org:"):
94 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
95
96 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
97 ("www.python.org:80", "www.python.org", 80),
98 ("www.python.org", "www.python.org", 80),
99 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Martin v. Löwis74a249e2004-09-14 21:45:36 +0000100 http = httplib.HTTP(hp)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000101 c = http._conn
102 if h != c.host: self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
103 if p != c.port: self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000104
Thomas Wouters89f507f2006-12-13 04:49:30 +0000105 def test_response_headers(self):
106 # test response with multiple message headers with the same field name.
107 text = ('HTTP/1.1 200 OK\r\n'
108 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
109 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
110 ' Path="/acme"\r\n'
111 '\r\n'
112 'No body\r\n')
113 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
114 ', '
115 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
116 s = FakeSocket(text)
117 r = httplib.HTTPResponse(s)
118 r.begin()
119 cookies = r.getheader("Set-Cookie")
120 if cookies != hdr:
121 self.fail("multiple headers not combined properly")
Jeremy Hyltonba603192003-01-23 18:02:20 +0000122
Thomas Wouters89f507f2006-12-13 04:49:30 +0000123 def test_read_head(self):
124 # Test that the library doesn't attempt to read any data
125 # from a HEAD request. (Tickles SF bug #622042.)
126 sock = FakeSocket(
127 'HTTP/1.1 200 OK\r\n'
128 'Content-Length: 14432\r\n'
129 '\r\n',
130 NoEOFStringIO)
131 resp = httplib.HTTPResponse(sock, method="HEAD")
132 resp.begin()
133 if resp.read() != "":
134 self.fail("Did not expect response from HEAD request")
135 resp.close()
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000136
Thomas Wouters89f507f2006-12-13 04:49:30 +0000137 def test_send_file(self):
138 expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
139 'Accept-Encoding: identity\r\nContent-Length:'
140
141 body = open(__file__, 'rb')
142 conn = httplib.HTTPConnection('example.com')
143 sock = FakeSocket(body)
144 conn.sock = sock
145 conn.request('GET', '/foo', body)
146 self.assertTrue(sock.data.startswith(expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000147
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000148class OfflineTest(TestCase):
149 def test_responses(self):
150 self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
151
Jeremy Hylton2c178252004-08-07 16:28:14 +0000152def test_main(verbose=None):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000153 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000154
Thomas Wouters89f507f2006-12-13 04:49:30 +0000155if __name__ == '__main__':
156 test_main()