blob: 7e5a8a5c950a65e8010cdb250c07b3a59590cf29 [file] [log] [blame]
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00001import httplib
Jeremy Hylton8fff7922007-08-03 20:56:14 +00002import io
Jeremy Hylton121d34a2003-07-08 12:36:58 +00003import sys
Guido van Rossumd8faa362007-04-27 19:54:29 +00004import socket
Jeremy Hylton121d34a2003-07-08 12:36:58 +00005
Jeremy Hylton2c178252004-08-07 16:28:14 +00006from unittest import TestCase
7
8from test import test_support
Jeremy Hylton79fa2b62001-04-13 14:57:44 +00009
10class FakeSocket:
Jeremy Hylton8fff7922007-08-03 20:56:14 +000011 def __init__(self, text, fileclass=io.BytesIO):
12 if isinstance(text, str):
Guido van Rossum39478e82007-08-27 17:23:59 +000013 text = text.encode("ascii")
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000014 self.text = text
Jeremy Hylton121d34a2003-07-08 12:36:58 +000015 self.fileclass = fileclass
Martin v. Löwisdd5a8602007-06-30 09:22:09 +000016 self.data = b''
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000017
Jeremy Hylton2c178252004-08-07 16:28:14 +000018 def sendall(self, data):
Thomas Wouters89f507f2006-12-13 04:49:30 +000019 self.data += data
Jeremy Hylton2c178252004-08-07 16:28:14 +000020
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000021 def makefile(self, mode, bufsize=None):
22 if mode != 'r' and mode != 'rb':
Neal Norwitz28bb5722002-04-01 19:00:50 +000023 raise httplib.UnimplementedFileMode()
Jeremy Hylton121d34a2003-07-08 12:36:58 +000024 return self.fileclass(self.text)
25
Jeremy Hylton8fff7922007-08-03 20:56:14 +000026class NoEOFStringIO(io.BytesIO):
Jeremy Hylton121d34a2003-07-08 12:36:58 +000027 """Like StringIO, but raises AssertionError on EOF.
28
29 This is used below to test that httplib doesn't try to read
30 more from the underlying file than it should.
31 """
32 def read(self, n=-1):
Jeremy Hylton8fff7922007-08-03 20:56:14 +000033 data = io.BytesIO.read(self, n)
Jeremy Hyltonda3f2282007-08-29 17:26:34 +000034 if data == b'':
Jeremy Hylton121d34a2003-07-08 12:36:58 +000035 raise AssertionError('caller tried to read past EOF')
36 return data
37
38 def readline(self, length=None):
Jeremy Hylton8fff7922007-08-03 20:56:14 +000039 data = io.BytesIO.readline(self, length)
Jeremy Hyltonda3f2282007-08-29 17:26:34 +000040 if data == b'':
Jeremy Hylton121d34a2003-07-08 12:36:58 +000041 raise AssertionError('caller tried to read past EOF')
42 return data
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000043
Jeremy Hylton2c178252004-08-07 16:28:14 +000044
45class 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
50 import httplib
51
52 class HeaderCountingBuffer(list):
53 def __init__(self):
54 self.count = {}
55 def append(self, item):
Guido van Rossum022c4742007-08-29 02:00:20 +000056 kv = item.split(b':')
Jeremy Hylton2c178252004-08-07 16:28:14 +000057 if len(kv) > 1:
58 # item is a 'Key: Value' header string
Martin v. Löwisdd5a8602007-06-30 09:22:09 +000059 lcKey = kv[0].decode('ascii').lower()
Jeremy Hylton2c178252004-08-07 16:28:14 +000060 self.count.setdefault(lcKey, 0)
61 self.count[lcKey] += 1
62 list.append(self, item)
63
64 for explicit_header in True, False:
65 for header in 'Content-length', 'Host', 'Accept-encoding':
66 conn = httplib.HTTPConnection('example.com')
67 conn.sock = FakeSocket('blahblahblah')
68 conn._buffer = HeaderCountingBuffer()
69
70 body = 'spamspamspam'
71 headers = {}
72 if explicit_header:
73 headers[header] = str(len(body))
74 conn.request('POST', '/', body, headers)
75 self.assertEqual(conn._buffer.count[header.lower()], 1)
76
Thomas Wouters89f507f2006-12-13 04:49:30 +000077class BasicTest(TestCase):
78 def test_status_lines(self):
79 # Test HTTP status lines
Jeremy Hylton79fa2b62001-04-13 14:57:44 +000080
Thomas Wouters89f507f2006-12-13 04:49:30 +000081 body = "HTTP/1.1 200 Ok\r\n\r\nText"
82 sock = FakeSocket(body)
83 resp = httplib.HTTPResponse(sock)
Jeremy Hyltonba603192003-01-23 18:02:20 +000084 resp.begin()
Jeremy Hylton8fff7922007-08-03 20:56:14 +000085 self.assertEqual(resp.read(), b"Text")
Guido van Rossum8ce8a782007-11-01 19:42:39 +000086 self.assertTrue(resp.isclosed())
Jeremy Hyltonba603192003-01-23 18:02:20 +000087
Thomas Wouters89f507f2006-12-13 04:49:30 +000088 body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
89 sock = FakeSocket(body)
90 resp = httplib.HTTPResponse(sock)
91 self.assertRaises(httplib.BadStatusLine, resp.begin)
Jeremy Hyltonba603192003-01-23 18:02:20 +000092
Guido van Rossum8ce8a782007-11-01 19:42:39 +000093 def test_partial_reads(self):
94 # if we have a lenght, the system knows when to close itself
95 # same behaviour than when we read the whole thing with read()
96 body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
97 sock = FakeSocket(body)
98 resp = httplib.HTTPResponse(sock)
99 resp.begin()
100 self.assertEqual(resp.read(2), b'Te')
101 self.assertFalse(resp.isclosed())
102 self.assertEqual(resp.read(2), b'xt')
103 self.assertTrue(resp.isclosed())
104
Thomas Wouters89f507f2006-12-13 04:49:30 +0000105 def test_host_port(self):
106 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +0000107
Thomas Wouters89f507f2006-12-13 04:49:30 +0000108 for hp in ("www.python.org:abc", "www.python.org:"):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000109 self.assertRaises(httplib.InvalidURL, httplib.HTTPConnection, hp)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000110
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000111 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000",
112 "fe80::207:e9ff:fe9b", 8000),
Thomas Wouters89f507f2006-12-13 04:49:30 +0000113 ("www.python.org:80", "www.python.org", 80),
114 ("www.python.org", "www.python.org", 80),
115 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000116 c = httplib.HTTPConnection(hp)
117 self.assertEqual(h, c.host)
118 self.assertEqual(p, c.port)
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000119
Thomas Wouters89f507f2006-12-13 04:49:30 +0000120 def test_response_headers(self):
121 # test response with multiple message headers with the same field name.
122 text = ('HTTP/1.1 200 OK\r\n'
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000123 'Set-Cookie: Customer="WILE_E_COYOTE"; '
124 'Version="1"; Path="/acme"\r\n'
Thomas Wouters89f507f2006-12-13 04:49:30 +0000125 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
126 ' Path="/acme"\r\n'
127 '\r\n'
128 'No body\r\n')
129 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
130 ', '
131 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
132 s = FakeSocket(text)
133 r = httplib.HTTPResponse(s)
134 r.begin()
135 cookies = r.getheader("Set-Cookie")
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000136 self.assertEqual(cookies, hdr)
Jeremy Hyltonba603192003-01-23 18:02:20 +0000137
Thomas Wouters89f507f2006-12-13 04:49:30 +0000138 def test_read_head(self):
139 # Test that the library doesn't attempt to read any data
140 # from a HEAD request. (Tickles SF bug #622042.)
141 sock = FakeSocket(
142 'HTTP/1.1 200 OK\r\n'
143 'Content-Length: 14432\r\n'
144 '\r\n',
145 NoEOFStringIO)
146 resp = httplib.HTTPResponse(sock, method="HEAD")
147 resp.begin()
Guido van Rossuma00f1232007-09-12 19:43:09 +0000148 if resp.read():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000149 self.fail("Did not expect response from HEAD request")
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000150
Thomas Wouters89f507f2006-12-13 04:49:30 +0000151 def test_send_file(self):
Guido van Rossum022c4742007-08-29 02:00:20 +0000152 expected = (b'GET /foo HTTP/1.1\r\nHost: example.com\r\n'
153 b'Accept-Encoding: identity\r\nContent-Length:')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000154
155 body = open(__file__, 'rb')
156 conn = httplib.HTTPConnection('example.com')
157 sock = FakeSocket(body)
158 conn.sock = sock
159 conn.request('GET', '/foo', body)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000160 self.assertTrue(sock.data.startswith(expected), '%r != %r' %
161 (sock.data[:len(expected)], expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000162
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000163class OfflineTest(TestCase):
164 def test_responses(self):
165 self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
166
Guido van Rossumd8faa362007-04-27 19:54:29 +0000167PORT = 50003
168HOST = "localhost"
169
170class TimeoutTest(TestCase):
171
172 def setUp(self):
173 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
174 self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
175 global PORT
176 PORT = test_support.bind_port(self.serv, HOST, PORT)
177 self.serv.listen(5)
178
179 def tearDown(self):
180 self.serv.close()
181 self.serv = None
182
183 def testTimeoutAttribute(self):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000184 # This will prove that the timeout gets through HTTPConnection
185 # and into the socket.
186
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187 # default
188 httpConn = httplib.HTTPConnection(HOST, PORT)
189 httpConn.connect()
190 self.assertTrue(httpConn.sock.gettimeout() is None)
191 httpConn.close()
192
193 # a value
194 httpConn = httplib.HTTPConnection(HOST, PORT, timeout=30)
195 httpConn.connect()
196 self.assertEqual(httpConn.sock.gettimeout(), 30)
197 httpConn.close()
198
199 # None, having other default
200 previous = socket.getdefaulttimeout()
201 socket.setdefaulttimeout(30)
202 try:
203 httpConn = httplib.HTTPConnection(HOST, PORT, timeout=None)
204 httpConn.connect()
205 finally:
206 socket.setdefaulttimeout(previous)
207 self.assertEqual(httpConn.sock.gettimeout(), 30)
208 httpConn.close()
209
210
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000211class HTTPSTimeoutTest(TestCase):
212# XXX Here should be tests for HTTPS, there isn't any right now!
213
214 def test_attributes(self):
215 # simple test to check it's storing it
Thomas Wouters582b5862007-08-30 22:39:17 +0000216 if hasattr(httplib, 'HTTPSConnection'):
217 h = httplib.HTTPSConnection(HOST, PORT, timeout=30)
218 self.assertEqual(h.timeout, 30)
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000219
Jeremy Hylton2c178252004-08-07 16:28:14 +0000220def test_main(verbose=None):
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000221 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, HTTPSTimeoutTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000222
Thomas Wouters89f507f2006-12-13 04:49:30 +0000223if __name__ == '__main__':
224 test_main()