blob: 099f803638bc2aa086a0dfad28f5d1400c92b564 [file] [log] [blame]
Georg Brandl24420152008-05-26 16:32:26 +00001import http.client as httplib
Jeremy Hylton8fff7922007-08-03 20:56:14 +00002import io
Guido van Rossumd8faa362007-04-27 19:54:29 +00003import socket
Jeremy Hylton121d34a2003-07-08 12:36:58 +00004
Jeremy Hylton2c178252004-08-07 16:28:14 +00005from unittest import TestCase
6
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00008
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009HOST = support.HOST
Christian Heimes5e696852008-04-09 08:37:03 +000010
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000011class FakeSocket:
Jeremy Hylton8fff7922007-08-03 20:56:14 +000012 def __init__(self, text, fileclass=io.BytesIO):
13 if isinstance(text, str):
Guido van Rossum39478e82007-08-27 17:23:59 +000014 text = text.encode("ascii")
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000015 self.text = text
Jeremy Hylton121d34a2003-07-08 12:36:58 +000016 self.fileclass = fileclass
Martin v. Löwisdd5a8602007-06-30 09:22:09 +000017 self.data = b''
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000018
Jeremy Hylton2c178252004-08-07 16:28:14 +000019 def sendall(self, data):
Thomas Wouters89f507f2006-12-13 04:49:30 +000020 self.data += data
Jeremy Hylton2c178252004-08-07 16:28:14 +000021
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000022 def makefile(self, mode, bufsize=None):
23 if mode != 'r' and mode != 'rb':
Neal Norwitz28bb5722002-04-01 19:00:50 +000024 raise httplib.UnimplementedFileMode()
Jeremy Hylton121d34a2003-07-08 12:36:58 +000025 return self.fileclass(self.text)
26
Jeremy Hylton8fff7922007-08-03 20:56:14 +000027class NoEOFStringIO(io.BytesIO):
Jeremy Hylton121d34a2003-07-08 12:36:58 +000028 """Like StringIO, but raises AssertionError on EOF.
29
30 This is used below to test that httplib doesn't try to read
31 more from the underlying file than it should.
32 """
33 def read(self, n=-1):
Jeremy Hylton8fff7922007-08-03 20:56:14 +000034 data = io.BytesIO.read(self, n)
Jeremy Hyltonda3f2282007-08-29 17:26:34 +000035 if data == b'':
Jeremy Hylton121d34a2003-07-08 12:36:58 +000036 raise AssertionError('caller tried to read past EOF')
37 return data
38
39 def readline(self, length=None):
Jeremy Hylton8fff7922007-08-03 20:56:14 +000040 data = io.BytesIO.readline(self, length)
Jeremy Hyltonda3f2282007-08-29 17:26:34 +000041 if data == b'':
Jeremy Hylton121d34a2003-07-08 12:36:58 +000042 raise AssertionError('caller tried to read past EOF')
43 return data
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000044
Jeremy Hylton2c178252004-08-07 16:28:14 +000045class HeaderTests(TestCase):
46 def test_auto_headers(self):
47 # Some headers are added automatically, but should not be added by
48 # .request() if they are explicitly set.
49
Jeremy Hylton2c178252004-08-07 16:28:14 +000050 class HeaderCountingBuffer(list):
51 def __init__(self):
52 self.count = {}
53 def append(self, item):
Guido van Rossum022c4742007-08-29 02:00:20 +000054 kv = item.split(b':')
Jeremy Hylton2c178252004-08-07 16:28:14 +000055 if len(kv) > 1:
56 # item is a 'Key: Value' header string
Martin v. Löwisdd5a8602007-06-30 09:22:09 +000057 lcKey = kv[0].decode('ascii').lower()
Jeremy Hylton2c178252004-08-07 16:28:14 +000058 self.count.setdefault(lcKey, 0)
59 self.count[lcKey] += 1
60 list.append(self, item)
61
62 for explicit_header in True, False:
63 for header in 'Content-length', 'Host', 'Accept-encoding':
64 conn = httplib.HTTPConnection('example.com')
65 conn.sock = FakeSocket('blahblahblah')
66 conn._buffer = HeaderCountingBuffer()
67
68 body = 'spamspamspam'
69 headers = {}
70 if explicit_header:
71 headers[header] = str(len(body))
72 conn.request('POST', '/', body, headers)
73 self.assertEqual(conn._buffer.count[header.lower()], 1)
74
Thomas Wouters89f507f2006-12-13 04:49:30 +000075class BasicTest(TestCase):
76 def test_status_lines(self):
77 # Test HTTP status lines
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000078
Thomas Wouters89f507f2006-12-13 04:49:30 +000079 body = "HTTP/1.1 200 Ok\r\n\r\nText"
80 sock = FakeSocket(body)
81 resp = httplib.HTTPResponse(sock)
Jeremy Hyltonba603192003-01-23 18:02:20 +000082 resp.begin()
Jeremy Hylton8fff7922007-08-03 20:56:14 +000083 self.assertEqual(resp.read(), b"Text")
Guido van Rossum8ce8a782007-11-01 19:42:39 +000084 self.assertTrue(resp.isclosed())
Jeremy Hyltonba603192003-01-23 18:02:20 +000085
Thomas Wouters89f507f2006-12-13 04:49:30 +000086 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
87 sock = FakeSocket(body)
88 resp = httplib.HTTPResponse(sock)
89 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +000090
Guido van Rossum8ce8a782007-11-01 19:42:39 +000091 def test_partial_reads(self):
92 # if we have a lenght, the system knows when to close itself
93 # same behaviour than when we read the whole thing with read()
94 body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
95 sock = FakeSocket(body)
96 resp = httplib.HTTPResponse(sock)
97 resp.begin()
98 self.assertEqual(resp.read(2), b'Te')
99 self.assertFalse(resp.isclosed())
100 self.assertEqual(resp.read(2), b'xt')
101 self.assertTrue(resp.isclosed())
102
Thomas Wouters89f507f2006-12-13 04:49:30 +0000103 def test_host_port(self):
104 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +0000105
Thomas Wouters89f507f2006-12-13 04:49:30 +0000106 for hp in ("www.python.org:abc", "www.python.org:"):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000107 self.assertRaises(httplib.InvalidURL, httplib.HTTPConnection, hp)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000108
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000109 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000",
110 "fe80::207:e9ff:fe9b", 8000),
Thomas Wouters89f507f2006-12-13 04:49:30 +0000111 ("www.python.org:80", "www.python.org", 80),
112 ("www.python.org", "www.python.org", 80),
113 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000114 c = httplib.HTTPConnection(hp)
115 self.assertEqual(h, c.host)
116 self.assertEqual(p, c.port)
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000117
Thomas Wouters89f507f2006-12-13 04:49:30 +0000118 def test_response_headers(self):
119 # test response with multiple message headers with the same field name.
120 text = ('HTTP/1.1 200 OK\r\n'
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000121 'Set-Cookie: Customer="WILE_E_COYOTE"; '
122 'Version="1"; Path="/acme"\r\n'
Thomas Wouters89f507f2006-12-13 04:49:30 +0000123 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
124 ' Path="/acme"\r\n'
125 '\r\n'
126 'No body\r\n')
127 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
128 ', '
129 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
130 s = FakeSocket(text)
131 r = httplib.HTTPResponse(s)
132 r.begin()
133 cookies = r.getheader("Set-Cookie")
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000134 self.assertEqual(cookies, hdr)
Jeremy Hyltonba603192003-01-23 18:02:20 +0000135
Thomas Wouters89f507f2006-12-13 04:49:30 +0000136 def test_read_head(self):
137 # Test that the library doesn't attempt to read any data
138 # from a HEAD request. (Tickles SF bug #622042.)
139 sock = FakeSocket(
140 'HTTP/1.1 200 OK\r\n'
141 'Content-Length: 14432\r\n'
142 '\r\n',
143 NoEOFStringIO)
144 resp = httplib.HTTPResponse(sock, method="HEAD")
145 resp.begin()
Guido van Rossuma00f1232007-09-12 19:43:09 +0000146 if resp.read():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000147 self.fail("Did not expect response from HEAD request")
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000148
Thomas Wouters89f507f2006-12-13 04:49:30 +0000149 def test_send_file(self):
Guido van Rossum022c4742007-08-29 02:00:20 +0000150 expected = (b'GET /foo HTTP/1.1\r\nHost: example.com\r\n'
151 b'Accept-Encoding: identity\r\nContent-Length:')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152
153 body = open(__file__, 'rb')
154 conn = httplib.HTTPConnection('example.com')
155 sock = FakeSocket(body)
156 conn.sock = sock
157 conn.request('GET', '/foo', body)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000158 self.assertTrue(sock.data.startswith(expected), '%r != %r' %
159 (sock.data[:len(expected)], expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000160
Christian Heimesa612dc02008-02-24 13:08:18 +0000161 def test_chunked(self):
162 chunked_start = (
163 'HTTP/1.1 200 OK\r\n'
164 'Transfer-Encoding: chunked\r\n\r\n'
165 'a\r\n'
166 'hello worl\r\n'
167 '1\r\n'
168 'd\r\n'
169 )
170 sock = FakeSocket(chunked_start + '0\r\n')
171 resp = httplib.HTTPResponse(sock, method="GET")
172 resp.begin()
173 self.assertEquals(resp.read(), b'hello world')
174 resp.close()
175
176 for x in ('', 'foo\r\n'):
177 sock = FakeSocket(chunked_start + x)
178 resp = httplib.HTTPResponse(sock, method="GET")
179 resp.begin()
180 try:
181 resp.read()
182 except httplib.IncompleteRead as i:
183 self.assertEquals(i.partial, b'hello world')
184 else:
185 self.fail('IncompleteRead expected')
186 finally:
187 resp.close()
188
189 def test_negative_content_length(self):
Jeremy Hylton82066952008-12-15 03:08:30 +0000190 sock = FakeSocket(
191 'HTTP/1.1 200 OK\r\nContent-Length: -1\r\n\r\nHello\r\n')
Christian Heimesa612dc02008-02-24 13:08:18 +0000192 resp = httplib.HTTPResponse(sock, method="GET")
193 resp.begin()
194 self.assertEquals(resp.read(), b'Hello\r\n')
195 resp.close()
196
197
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000198class OfflineTest(TestCase):
199 def test_responses(self):
200 self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
201
Guido van Rossumd8faa362007-04-27 19:54:29 +0000202class TimeoutTest(TestCase):
Christian Heimes5e696852008-04-09 08:37:03 +0000203 PORT = None
Guido van Rossumd8faa362007-04-27 19:54:29 +0000204
205 def setUp(self):
206 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000207 TimeoutTest.PORT = support.bind_port(self.serv)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000208 self.serv.listen(5)
209
210 def tearDown(self):
211 self.serv.close()
212 self.serv = None
213
214 def testTimeoutAttribute(self):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000215 # This will prove that the timeout gets through HTTPConnection
216 # and into the socket.
217
Georg Brandlf78e02b2008-06-10 17:40:04 +0000218 # default -- use global socket timeout
219 self.assert_(socket.getdefaulttimeout() is None)
220 socket.setdefaulttimeout(30)
221 try:
222 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
223 httpConn.connect()
224 finally:
225 socket.setdefaulttimeout(None)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000226 self.assertEqual(httpConn.sock.gettimeout(), 30)
227 httpConn.close()
228
Georg Brandlf78e02b2008-06-10 17:40:04 +0000229 # no timeout -- do not use global socket default
230 self.assert_(socket.getdefaulttimeout() is None)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000231 socket.setdefaulttimeout(30)
232 try:
Christian Heimes5e696852008-04-09 08:37:03 +0000233 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
234 timeout=None)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000235 httpConn.connect()
236 finally:
Georg Brandlf78e02b2008-06-10 17:40:04 +0000237 socket.setdefaulttimeout(None)
238 self.assertEqual(httpConn.sock.gettimeout(), None)
239 httpConn.close()
240
241 # a value
242 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
243 httpConn.connect()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000244 self.assertEqual(httpConn.sock.gettimeout(), 30)
245 httpConn.close()
246
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000247class HTTPSTimeoutTest(TestCase):
248# XXX Here should be tests for HTTPS, there isn't any right now!
249
250 def test_attributes(self):
251 # simple test to check it's storing it
Thomas Wouters582b5862007-08-30 22:39:17 +0000252 if hasattr(httplib, 'HTTPSConnection'):
Christian Heimes5e696852008-04-09 08:37:03 +0000253 h = httplib.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30)
Thomas Wouters582b5862007-08-30 22:39:17 +0000254 self.assertEqual(h.timeout, 30)
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000255
Jeremy Hylton2c178252004-08-07 16:28:14 +0000256def test_main(verbose=None):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000257 support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
Antoine Pitroub353c122009-02-11 00:39:14 +0000258 HTTPSTimeoutTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000259
Thomas Wouters89f507f2006-12-13 04:49:30 +0000260if __name__ == '__main__':
261 test_main()