blob: 2d61c4646d27ee7f73e4a48768d918ce4d140608 [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 Hylton121d34a2003-07-08 12:36:58 +000034 if data == '':
35 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 Hylton121d34a2003-07-08 12:36:58 +000040 if data == '':
41 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):
56 kv = item.split(':')
57 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")
Thomas Wouters89f507f2006-12-13 04:49:30 +000086 resp.close()
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
Thomas Wouters89f507f2006-12-13 04:49:30 +000093 def test_host_port(self):
94 # Check invalid host_port
Jeremy Hyltonba603192003-01-23 18:02:20 +000095
Thomas Wouters89f507f2006-12-13 04:49:30 +000096 for hp in ("www.python.org:abc", "www.python.org:"):
Jeremy Hylton3a38c912007-08-14 17:08:07 +000097 self.assertRaises(httplib.InvalidURL, httplib.HTTPConnection, hp)
Thomas Wouters89f507f2006-12-13 04:49:30 +000098
Jeremy Hylton3a38c912007-08-14 17:08:07 +000099 for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000",
100 "fe80::207:e9ff:fe9b", 8000),
Thomas Wouters89f507f2006-12-13 04:49:30 +0000101 ("www.python.org:80", "www.python.org", 80),
102 ("www.python.org", "www.python.org", 80),
103 ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000104 c = httplib.HTTPConnection(hp)
105 self.assertEqual(h, c.host)
106 self.assertEqual(p, c.port)
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000107
Thomas Wouters89f507f2006-12-13 04:49:30 +0000108 def test_response_headers(self):
109 # test response with multiple message headers with the same field name.
110 text = ('HTTP/1.1 200 OK\r\n'
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000111 'Set-Cookie: Customer="WILE_E_COYOTE"; '
112 'Version="1"; Path="/acme"\r\n'
Thomas Wouters89f507f2006-12-13 04:49:30 +0000113 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
114 ' Path="/acme"\r\n'
115 '\r\n'
116 'No body\r\n')
117 hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
118 ', '
119 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
120 s = FakeSocket(text)
121 r = httplib.HTTPResponse(s)
122 r.begin()
123 cookies = r.getheader("Set-Cookie")
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000124 self.assertEqual(cookies, hdr)
Jeremy Hyltonba603192003-01-23 18:02:20 +0000125
Thomas Wouters89f507f2006-12-13 04:49:30 +0000126 def test_read_head(self):
127 # Test that the library doesn't attempt to read any data
128 # from a HEAD request. (Tickles SF bug #622042.)
129 sock = FakeSocket(
130 'HTTP/1.1 200 OK\r\n'
131 'Content-Length: 14432\r\n'
132 '\r\n',
133 NoEOFStringIO)
134 resp = httplib.HTTPResponse(sock, method="HEAD")
135 resp.begin()
136 if resp.read() != "":
137 self.fail("Did not expect response from HEAD request")
138 resp.close()
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000139
Thomas Wouters89f507f2006-12-13 04:49:30 +0000140 def test_send_file(self):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000141 expected = ('GET /foo HTTP/1.1\r\nHost: example.com\r\n'
142 'Accept-Encoding: identity\r\nContent-Length:')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000143
144 body = open(__file__, 'rb')
145 conn = httplib.HTTPConnection('example.com')
146 sock = FakeSocket(body)
147 conn.sock = sock
148 conn.request('GET', '/foo', body)
149 self.assertTrue(sock.data.startswith(expected))
Jeremy Hylton2c178252004-08-07 16:28:14 +0000150
Georg Brandl4cbd1e32006-02-17 22:01:08 +0000151class OfflineTest(TestCase):
152 def test_responses(self):
153 self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
154
Guido van Rossumd8faa362007-04-27 19:54:29 +0000155PORT = 50003
156HOST = "localhost"
157
158class TimeoutTest(TestCase):
159
160 def setUp(self):
161 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
162 self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
163 global PORT
164 PORT = test_support.bind_port(self.serv, HOST, PORT)
165 self.serv.listen(5)
166
167 def tearDown(self):
168 self.serv.close()
169 self.serv = None
170
171 def testTimeoutAttribute(self):
Jeremy Hylton3a38c912007-08-14 17:08:07 +0000172 # This will prove that the timeout gets through HTTPConnection
173 # and into the socket.
174
Guido van Rossumd8faa362007-04-27 19:54:29 +0000175 # default
176 httpConn = httplib.HTTPConnection(HOST, PORT)
177 httpConn.connect()
178 self.assertTrue(httpConn.sock.gettimeout() is None)
179 httpConn.close()
180
181 # a value
182 httpConn = httplib.HTTPConnection(HOST, PORT, timeout=30)
183 httpConn.connect()
184 self.assertEqual(httpConn.sock.gettimeout(), 30)
185 httpConn.close()
186
187 # None, having other default
188 previous = socket.getdefaulttimeout()
189 socket.setdefaulttimeout(30)
190 try:
191 httpConn = httplib.HTTPConnection(HOST, PORT, timeout=None)
192 httpConn.connect()
193 finally:
194 socket.setdefaulttimeout(previous)
195 self.assertEqual(httpConn.sock.gettimeout(), 30)
196 httpConn.close()
197
198
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000199class HTTPSTimeoutTest(TestCase):
200# XXX Here should be tests for HTTPS, there isn't any right now!
201
202 def test_attributes(self):
203 # simple test to check it's storing it
204 h = httplib.HTTPSConnection(HOST, PORT, timeout=30)
205 self.assertEqual(h.timeout, 30)
206
Jeremy Hylton2c178252004-08-07 16:28:14 +0000207def test_main(verbose=None):
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000208 test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, HTTPSTimeoutTest)
Jeremy Hylton2c178252004-08-07 16:28:14 +0000209
Thomas Wouters89f507f2006-12-13 04:49:30 +0000210if __name__ == '__main__':
211 test_main()