blob: f11fac393930a18ffe8ecc6690bda2a31dca3c0f [file] [log] [blame]
Senthil Kumaranaa5f49e2010-10-03 18:26:07 +00001import httplib
Antoine Pitrou72481782009-09-29 17:48:18 +00002import array
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00003import httplib
4import StringIO
Facundo Batista07c78be2007-03-23 18:54:07 +00005import socket
Victor Stinner2c6aee92010-07-24 02:46:16 +00006import errno
Jeremy Hylton121d34a2003-07-08 12:36:58 +00007
Gregory P. Smith9d325212010-01-03 02:06:07 +00008import unittest
9TestCase = unittest.TestCase
Jeremy Hylton2c178252004-08-07 16:28:14 +000010
11from test import test_support
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000012
Trent Nelsone41b0062008-04-08 23:47:30 +000013HOST = test_support.HOST
14
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000015class FakeSocket:
Jeremy Hylton121d34a2003-07-08 12:36:58 +000016 def __init__(self, text, fileclass=StringIO.StringIO):
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000017 self.text = text
Jeremy Hylton121d34a2003-07-08 12:36:58 +000018 self.fileclass = fileclass
Martin v. Löwis040a9272006-11-12 10:32:47 +000019 self.data = ''
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000020
Jeremy Hylton2c178252004-08-07 16:28:14 +000021 def sendall(self, data):
Antoine Pitrou72481782009-09-29 17:48:18 +000022 self.data += ''.join(data)
Jeremy Hylton2c178252004-08-07 16:28:14 +000023
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000024 def makefile(self, mode, bufsize=None):
25 if mode != 'r' and mode != 'rb':
Neal Norwitz28bb5722002-04-01 19:00:50 +000026 raise httplib.UnimplementedFileMode()
Jeremy Hylton121d34a2003-07-08 12:36:58 +000027 return self.fileclass(self.text)
28
Victor Stinner2c6aee92010-07-24 02:46:16 +000029class EPipeSocket(FakeSocket):
30
31 def __init__(self, text, pipe_trigger):
32 # When sendall() is called with pipe_trigger, raise EPIPE.
33 FakeSocket.__init__(self, text)
34 self.pipe_trigger = pipe_trigger
35
36 def sendall(self, data):
37 if self.pipe_trigger in data:
38 raise socket.error(errno.EPIPE, "gotcha")
39 self.data += data
40
41 def close(self):
42 pass
43
Jeremy Hylton121d34a2003-07-08 12:36:58 +000044class NoEOFStringIO(StringIO.StringIO):
45 """Like StringIO, but raises AssertionError on EOF.
46
47 This is used below to test that httplib doesn't try to read
48 more from the underlying file than it should.
49 """
50 def read(self, n=-1):
51 data = StringIO.StringIO.read(self, n)
52 if data == '':
53 raise AssertionError('caller tried to read past EOF')
54 return data
55
56 def readline(self, length=None):
57 data = StringIO.StringIO.readline(self, length)
58 if data == '':
59 raise AssertionError('caller tried to read past EOF')
60 return data
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000061
Jeremy Hylton2c178252004-08-07 16:28:14 +000062
63class HeaderTests(TestCase):
64 def test_auto_headers(self):
65 # Some headers are added automatically, but should not be added by
66 # .request() if they are explicitly set.
67
Jeremy Hylton2c178252004-08-07 16:28:14 +000068 class HeaderCountingBuffer(list):
69 def __init__(self):
70 self.count = {}
71 def append(self, item):
72 kv = item.split(':')
73 if len(kv) > 1:
74 # item is a 'Key: Value' header string
75 lcKey = kv[0].lower()
76 self.count.setdefault(lcKey, 0)
77 self.count[lcKey] += 1
78 list.append(self, item)
79
80 for explicit_header in True, False:
81 for header in 'Content-length', 'Host', 'Accept-encoding':
82 conn = httplib.HTTPConnection('example.com')
83 conn.sock = FakeSocket('blahblahblah')
84 conn._buffer = HeaderCountingBuffer()
85
86 body = 'spamspamspam'
87 headers = {}
88 if explicit_header:
89 headers[header] = str(len(body))
90 conn.request('POST', '/', body, headers)
91 self.assertEqual(conn._buffer.count[header.lower()], 1)
92
Senthil Kumaran618802d2012-05-19 16:52:21 +080093 def test_content_length_0(self):
94
95 class ContentLengthChecker(list):
96 def __init__(self):
97 list.__init__(self)
98 self.content_length = None
99 def append(self, item):
100 kv = item.split(':', 1)
101 if len(kv) > 1 and kv[0].lower() == 'content-length':
102 self.content_length = kv[1].strip()
103 list.append(self, item)
104
105 # POST with empty body
106 conn = httplib.HTTPConnection('example.com')
107 conn.sock = FakeSocket(None)
108 conn._buffer = ContentLengthChecker()
109 conn.request('POST', '/', '')
110 self.assertEqual(conn._buffer.content_length, '0',
111 'Header Content-Length not set')
112
113 # PUT request with empty body
114 conn = httplib.HTTPConnection('example.com')
115 conn.sock = FakeSocket(None)
116 conn._buffer = ContentLengthChecker()
117 conn.request('PUT', '/', '')
118 self.assertEqual(conn._buffer.content_length, '0',
119 'Header Content-Length not set')
120
Senthil Kumaranaa5f49e2010-10-03 18:26:07 +0000121 def test_putheader(self):
122 conn = httplib.HTTPConnection('example.com')
123 conn.sock = FakeSocket(None)
124 conn.putrequest('GET','/')
125 conn.putheader('Content-length',42)
126 self.assertTrue('Content-length: 42' in conn._buffer)
127
Senthil Kumaran501bfd82010-11-14 03:31:52 +0000128 def test_ipv6host_header(self):
129 # Default host header on IPv6 transaction should wrapped by [] if
130 # its actual IPv6 address
131 expected = 'GET /foo HTTP/1.1\r\nHost: [2001::]:81\r\n' \
132 'Accept-Encoding: identity\r\n\r\n'
133 conn = httplib.HTTPConnection('[2001::]:81')
134 sock = FakeSocket('')
135 conn.sock = sock
136 conn.request('GET', '/foo')
137 self.assertTrue(sock.data.startswith(expected))
138
139 expected = 'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n' \
140 'Accept-Encoding: identity\r\n\r\n'
141 conn = httplib.HTTPConnection('[2001:102A::]')
142 sock = FakeSocket('')
143 conn.sock = sock
144 conn.request('GET', '/foo')
145 self.assertTrue(sock.data.startswith(expected))
146
147
Georg Brandl71a20892006-10-29 20:24:01 +0000148class BasicTest(TestCase):
149 def test_status_lines(self):
150 # Test HTTP status lines
Jeremy Hylton79fa2b62001-04-13 14:57:44 +0000151
Georg Brandl71a20892006-10-29 20:24:01 +0000152 body = "HTTP/1.1 200 Ok\r\n\r\nText"
153 sock = FakeSocket(body)
154 resp = httplib.HTTPResponse(sock)
Jeremy Hyltonba603192003-01-23 18:02:20 +0000155 resp.begin()
Serhiy Storchakac97f5ed2013-12-17 21:49:48 +0200156 self.assertEqual(resp.read(0), '') # Issue #20007
157 self.assertFalse(resp.isclosed())
Georg Brandl71a20892006-10-29 20:24:01 +0000158 self.assertEqual(resp.read(), 'Text')
Facundo Batista70665902007-10-18 03:16:03 +0000159 self.assertTrue(resp.isclosed())
Jeremy Hyltonba603192003-01-23 18:02:20 +0000160
Georg Brandl71a20892006-10-29 20:24:01 +0000161 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
162 sock = FakeSocket(body)
163 resp = httplib.HTTPResponse(sock)
164 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +0000165
Dirkjan Ochtmanebc73dc2010-02-24 04:49:00 +0000166 def test_bad_status_repr(self):
167 exc = httplib.BadStatusLine('')
Ezio Melotti2623a372010-11-21 13:34:58 +0000168 self.assertEqual(repr(exc), '''BadStatusLine("\'\'",)''')
Dirkjan Ochtmanebc73dc2010-02-24 04:49:00 +0000169
Facundo Batista70665902007-10-18 03:16:03 +0000170 def test_partial_reads(self):
Antoine Pitrou4113d2b2012-12-15 19:11:54 +0100171 # if we have a length, the system knows when to close itself
Facundo Batista70665902007-10-18 03:16:03 +0000172 # same behaviour than when we read the whole thing with read()
173 body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
174 sock = FakeSocket(body)
175 resp = httplib.HTTPResponse(sock)
176 resp.begin()
177 self.assertEqual(resp.read(2), 'Te')
178 self.assertFalse(resp.isclosed())
179 self.assertEqual(resp.read(2), 'xt')
180 self.assertTrue(resp.isclosed())
181
Antoine Pitrou4113d2b2012-12-15 19:11:54 +0100182 def test_partial_reads_no_content_length(self):
183 # when no length is present, the socket should be gracefully closed when
184 # all data was read
185 body = "HTTP/1.1 200 Ok\r\n\r\nText"
186 sock = FakeSocket(body)
187 resp = httplib.HTTPResponse(sock)
188 resp.begin()
189 self.assertEqual(resp.read(2), 'Te')
190 self.assertFalse(resp.isclosed())
191 self.assertEqual(resp.read(2), 'xt')
192 self.assertEqual(resp.read(1), '')
193 self.assertTrue(resp.isclosed())
194
Antoine Pitroud66c0ee2013-02-02 22:49:34 +0100195 def test_partial_reads_incomplete_body(self):
196 # if the server shuts down the connection before the whole
197 # content-length is delivered, the socket is gracefully closed
198 body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText"
199 sock = FakeSocket(body)
200 resp = httplib.HTTPResponse(sock)
201 resp.begin()
202 self.assertEqual(resp.read(2), 'Te')
203 self.assertFalse(resp.isclosed())
204 self.assertEqual(resp.read(2), 'xt')
205 self.assertEqual(resp.read(1), '')
206 self.assertTrue(resp.isclosed())
207
Georg Brandl71a20892006-10-29 20:24:01 +0000208 def test_host_port(self):
209 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +0000210
Łukasz Langa7a153902011-10-18 17:16:00 +0200211 # Note that httplib does not accept user:password@ in the host-port.
212 for hp in ("www.python.org:abc", "user:password@www.python.org"):
Georg Brandl71a20892006-10-29 20:24:01 +0000213 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
214
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000215 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
216 8000),
Georg Brandl71a20892006-10-29 20:24:01 +0000217 ("www.python.org:80", "www.python.org", 80),
218 ("www.python.org", "www.python.org", 80),
Łukasz Langa7a153902011-10-18 17:16:00 +0200219 ("www.python.org:", "www.python.org", 80),
Georg Brandl71a20892006-10-29 20:24:01 +0000220 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Martin v. Löwis74a249e2004-09-14 21:45:36 +0000221 http = httplib.HTTP(hp)
Georg Brandl71a20892006-10-29 20:24:01 +0000222 c = http._conn
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000223 if h != c.host:
224 self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
225 if p != c.port:
226 self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000227
Georg Brandl71a20892006-10-29 20:24:01 +0000228 def test_response_headers(self):
229 # test response with multiple message headers with the same field name.
230 text = ('HTTP/1.1 200 OK\r\n'
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000231 'Set-Cookie: Customer="WILE_E_COYOTE";'
232 ' Version="1"; Path="/acme"\r\n'
Georg Brandl71a20892006-10-29 20:24:01 +0000233 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
234 ' Path="/acme"\r\n'
235 '\r\n'
236 'No body\r\n')
237 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
238 ', '
239 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
240 s = FakeSocket(text)
241 r = httplib.HTTPResponse(s)
242 r.begin()
243 cookies = r.getheader("Set-Cookie")
244 if cookies != hdr:
245 self.fail("multiple headers not combined properly")
Jeremy Hyltonba603192003-01-23 18:02:20 +0000246
Georg Brandl71a20892006-10-29 20:24:01 +0000247 def test_read_head(self):
248 # Test that the library doesn't attempt to read any data
249 # from a HEAD request. (Tickles SF bug #622042.)
250 sock = FakeSocket(
251 'HTTP/1.1 200 OK\r\n'
252 'Content-Length: 14432\r\n'
253 '\r\n',
254 NoEOFStringIO)
255 resp = httplib.HTTPResponse(sock, method="HEAD")
256 resp.begin()
257 if resp.read() != "":
258 self.fail("Did not expect response from HEAD request")
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000259
Martin v. Löwis040a9272006-11-12 10:32:47 +0000260 def test_send_file(self):
261 expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
262 'Accept-Encoding: identity\r\nContent-Length:'
263
264 body = open(__file__, 'rb')
265 conn = httplib.HTTPConnection('example.com')
266 sock = FakeSocket(body)
267 conn.sock = sock
268 conn.request('GET', '/foo', body)
269 self.assertTrue(sock.data.startswith(expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000270
Antoine Pitrou72481782009-09-29 17:48:18 +0000271 def test_send(self):
272 expected = 'this is a test this is only a test'
273 conn = httplib.HTTPConnection('example.com')
274 sock = FakeSocket(None)
275 conn.sock = sock
276 conn.send(expected)
Ezio Melotti2623a372010-11-21 13:34:58 +0000277 self.assertEqual(expected, sock.data)
Antoine Pitrou72481782009-09-29 17:48:18 +0000278 sock.data = ''
279 conn.send(array.array('c', expected))
Ezio Melotti2623a372010-11-21 13:34:58 +0000280 self.assertEqual(expected, sock.data)
Antoine Pitrou72481782009-09-29 17:48:18 +0000281 sock.data = ''
282 conn.send(StringIO.StringIO(expected))
Ezio Melotti2623a372010-11-21 13:34:58 +0000283 self.assertEqual(expected, sock.data)
Antoine Pitrou72481782009-09-29 17:48:18 +0000284
Georg Brandl23635032008-02-24 00:03:22 +0000285 def test_chunked(self):
286 chunked_start = (
287 'HTTP/1.1 200 OK\r\n'
288 'Transfer-Encoding: chunked\r\n\r\n'
289 'a\r\n'
290 'hello worl\r\n'
291 '1\r\n'
292 'd\r\n'
293 )
294 sock = FakeSocket(chunked_start + '0\r\n')
295 resp = httplib.HTTPResponse(sock, method="GET")
296 resp.begin()
Ezio Melotti2623a372010-11-21 13:34:58 +0000297 self.assertEqual(resp.read(), 'hello world')
Georg Brandl23635032008-02-24 00:03:22 +0000298 resp.close()
299
300 for x in ('', 'foo\r\n'):
301 sock = FakeSocket(chunked_start + x)
302 resp = httplib.HTTPResponse(sock, method="GET")
303 resp.begin()
304 try:
305 resp.read()
306 except httplib.IncompleteRead, i:
Ezio Melotti2623a372010-11-21 13:34:58 +0000307 self.assertEqual(i.partial, 'hello world')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000308 self.assertEqual(repr(i),'IncompleteRead(11 bytes read)')
309 self.assertEqual(str(i),'IncompleteRead(11 bytes read)')
Georg Brandl23635032008-02-24 00:03:22 +0000310 else:
311 self.fail('IncompleteRead expected')
312 finally:
313 resp.close()
314
Senthil Kumaraned9204342010-04-28 17:20:43 +0000315 def test_chunked_head(self):
316 chunked_start = (
317 'HTTP/1.1 200 OK\r\n'
318 'Transfer-Encoding: chunked\r\n\r\n'
319 'a\r\n'
320 'hello world\r\n'
321 '1\r\n'
322 'd\r\n'
323 )
324 sock = FakeSocket(chunked_start + '0\r\n')
325 resp = httplib.HTTPResponse(sock, method="HEAD")
326 resp.begin()
Ezio Melotti2623a372010-11-21 13:34:58 +0000327 self.assertEqual(resp.read(), '')
328 self.assertEqual(resp.status, 200)
329 self.assertEqual(resp.reason, 'OK')
Senthil Kumaranfb695012010-06-04 17:17:09 +0000330 self.assertTrue(resp.isclosed())
Senthil Kumaraned9204342010-04-28 17:20:43 +0000331
Georg Brandl8c460d52008-02-24 00:14:24 +0000332 def test_negative_content_length(self):
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000333 sock = FakeSocket('HTTP/1.1 200 OK\r\n'
334 'Content-Length: -1\r\n\r\nHello\r\n')
Georg Brandl8c460d52008-02-24 00:14:24 +0000335 resp = httplib.HTTPResponse(sock, method="GET")
336 resp.begin()
Ezio Melotti2623a372010-11-21 13:34:58 +0000337 self.assertEqual(resp.read(), 'Hello\r\n')
Antoine Pitroud66c0ee2013-02-02 22:49:34 +0100338 self.assertTrue(resp.isclosed())
Georg Brandl8c460d52008-02-24 00:14:24 +0000339
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000340 def test_incomplete_read(self):
341 sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n')
342 resp = httplib.HTTPResponse(sock, method="GET")
343 resp.begin()
344 try:
345 resp.read()
346 except httplib.IncompleteRead as i:
Ezio Melotti2623a372010-11-21 13:34:58 +0000347 self.assertEqual(i.partial, 'Hello\r\n')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000348 self.assertEqual(repr(i),
349 "IncompleteRead(7 bytes read, 3 more expected)")
350 self.assertEqual(str(i),
351 "IncompleteRead(7 bytes read, 3 more expected)")
Antoine Pitroud66c0ee2013-02-02 22:49:34 +0100352 self.assertTrue(resp.isclosed())
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000353 else:
354 self.fail('IncompleteRead expected')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000355
Victor Stinner2c6aee92010-07-24 02:46:16 +0000356 def test_epipe(self):
357 sock = EPipeSocket(
358 "HTTP/1.0 401 Authorization Required\r\n"
359 "Content-type: text/html\r\n"
360 "WWW-Authenticate: Basic realm=\"example\"\r\n",
361 b"Content-Length")
362 conn = httplib.HTTPConnection("example.com")
363 conn.sock = sock
364 self.assertRaises(socket.error,
365 lambda: conn.request("PUT", "/url", "body"))
366 resp = conn.getresponse()
367 self.assertEqual(401, resp.status)
368 self.assertEqual("Basic realm=\"example\"",
369 resp.getheader("www-authenticate"))
370
Senthil Kumarand389cb52010-09-21 01:38:15 +0000371 def test_filenoattr(self):
372 # Just test the fileno attribute in the HTTPResponse Object.
373 body = "HTTP/1.1 200 Ok\r\n\r\nText"
374 sock = FakeSocket(body)
375 resp = httplib.HTTPResponse(sock)
376 self.assertTrue(hasattr(resp,'fileno'),
377 'HTTPResponse should expose a fileno attribute')
Georg Brandl23635032008-02-24 00:03:22 +0000378
Antoine Pitroud7b6ac62010-12-18 18:18:21 +0000379 # Test lines overflowing the max line size (_MAXLINE in http.client)
380
381 def test_overflowing_status_line(self):
382 self.skipTest("disabled for HTTP 0.9 support")
383 body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n"
384 resp = httplib.HTTPResponse(FakeSocket(body))
385 self.assertRaises((httplib.LineTooLong, httplib.BadStatusLine), resp.begin)
386
387 def test_overflowing_header_line(self):
388 body = (
389 'HTTP/1.1 200 OK\r\n'
390 'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n'
391 )
392 resp = httplib.HTTPResponse(FakeSocket(body))
393 self.assertRaises(httplib.LineTooLong, resp.begin)
394
395 def test_overflowing_chunked_line(self):
396 body = (
397 'HTTP/1.1 200 OK\r\n'
398 'Transfer-Encoding: chunked\r\n\r\n'
399 + '0' * 65536 + 'a\r\n'
400 'hello world\r\n'
401 '0\r\n'
402 )
403 resp = httplib.HTTPResponse(FakeSocket(body))
404 resp.begin()
405 self.assertRaises(httplib.LineTooLong, resp.read)
406
Senthil Kumaranf5aaf6f2012-04-29 10:15:31 +0800407 def test_early_eof(self):
408 # Test httpresponse with no \r\n termination,
409 body = "HTTP/1.1 200 Ok"
410 sock = FakeSocket(body)
411 resp = httplib.HTTPResponse(sock)
412 resp.begin()
413 self.assertEqual(resp.read(), '')
414 self.assertTrue(resp.isclosed())
Antoine Pitroud7b6ac62010-12-18 18:18:21 +0000415
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000416class OfflineTest(TestCase):
417 def test_responses(self):
Ezio Melotti2623a372010-11-21 13:34:58 +0000418 self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000419
Gregory P. Smith9d325212010-01-03 02:06:07 +0000420
421class SourceAddressTest(TestCase):
422 def setUp(self):
423 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
424 self.port = test_support.bind_port(self.serv)
425 self.source_port = test_support.find_unused_port()
426 self.serv.listen(5)
427 self.conn = None
428
429 def tearDown(self):
430 if self.conn:
431 self.conn.close()
432 self.conn = None
433 self.serv.close()
434 self.serv = None
435
436 def testHTTPConnectionSourceAddress(self):
437 self.conn = httplib.HTTPConnection(HOST, self.port,
438 source_address=('', self.source_port))
439 self.conn.connect()
440 self.assertEqual(self.conn.sock.getsockname()[1], self.source_port)
441
442 @unittest.skipIf(not hasattr(httplib, 'HTTPSConnection'),
443 'httplib.HTTPSConnection not defined')
444 def testHTTPSConnectionSourceAddress(self):
445 self.conn = httplib.HTTPSConnection(HOST, self.port,
446 source_address=('', self.source_port))
447 # We don't test anything here other the constructor not barfing as
448 # this code doesn't deal with setting up an active running SSL server
449 # for an ssl_wrapped connect() to actually return from.
450
451
Facundo Batista07c78be2007-03-23 18:54:07 +0000452class TimeoutTest(TestCase):
Trent Nelsone41b0062008-04-08 23:47:30 +0000453 PORT = None
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000454
Facundo Batista07c78be2007-03-23 18:54:07 +0000455 def setUp(self):
456 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Trent Nelson6c4a7c62008-04-09 00:34:53 +0000457 TimeoutTest.PORT = test_support.bind_port(self.serv)
Facundo Batistaf1966292007-03-25 03:20:05 +0000458 self.serv.listen(5)
Facundo Batista07c78be2007-03-23 18:54:07 +0000459
460 def tearDown(self):
461 self.serv.close()
462 self.serv = None
463
464 def testTimeoutAttribute(self):
465 '''This will prove that the timeout gets through
466 HTTPConnection and into the socket.
467 '''
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000468 # default -- use global socket timeout
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000469 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000470 socket.setdefaulttimeout(30)
471 try:
472 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
473 httpConn.connect()
474 finally:
475 socket.setdefaulttimeout(None)
Facundo Batista14553b02007-03-23 20:23:08 +0000476 self.assertEqual(httpConn.sock.gettimeout(), 30)
Facundo Batistaf1966292007-03-25 03:20:05 +0000477 httpConn.close()
Facundo Batista07c78be2007-03-23 18:54:07 +0000478
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000479 # no timeout -- do not use global socket default
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000480 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batista14553b02007-03-23 20:23:08 +0000481 socket.setdefaulttimeout(30)
482 try:
Trent Nelson6c4a7c62008-04-09 00:34:53 +0000483 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
484 timeout=None)
Facundo Batista14553b02007-03-23 20:23:08 +0000485 httpConn.connect()
486 finally:
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000487 socket.setdefaulttimeout(None)
488 self.assertEqual(httpConn.sock.gettimeout(), None)
489 httpConn.close()
490
491 # a value
492 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
493 httpConn.connect()
Facundo Batista14553b02007-03-23 20:23:08 +0000494 self.assertEqual(httpConn.sock.gettimeout(), 30)
Facundo Batistaf1966292007-03-25 03:20:05 +0000495 httpConn.close()
Facundo Batista07c78be2007-03-23 18:54:07 +0000496
497
Facundo Batista70f996b2007-05-21 17:32:32 +0000498class HTTPSTimeoutTest(TestCase):
499# XXX Here should be tests for HTTPS, there isn't any right now!
500
501 def test_attributes(self):
502 # simple test to check it's storing it
Thomas Wouters628e3bb2007-08-30 22:35:31 +0000503 if hasattr(httplib, 'HTTPSConnection'):
Trent Nelsone41b0062008-04-08 23:47:30 +0000504 h = httplib.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30)
Thomas Wouters628e3bb2007-08-30 22:35:31 +0000505 self.assertEqual(h.timeout, 30)
Facundo Batista70f996b2007-05-21 17:32:32 +0000506
Petri Lehtinen6d089df2011-10-26 21:25:56 +0300507 @unittest.skipIf(not hasattr(httplib, 'HTTPS'), 'httplib.HTTPS not available')
Łukasz Langa7a153902011-10-18 17:16:00 +0200508 def test_host_port(self):
509 # Check invalid host_port
510
511 # Note that httplib does not accept user:password@ in the host-port.
512 for hp in ("www.python.org:abc", "user:password@www.python.org"):
513 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
514
515 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
516 8000),
517 ("pypi.python.org:443", "pypi.python.org", 443),
518 ("pypi.python.org", "pypi.python.org", 443),
519 ("pypi.python.org:", "pypi.python.org", 443),
520 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 443)):
521 http = httplib.HTTPS(hp)
522 c = http._conn
523 if h != c.host:
524 self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
525 if p != c.port:
526 self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
527
528
Jeremy Hylton2c178252004-08-07 16:28:14 +0000529def test_main(verbose=None):
Trent Nelsone41b0062008-04-08 23:47:30 +0000530 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
Gregory P. Smith9d325212010-01-03 02:06:07 +0000531 HTTPSTimeoutTest, SourceAddressTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000532
Georg Brandl71a20892006-10-29 20:24:01 +0000533if __name__ == '__main__':
534 test_main()