blob: c0c12e712228804a408180eda406a4647b78427c [file] [log] [blame]
Antoine Pitrou72481782009-09-29 17:48:18 +00001import array
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00002import httplib
3import StringIO
Facundo Batista07c78be2007-03-23 18:54:07 +00004import socket
Jeremy Hylton121d34a2003-07-08 12:36:58 +00005
Gregory P. Smith9d325212010-01-03 02:06:07 +00006import unittest
7TestCase = unittest.TestCase
Jeremy Hylton2c178252004-08-07 16:28:14 +00008
9from test import test_support
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000010
Trent Nelsone41b0062008-04-08 23:47:30 +000011HOST = test_support.HOST
12
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000013class FakeSocket:
Jeremy Hylton121d34a2003-07-08 12:36:58 +000014 def __init__(self, text, fileclass=StringIO.StringIO):
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öwis040a9272006-11-12 10:32:47 +000017 self.data = ''
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000018
Jeremy Hylton2c178252004-08-07 16:28:14 +000019 def sendall(self, data):
Antoine Pitrou72481782009-09-29 17:48:18 +000020 self.data += ''.join(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
27class NoEOFStringIO(StringIO.StringIO):
28 """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):
34 data = StringIO.StringIO.read(self, n)
35 if data == '':
36 raise AssertionError('caller tried to read past EOF')
37 return data
38
39 def readline(self, length=None):
40 data = StringIO.StringIO.readline(self, length)
41 if data == '':
42 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 +000045
46class HeaderTests(TestCase):
47 def test_auto_headers(self):
48 # Some headers are added automatically, but should not be added by
49 # .request() if they are explicitly set.
50
51 import httplib
52
53 class HeaderCountingBuffer(list):
54 def __init__(self):
55 self.count = {}
56 def append(self, item):
57 kv = item.split(':')
58 if len(kv) > 1:
59 # item is a 'Key: Value' header string
60 lcKey = kv[0].lower()
61 self.count.setdefault(lcKey, 0)
62 self.count[lcKey] += 1
63 list.append(self, item)
64
65 for explicit_header in True, False:
66 for header in 'Content-length', 'Host', 'Accept-encoding':
67 conn = httplib.HTTPConnection('example.com')
68 conn.sock = FakeSocket('blahblahblah')
69 conn._buffer = HeaderCountingBuffer()
70
71 body = 'spamspamspam'
72 headers = {}
73 if explicit_header:
74 headers[header] = str(len(body))
75 conn.request('POST', '/', body, headers)
76 self.assertEqual(conn._buffer.count[header.lower()], 1)
77
Georg Brandl71a20892006-10-29 20:24:01 +000078class BasicTest(TestCase):
79 def test_status_lines(self):
80 # Test HTTP status lines
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000081
Georg Brandl71a20892006-10-29 20:24:01 +000082 body = "HTTP/1.1 200 Ok\r\n\r\nText"
83 sock = FakeSocket(body)
84 resp = httplib.HTTPResponse(sock)
Jeremy Hyltonba603192003-01-23 18:02:20 +000085 resp.begin()
Georg Brandl71a20892006-10-29 20:24:01 +000086 self.assertEqual(resp.read(), 'Text')
Facundo Batista70665902007-10-18 03:16:03 +000087 self.assertTrue(resp.isclosed())
Jeremy Hyltonba603192003-01-23 18:02:20 +000088
Georg Brandl71a20892006-10-29 20:24:01 +000089 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
90 sock = FakeSocket(body)
91 resp = httplib.HTTPResponse(sock)
92 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +000093
Facundo Batista70665902007-10-18 03:16:03 +000094 def test_partial_reads(self):
95 # if we have a lenght, the system knows when to close itself
96 # same behaviour than when we read the whole thing with read()
97 body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
98 sock = FakeSocket(body)
99 resp = httplib.HTTPResponse(sock)
100 resp.begin()
101 self.assertEqual(resp.read(2), 'Te')
102 self.assertFalse(resp.isclosed())
103 self.assertEqual(resp.read(2), 'xt')
104 self.assertTrue(resp.isclosed())
105
Georg Brandl71a20892006-10-29 20:24:01 +0000106 def test_host_port(self):
107 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +0000108
Georg Brandl71a20892006-10-29 20:24:01 +0000109 for hp in ("www.python.org:abc", "www.python.org:"):
110 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
111
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000112 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
113 8000),
Georg Brandl71a20892006-10-29 20:24:01 +0000114 ("www.python.org:80", "www.python.org", 80),
115 ("www.python.org", "www.python.org", 80),
116 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Martin v. Löwis74a249e2004-09-14 21:45:36 +0000117 http = httplib.HTTP(hp)
Georg Brandl71a20892006-10-29 20:24:01 +0000118 c = http._conn
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000119 if h != c.host:
120 self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
121 if p != c.port:
122 self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000123
Georg Brandl71a20892006-10-29 20:24:01 +0000124 def test_response_headers(self):
125 # test response with multiple message headers with the same field name.
126 text = ('HTTP/1.1 200 OK\r\n'
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000127 'Set-Cookie: Customer="WILE_E_COYOTE";'
128 ' Version="1"; Path="/acme"\r\n'
Georg Brandl71a20892006-10-29 20:24:01 +0000129 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
130 ' Path="/acme"\r\n'
131 '\r\n'
132 'No body\r\n')
133 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
134 ', '
135 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
136 s = FakeSocket(text)
137 r = httplib.HTTPResponse(s)
138 r.begin()
139 cookies = r.getheader("Set-Cookie")
140 if cookies != hdr:
141 self.fail("multiple headers not combined properly")
Jeremy Hyltonba603192003-01-23 18:02:20 +0000142
Georg Brandl71a20892006-10-29 20:24:01 +0000143 def test_read_head(self):
144 # Test that the library doesn't attempt to read any data
145 # from a HEAD request. (Tickles SF bug #622042.)
146 sock = FakeSocket(
147 'HTTP/1.1 200 OK\r\n'
148 'Content-Length: 14432\r\n'
149 '\r\n',
150 NoEOFStringIO)
151 resp = httplib.HTTPResponse(sock, method="HEAD")
152 resp.begin()
153 if resp.read() != "":
154 self.fail("Did not expect response from HEAD request")
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000155
Martin v. Löwis040a9272006-11-12 10:32:47 +0000156 def test_send_file(self):
157 expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
158 'Accept-Encoding: identity\r\nContent-Length:'
159
160 body = open(__file__, 'rb')
161 conn = httplib.HTTPConnection('example.com')
162 sock = FakeSocket(body)
163 conn.sock = sock
164 conn.request('GET', '/foo', body)
165 self.assertTrue(sock.data.startswith(expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000166
Antoine Pitrou72481782009-09-29 17:48:18 +0000167 def test_send(self):
168 expected = 'this is a test this is only a test'
169 conn = httplib.HTTPConnection('example.com')
170 sock = FakeSocket(None)
171 conn.sock = sock
172 conn.send(expected)
173 self.assertEquals(expected, sock.data)
174 sock.data = ''
175 conn.send(array.array('c', expected))
176 self.assertEquals(expected, sock.data)
177 sock.data = ''
178 conn.send(StringIO.StringIO(expected))
179 self.assertEquals(expected, sock.data)
180
Georg Brandl23635032008-02-24 00:03:22 +0000181 def test_chunked(self):
182 chunked_start = (
183 'HTTP/1.1 200 OK\r\n'
184 'Transfer-Encoding: chunked\r\n\r\n'
185 'a\r\n'
186 'hello worl\r\n'
187 '1\r\n'
188 'd\r\n'
189 )
190 sock = FakeSocket(chunked_start + '0\r\n')
191 resp = httplib.HTTPResponse(sock, method="GET")
192 resp.begin()
193 self.assertEquals(resp.read(), 'hello world')
194 resp.close()
195
196 for x in ('', 'foo\r\n'):
197 sock = FakeSocket(chunked_start + x)
198 resp = httplib.HTTPResponse(sock, method="GET")
199 resp.begin()
200 try:
201 resp.read()
202 except httplib.IncompleteRead, i:
203 self.assertEquals(i.partial, 'hello world')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000204 self.assertEqual(repr(i),'IncompleteRead(11 bytes read)')
205 self.assertEqual(str(i),'IncompleteRead(11 bytes read)')
Georg Brandl23635032008-02-24 00:03:22 +0000206 else:
207 self.fail('IncompleteRead expected')
208 finally:
209 resp.close()
210
Georg Brandl8c460d52008-02-24 00:14:24 +0000211 def test_negative_content_length(self):
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000212 sock = FakeSocket('HTTP/1.1 200 OK\r\n'
213 'Content-Length: -1\r\n\r\nHello\r\n')
Georg Brandl8c460d52008-02-24 00:14:24 +0000214 resp = httplib.HTTPResponse(sock, method="GET")
215 resp.begin()
216 self.assertEquals(resp.read(), 'Hello\r\n')
217 resp.close()
218
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000219 def test_incomplete_read(self):
220 sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n')
221 resp = httplib.HTTPResponse(sock, method="GET")
222 resp.begin()
223 try:
224 resp.read()
225 except httplib.IncompleteRead as i:
226 self.assertEquals(i.partial, 'Hello\r\n')
227 self.assertEqual(repr(i),
228 "IncompleteRead(7 bytes read, 3 more expected)")
229 self.assertEqual(str(i),
230 "IncompleteRead(7 bytes read, 3 more expected)")
231 else:
232 self.fail('IncompleteRead expected')
233 finally:
234 resp.close()
235
Georg Brandl23635032008-02-24 00:03:22 +0000236
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000237class OfflineTest(TestCase):
238 def test_responses(self):
239 self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
240
Gregory P. Smith9d325212010-01-03 02:06:07 +0000241
242class SourceAddressTest(TestCase):
243 def setUp(self):
244 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
245 self.port = test_support.bind_port(self.serv)
246 self.source_port = test_support.find_unused_port()
247 self.serv.listen(5)
248 self.conn = None
249
250 def tearDown(self):
251 if self.conn:
252 self.conn.close()
253 self.conn = None
254 self.serv.close()
255 self.serv = None
256
257 def testHTTPConnectionSourceAddress(self):
258 self.conn = httplib.HTTPConnection(HOST, self.port,
259 source_address=('', self.source_port))
260 self.conn.connect()
261 self.assertEqual(self.conn.sock.getsockname()[1], self.source_port)
262
263 @unittest.skipIf(not hasattr(httplib, 'HTTPSConnection'),
264 'httplib.HTTPSConnection not defined')
265 def testHTTPSConnectionSourceAddress(self):
266 self.conn = httplib.HTTPSConnection(HOST, self.port,
267 source_address=('', self.source_port))
268 # We don't test anything here other the constructor not barfing as
269 # this code doesn't deal with setting up an active running SSL server
270 # for an ssl_wrapped connect() to actually return from.
271
272
Facundo Batista07c78be2007-03-23 18:54:07 +0000273class TimeoutTest(TestCase):
Trent Nelsone41b0062008-04-08 23:47:30 +0000274 PORT = None
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000275
Facundo Batista07c78be2007-03-23 18:54:07 +0000276 def setUp(self):
277 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Trent Nelson6c4a7c62008-04-09 00:34:53 +0000278 TimeoutTest.PORT = test_support.bind_port(self.serv)
Facundo Batistaf1966292007-03-25 03:20:05 +0000279 self.serv.listen(5)
Facundo Batista07c78be2007-03-23 18:54:07 +0000280
281 def tearDown(self):
282 self.serv.close()
283 self.serv = None
284
285 def testTimeoutAttribute(self):
286 '''This will prove that the timeout gets through
287 HTTPConnection and into the socket.
288 '''
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000289 # default -- use global socket timeout
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000290 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000291 socket.setdefaulttimeout(30)
292 try:
293 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
294 httpConn.connect()
295 finally:
296 socket.setdefaulttimeout(None)
Facundo Batista14553b02007-03-23 20:23:08 +0000297 self.assertEqual(httpConn.sock.gettimeout(), 30)
Facundo Batistaf1966292007-03-25 03:20:05 +0000298 httpConn.close()
Facundo Batista07c78be2007-03-23 18:54:07 +0000299
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000300 # no timeout -- do not use global socket default
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000301 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batista14553b02007-03-23 20:23:08 +0000302 socket.setdefaulttimeout(30)
303 try:
Trent Nelson6c4a7c62008-04-09 00:34:53 +0000304 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
305 timeout=None)
Facundo Batista14553b02007-03-23 20:23:08 +0000306 httpConn.connect()
307 finally:
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000308 socket.setdefaulttimeout(None)
309 self.assertEqual(httpConn.sock.gettimeout(), None)
310 httpConn.close()
311
312 # a value
313 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
314 httpConn.connect()
Facundo Batista14553b02007-03-23 20:23:08 +0000315 self.assertEqual(httpConn.sock.gettimeout(), 30)
Facundo Batistaf1966292007-03-25 03:20:05 +0000316 httpConn.close()
Facundo Batista07c78be2007-03-23 18:54:07 +0000317
318
Facundo Batista70f996b2007-05-21 17:32:32 +0000319class HTTPSTimeoutTest(TestCase):
320# XXX Here should be tests for HTTPS, there isn't any right now!
321
322 def test_attributes(self):
323 # simple test to check it's storing it
Thomas Wouters628e3bb2007-08-30 22:35:31 +0000324 if hasattr(httplib, 'HTTPSConnection'):
Trent Nelsone41b0062008-04-08 23:47:30 +0000325 h = httplib.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30)
Thomas Wouters628e3bb2007-08-30 22:35:31 +0000326 self.assertEqual(h.timeout, 30)
Facundo Batista70f996b2007-05-21 17:32:32 +0000327
Jeremy Hylton2c178252004-08-07 16:28:14 +0000328def test_main(verbose=None):
Trent Nelsone41b0062008-04-08 23:47:30 +0000329 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
Gregory P. Smith9d325212010-01-03 02:06:07 +0000330 HTTPSTimeoutTest, SourceAddressTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000331
Georg Brandl71a20892006-10-29 20:24:01 +0000332if __name__ == '__main__':
333 test_main()