blob: 3e81a2c0f9aa846eecbc600b6be370186f5860a0 [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()
Georg Brandl71a20892006-10-29 20:24:01 +0000156 self.assertEqual(resp.read(), 'Text')
Facundo Batista70665902007-10-18 03:16:03 +0000157 self.assertTrue(resp.isclosed())
Jeremy Hyltonba603192003-01-23 18:02:20 +0000158
Georg Brandl71a20892006-10-29 20:24:01 +0000159 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
160 sock = FakeSocket(body)
161 resp = httplib.HTTPResponse(sock)
162 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +0000163
Dirkjan Ochtmanebc73dc2010-02-24 04:49:00 +0000164 def test_bad_status_repr(self):
165 exc = httplib.BadStatusLine('')
Ezio Melotti2623a372010-11-21 13:34:58 +0000166 self.assertEqual(repr(exc), '''BadStatusLine("\'\'",)''')
Dirkjan Ochtmanebc73dc2010-02-24 04:49:00 +0000167
Facundo Batista70665902007-10-18 03:16:03 +0000168 def test_partial_reads(self):
Antoine Pitrou4113d2b2012-12-15 19:11:54 +0100169 # if we have a length, the system knows when to close itself
Facundo Batista70665902007-10-18 03:16:03 +0000170 # same behaviour than when we read the whole thing with read()
171 body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
172 sock = FakeSocket(body)
173 resp = httplib.HTTPResponse(sock)
174 resp.begin()
175 self.assertEqual(resp.read(2), 'Te')
176 self.assertFalse(resp.isclosed())
177 self.assertEqual(resp.read(2), 'xt')
178 self.assertTrue(resp.isclosed())
179
Antoine Pitrou4113d2b2012-12-15 19:11:54 +0100180 def test_partial_reads_no_content_length(self):
181 # when no length is present, the socket should be gracefully closed when
182 # all data was read
183 body = "HTTP/1.1 200 Ok\r\n\r\nText"
184 sock = FakeSocket(body)
185 resp = httplib.HTTPResponse(sock)
186 resp.begin()
187 self.assertEqual(resp.read(2), 'Te')
188 self.assertFalse(resp.isclosed())
189 self.assertEqual(resp.read(2), 'xt')
190 self.assertEqual(resp.read(1), '')
191 self.assertTrue(resp.isclosed())
192
Antoine Pitroud66c0ee2013-02-02 22:49:34 +0100193 def test_partial_reads_incomplete_body(self):
194 # if the server shuts down the connection before the whole
195 # content-length is delivered, the socket is gracefully closed
196 body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText"
197 sock = FakeSocket(body)
198 resp = httplib.HTTPResponse(sock)
199 resp.begin()
200 self.assertEqual(resp.read(2), 'Te')
201 self.assertFalse(resp.isclosed())
202 self.assertEqual(resp.read(2), 'xt')
203 self.assertEqual(resp.read(1), '')
204 self.assertTrue(resp.isclosed())
205
Georg Brandl71a20892006-10-29 20:24:01 +0000206 def test_host_port(self):
207 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +0000208
Łukasz Langa7a153902011-10-18 17:16:00 +0200209 # Note that httplib does not accept user:password@ in the host-port.
210 for hp in ("www.python.org:abc", "user:password@www.python.org"):
Georg Brandl71a20892006-10-29 20:24:01 +0000211 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
212
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000213 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
214 8000),
Georg Brandl71a20892006-10-29 20:24:01 +0000215 ("www.python.org:80", "www.python.org", 80),
216 ("www.python.org", "www.python.org", 80),
Łukasz Langa7a153902011-10-18 17:16:00 +0200217 ("www.python.org:", "www.python.org", 80),
Georg Brandl71a20892006-10-29 20:24:01 +0000218 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Martin v. Löwis74a249e2004-09-14 21:45:36 +0000219 http = httplib.HTTP(hp)
Georg Brandl71a20892006-10-29 20:24:01 +0000220 c = http._conn
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000221 if h != c.host:
222 self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
223 if p != c.port:
224 self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000225
Georg Brandl71a20892006-10-29 20:24:01 +0000226 def test_response_headers(self):
227 # test response with multiple message headers with the same field name.
228 text = ('HTTP/1.1 200 OK\r\n'
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000229 'Set-Cookie: Customer="WILE_E_COYOTE";'
230 ' Version="1"; Path="/acme"\r\n'
Georg Brandl71a20892006-10-29 20:24:01 +0000231 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
232 ' Path="/acme"\r\n'
233 '\r\n'
234 'No body\r\n')
235 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
236 ', '
237 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
238 s = FakeSocket(text)
239 r = httplib.HTTPResponse(s)
240 r.begin()
241 cookies = r.getheader("Set-Cookie")
242 if cookies != hdr:
243 self.fail("multiple headers not combined properly")
Jeremy Hyltonba603192003-01-23 18:02:20 +0000244
Georg Brandl71a20892006-10-29 20:24:01 +0000245 def test_read_head(self):
246 # Test that the library doesn't attempt to read any data
247 # from a HEAD request. (Tickles SF bug #622042.)
248 sock = FakeSocket(
249 'HTTP/1.1 200 OK\r\n'
250 'Content-Length: 14432\r\n'
251 '\r\n',
252 NoEOFStringIO)
253 resp = httplib.HTTPResponse(sock, method="HEAD")
254 resp.begin()
255 if resp.read() != "":
256 self.fail("Did not expect response from HEAD request")
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000257
Martin v. Löwis040a9272006-11-12 10:32:47 +0000258 def test_send_file(self):
259 expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
260 'Accept-Encoding: identity\r\nContent-Length:'
261
262 body = open(__file__, 'rb')
263 conn = httplib.HTTPConnection('example.com')
264 sock = FakeSocket(body)
265 conn.sock = sock
266 conn.request('GET', '/foo', body)
267 self.assertTrue(sock.data.startswith(expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000268
Antoine Pitrou72481782009-09-29 17:48:18 +0000269 def test_send(self):
270 expected = 'this is a test this is only a test'
271 conn = httplib.HTTPConnection('example.com')
272 sock = FakeSocket(None)
273 conn.sock = sock
274 conn.send(expected)
Ezio Melotti2623a372010-11-21 13:34:58 +0000275 self.assertEqual(expected, sock.data)
Antoine Pitrou72481782009-09-29 17:48:18 +0000276 sock.data = ''
277 conn.send(array.array('c', expected))
Ezio Melotti2623a372010-11-21 13:34:58 +0000278 self.assertEqual(expected, sock.data)
Antoine Pitrou72481782009-09-29 17:48:18 +0000279 sock.data = ''
280 conn.send(StringIO.StringIO(expected))
Ezio Melotti2623a372010-11-21 13:34:58 +0000281 self.assertEqual(expected, sock.data)
Antoine Pitrou72481782009-09-29 17:48:18 +0000282
Georg Brandl23635032008-02-24 00:03:22 +0000283 def test_chunked(self):
284 chunked_start = (
285 'HTTP/1.1 200 OK\r\n'
286 'Transfer-Encoding: chunked\r\n\r\n'
287 'a\r\n'
288 'hello worl\r\n'
289 '1\r\n'
290 'd\r\n'
291 )
292 sock = FakeSocket(chunked_start + '0\r\n')
293 resp = httplib.HTTPResponse(sock, method="GET")
294 resp.begin()
Ezio Melotti2623a372010-11-21 13:34:58 +0000295 self.assertEqual(resp.read(), 'hello world')
Georg Brandl23635032008-02-24 00:03:22 +0000296 resp.close()
297
298 for x in ('', 'foo\r\n'):
299 sock = FakeSocket(chunked_start + x)
300 resp = httplib.HTTPResponse(sock, method="GET")
301 resp.begin()
302 try:
303 resp.read()
304 except httplib.IncompleteRead, i:
Ezio Melotti2623a372010-11-21 13:34:58 +0000305 self.assertEqual(i.partial, 'hello world')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000306 self.assertEqual(repr(i),'IncompleteRead(11 bytes read)')
307 self.assertEqual(str(i),'IncompleteRead(11 bytes read)')
Georg Brandl23635032008-02-24 00:03:22 +0000308 else:
309 self.fail('IncompleteRead expected')
310 finally:
311 resp.close()
312
Senthil Kumaraned9204342010-04-28 17:20:43 +0000313 def test_chunked_head(self):
314 chunked_start = (
315 'HTTP/1.1 200 OK\r\n'
316 'Transfer-Encoding: chunked\r\n\r\n'
317 'a\r\n'
318 'hello world\r\n'
319 '1\r\n'
320 'd\r\n'
321 )
322 sock = FakeSocket(chunked_start + '0\r\n')
323 resp = httplib.HTTPResponse(sock, method="HEAD")
324 resp.begin()
Ezio Melotti2623a372010-11-21 13:34:58 +0000325 self.assertEqual(resp.read(), '')
326 self.assertEqual(resp.status, 200)
327 self.assertEqual(resp.reason, 'OK')
Senthil Kumaranfb695012010-06-04 17:17:09 +0000328 self.assertTrue(resp.isclosed())
Senthil Kumaraned9204342010-04-28 17:20:43 +0000329
Georg Brandl8c460d52008-02-24 00:14:24 +0000330 def test_negative_content_length(self):
Jeremy Hylton21d2e592008-11-29 00:09:16 +0000331 sock = FakeSocket('HTTP/1.1 200 OK\r\n'
332 'Content-Length: -1\r\n\r\nHello\r\n')
Georg Brandl8c460d52008-02-24 00:14:24 +0000333 resp = httplib.HTTPResponse(sock, method="GET")
334 resp.begin()
Ezio Melotti2623a372010-11-21 13:34:58 +0000335 self.assertEqual(resp.read(), 'Hello\r\n')
Antoine Pitroud66c0ee2013-02-02 22:49:34 +0100336 self.assertTrue(resp.isclosed())
Georg Brandl8c460d52008-02-24 00:14:24 +0000337
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000338 def test_incomplete_read(self):
339 sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n')
340 resp = httplib.HTTPResponse(sock, method="GET")
341 resp.begin()
342 try:
343 resp.read()
344 except httplib.IncompleteRead as i:
Ezio Melotti2623a372010-11-21 13:34:58 +0000345 self.assertEqual(i.partial, 'Hello\r\n')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000346 self.assertEqual(repr(i),
347 "IncompleteRead(7 bytes read, 3 more expected)")
348 self.assertEqual(str(i),
349 "IncompleteRead(7 bytes read, 3 more expected)")
Antoine Pitroud66c0ee2013-02-02 22:49:34 +0100350 self.assertTrue(resp.isclosed())
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000351 else:
352 self.fail('IncompleteRead expected')
Benjamin Peterson7d49bba2009-03-02 22:41:42 +0000353
Victor Stinner2c6aee92010-07-24 02:46:16 +0000354 def test_epipe(self):
355 sock = EPipeSocket(
356 "HTTP/1.0 401 Authorization Required\r\n"
357 "Content-type: text/html\r\n"
358 "WWW-Authenticate: Basic realm=\"example\"\r\n",
359 b"Content-Length")
360 conn = httplib.HTTPConnection("example.com")
361 conn.sock = sock
362 self.assertRaises(socket.error,
363 lambda: conn.request("PUT", "/url", "body"))
364 resp = conn.getresponse()
365 self.assertEqual(401, resp.status)
366 self.assertEqual("Basic realm=\"example\"",
367 resp.getheader("www-authenticate"))
368
Senthil Kumarand389cb52010-09-21 01:38:15 +0000369 def test_filenoattr(self):
370 # Just test the fileno attribute in the HTTPResponse Object.
371 body = "HTTP/1.1 200 Ok\r\n\r\nText"
372 sock = FakeSocket(body)
373 resp = httplib.HTTPResponse(sock)
374 self.assertTrue(hasattr(resp,'fileno'),
375 'HTTPResponse should expose a fileno attribute')
Georg Brandl23635032008-02-24 00:03:22 +0000376
Antoine Pitroud7b6ac62010-12-18 18:18:21 +0000377 # Test lines overflowing the max line size (_MAXLINE in http.client)
378
379 def test_overflowing_status_line(self):
380 self.skipTest("disabled for HTTP 0.9 support")
381 body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n"
382 resp = httplib.HTTPResponse(FakeSocket(body))
383 self.assertRaises((httplib.LineTooLong, httplib.BadStatusLine), resp.begin)
384
385 def test_overflowing_header_line(self):
386 body = (
387 'HTTP/1.1 200 OK\r\n'
388 'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n'
389 )
390 resp = httplib.HTTPResponse(FakeSocket(body))
391 self.assertRaises(httplib.LineTooLong, resp.begin)
392
393 def test_overflowing_chunked_line(self):
394 body = (
395 'HTTP/1.1 200 OK\r\n'
396 'Transfer-Encoding: chunked\r\n\r\n'
397 + '0' * 65536 + 'a\r\n'
398 'hello world\r\n'
399 '0\r\n'
400 )
401 resp = httplib.HTTPResponse(FakeSocket(body))
402 resp.begin()
403 self.assertRaises(httplib.LineTooLong, resp.read)
404
Senthil Kumaranf5aaf6f2012-04-29 10:15:31 +0800405 def test_early_eof(self):
406 # Test httpresponse with no \r\n termination,
407 body = "HTTP/1.1 200 Ok"
408 sock = FakeSocket(body)
409 resp = httplib.HTTPResponse(sock)
410 resp.begin()
411 self.assertEqual(resp.read(), '')
412 self.assertTrue(resp.isclosed())
Antoine Pitroud7b6ac62010-12-18 18:18:21 +0000413
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000414class OfflineTest(TestCase):
415 def test_responses(self):
Ezio Melotti2623a372010-11-21 13:34:58 +0000416 self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000417
Gregory P. Smith9d325212010-01-03 02:06:07 +0000418
419class SourceAddressTest(TestCase):
420 def setUp(self):
421 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
422 self.port = test_support.bind_port(self.serv)
423 self.source_port = test_support.find_unused_port()
424 self.serv.listen(5)
425 self.conn = None
426
427 def tearDown(self):
428 if self.conn:
429 self.conn.close()
430 self.conn = None
431 self.serv.close()
432 self.serv = None
433
434 def testHTTPConnectionSourceAddress(self):
435 self.conn = httplib.HTTPConnection(HOST, self.port,
436 source_address=('', self.source_port))
437 self.conn.connect()
438 self.assertEqual(self.conn.sock.getsockname()[1], self.source_port)
439
440 @unittest.skipIf(not hasattr(httplib, 'HTTPSConnection'),
441 'httplib.HTTPSConnection not defined')
442 def testHTTPSConnectionSourceAddress(self):
443 self.conn = httplib.HTTPSConnection(HOST, self.port,
444 source_address=('', self.source_port))
445 # We don't test anything here other the constructor not barfing as
446 # this code doesn't deal with setting up an active running SSL server
447 # for an ssl_wrapped connect() to actually return from.
448
449
Facundo Batista07c78be2007-03-23 18:54:07 +0000450class TimeoutTest(TestCase):
Trent Nelsone41b0062008-04-08 23:47:30 +0000451 PORT = None
Neal Norwitz0d4c06e2007-04-25 06:30:05 +0000452
Facundo Batista07c78be2007-03-23 18:54:07 +0000453 def setUp(self):
454 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Trent Nelson6c4a7c62008-04-09 00:34:53 +0000455 TimeoutTest.PORT = test_support.bind_port(self.serv)
Facundo Batistaf1966292007-03-25 03:20:05 +0000456 self.serv.listen(5)
Facundo Batista07c78be2007-03-23 18:54:07 +0000457
458 def tearDown(self):
459 self.serv.close()
460 self.serv = None
461
462 def testTimeoutAttribute(self):
463 '''This will prove that the timeout gets through
464 HTTPConnection and into the socket.
465 '''
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000466 # default -- use global socket timeout
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000467 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000468 socket.setdefaulttimeout(30)
469 try:
470 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
471 httpConn.connect()
472 finally:
473 socket.setdefaulttimeout(None)
Facundo Batista14553b02007-03-23 20:23:08 +0000474 self.assertEqual(httpConn.sock.gettimeout(), 30)
Facundo Batistaf1966292007-03-25 03:20:05 +0000475 httpConn.close()
Facundo Batista07c78be2007-03-23 18:54:07 +0000476
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000477 # no timeout -- do not use global socket default
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000478 self.assertTrue(socket.getdefaulttimeout() is None)
Facundo Batista14553b02007-03-23 20:23:08 +0000479 socket.setdefaulttimeout(30)
480 try:
Trent Nelson6c4a7c62008-04-09 00:34:53 +0000481 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
482 timeout=None)
Facundo Batista14553b02007-03-23 20:23:08 +0000483 httpConn.connect()
484 finally:
Facundo Batista4f1b1ed2008-05-29 16:39:26 +0000485 socket.setdefaulttimeout(None)
486 self.assertEqual(httpConn.sock.gettimeout(), None)
487 httpConn.close()
488
489 # a value
490 httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
491 httpConn.connect()
Facundo Batista14553b02007-03-23 20:23:08 +0000492 self.assertEqual(httpConn.sock.gettimeout(), 30)
Facundo Batistaf1966292007-03-25 03:20:05 +0000493 httpConn.close()
Facundo Batista07c78be2007-03-23 18:54:07 +0000494
495
Facundo Batista70f996b2007-05-21 17:32:32 +0000496class HTTPSTimeoutTest(TestCase):
497# XXX Here should be tests for HTTPS, there isn't any right now!
498
499 def test_attributes(self):
500 # simple test to check it's storing it
Thomas Wouters628e3bb2007-08-30 22:35:31 +0000501 if hasattr(httplib, 'HTTPSConnection'):
Trent Nelsone41b0062008-04-08 23:47:30 +0000502 h = httplib.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30)
Thomas Wouters628e3bb2007-08-30 22:35:31 +0000503 self.assertEqual(h.timeout, 30)
Facundo Batista70f996b2007-05-21 17:32:32 +0000504
Petri Lehtinen6d089df2011-10-26 21:25:56 +0300505 @unittest.skipIf(not hasattr(httplib, 'HTTPS'), 'httplib.HTTPS not available')
Łukasz Langa7a153902011-10-18 17:16:00 +0200506 def test_host_port(self):
507 # Check invalid host_port
508
509 # Note that httplib does not accept user:password@ in the host-port.
510 for hp in ("www.python.org:abc", "user:password@www.python.org"):
511 self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
512
513 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
514 8000),
515 ("pypi.python.org:443", "pypi.python.org", 443),
516 ("pypi.python.org", "pypi.python.org", 443),
517 ("pypi.python.org:", "pypi.python.org", 443),
518 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 443)):
519 http = httplib.HTTPS(hp)
520 c = http._conn
521 if h != c.host:
522 self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
523 if p != c.port:
524 self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
525
526
Jeremy Hylton2c178252004-08-07 16:28:14 +0000527def test_main(verbose=None):
Trent Nelsone41b0062008-04-08 23:47:30 +0000528 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
Gregory P. Smith9d325212010-01-03 02:06:07 +0000529 HTTPSTimeoutTest, SourceAddressTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000530
Georg Brandl71a20892006-10-29 20:24:01 +0000531if __name__ == '__main__':
532 test_main()