6 from unittest
import TestCase
8 from test
import test_support
10 HOST
= test_support
.HOST
13 def __init__(self
, text
, fileclass
=StringIO
.StringIO
):
15 self
.fileclass
= fileclass
18 def sendall(self
, data
):
19 self
.data
+= ''.join(data
)
21 def makefile(self
, mode
, bufsize
=None):
22 if mode
!= 'r' and mode
!= 'rb':
23 raise httplib
.UnimplementedFileMode()
24 return self
.fileclass(self
.text
)
26 class NoEOFStringIO(StringIO
.StringIO
):
27 """Like StringIO, but raises AssertionError on EOF.
29 This is used below to test that httplib doesn't try to read
30 more from the underlying file than it should.
33 data
= StringIO
.StringIO
.read(self
, n
)
35 raise AssertionError('caller tried to read past EOF')
38 def readline(self
, length
=None):
39 data
= StringIO
.StringIO
.readline(self
, length
)
41 raise AssertionError('caller tried to read past EOF')
45 class 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.
52 class HeaderCountingBuffer(list):
55 def append(self
, item
):
58 # item is a 'Key: Value' header string
60 self
.count
.setdefault(lcKey
, 0)
61 self
.count
[lcKey
] += 1
62 list.append(self
, item
)
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()
73 headers
[header
] = str(len(body
))
74 conn
.request('POST', '/', body
, headers
)
75 self
.assertEqual(conn
._buffer
.count
[header
.lower()], 1)
77 class BasicTest(TestCase
):
78 def test_status_lines(self
):
79 # Test HTTP status lines
81 body
= "HTTP/1.1 200 Ok\r\n\r\nText"
82 sock
= FakeSocket(body
)
83 resp
= httplib
.HTTPResponse(sock
)
85 self
.assertEqual(resp
.read(), 'Text')
86 self
.assertTrue(resp
.isclosed())
88 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
)
93 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
)
100 self
.assertEqual(resp
.read(2), 'Te')
101 self
.assertFalse(resp
.isclosed())
102 self
.assertEqual(resp
.read(2), 'xt')
103 self
.assertTrue(resp
.isclosed())
105 def test_host_port(self
):
106 # Check invalid host_port
108 for hp
in ("www.python.org:abc", "www.python.org:"):
109 self
.assertRaises(httplib
.InvalidURL
, httplib
.HTTP
, hp
)
111 for hp
, h
, p
in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
113 ("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)):
116 http
= httplib
.HTTP(hp
)
119 self
.fail("Host incorrectly parsed: %s != %s" % (h
, c
.host
))
121 self
.fail("Port incorrectly parsed: %s != %s" % (p
, c
.host
))
123 def test_response_headers(self
):
124 # test response with multiple message headers with the same field name.
125 text
= ('HTTP/1.1 200 OK\r\n'
126 'Set-Cookie: Customer="WILE_E_COYOTE";'
127 ' Version="1"; Path="/acme"\r\n'
128 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
132 hdr
= ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
134 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
136 r
= httplib
.HTTPResponse(s
)
138 cookies
= r
.getheader("Set-Cookie")
140 self
.fail("multiple headers not combined properly")
142 def test_read_head(self
):
143 # Test that the library doesn't attempt to read any data
144 # from a HEAD request. (Tickles SF bug #622042.)
146 'HTTP/1.1 200 OK\r\n'
147 'Content-Length: 14432\r\n'
150 resp
= httplib
.HTTPResponse(sock
, method
="HEAD")
152 if resp
.read() != "":
153 self
.fail("Did not expect response from HEAD request")
155 def test_send_file(self
):
156 expected
= 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
157 'Accept-Encoding: identity\r\nContent-Length:'
159 body
= open(__file__
, 'rb')
160 conn
= httplib
.HTTPConnection('example.com')
161 sock
= FakeSocket(body
)
163 conn
.request('GET', '/foo', body
)
164 self
.assertTrue(sock
.data
.startswith(expected
))
167 expected
= 'this is a test this is only a test'
168 conn
= httplib
.HTTPConnection('example.com')
169 sock
= FakeSocket(None)
172 self
.assertEquals(expected
, sock
.data
)
174 conn
.send(array
.array('c', expected
))
175 self
.assertEquals(expected
, sock
.data
)
177 conn
.send(StringIO
.StringIO(expected
))
178 self
.assertEquals(expected
, sock
.data
)
180 def test_chunked(self
):
182 'HTTP/1.1 200 OK\r\n'
183 'Transfer-Encoding: chunked\r\n\r\n'
189 sock
= FakeSocket(chunked_start
+ '0\r\n')
190 resp
= httplib
.HTTPResponse(sock
, method
="GET")
192 self
.assertEquals(resp
.read(), 'hello world')
195 for x
in ('', 'foo\r\n'):
196 sock
= FakeSocket(chunked_start
+ x
)
197 resp
= httplib
.HTTPResponse(sock
, method
="GET")
201 except httplib
.IncompleteRead
, i
:
202 self
.assertEquals(i
.partial
, 'hello world')
203 self
.assertEqual(repr(i
),'IncompleteRead(11 bytes read)')
204 self
.assertEqual(str(i
),'IncompleteRead(11 bytes read)')
206 self
.fail('IncompleteRead expected')
210 def test_negative_content_length(self
):
211 sock
= FakeSocket('HTTP/1.1 200 OK\r\n'
212 'Content-Length: -1\r\n\r\nHello\r\n')
213 resp
= httplib
.HTTPResponse(sock
, method
="GET")
215 self
.assertEquals(resp
.read(), 'Hello\r\n')
218 def test_incomplete_read(self
):
219 sock
= FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n')
220 resp
= httplib
.HTTPResponse(sock
, method
="GET")
224 except httplib
.IncompleteRead
as i
:
225 self
.assertEquals(i
.partial
, 'Hello\r\n')
226 self
.assertEqual(repr(i
),
227 "IncompleteRead(7 bytes read, 3 more expected)")
228 self
.assertEqual(str(i
),
229 "IncompleteRead(7 bytes read, 3 more expected)")
231 self
.fail('IncompleteRead expected')
236 class OfflineTest(TestCase
):
237 def test_responses(self
):
238 self
.assertEquals(httplib
.responses
[httplib
.NOT_FOUND
], "Not Found")
240 class TimeoutTest(TestCase
):
244 self
.serv
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
245 TimeoutTest
.PORT
= test_support
.bind_port(self
.serv
)
252 def testTimeoutAttribute(self
):
253 '''This will prove that the timeout gets through
254 HTTPConnection and into the socket.
256 # default -- use global socket timeout
257 self
.assertTrue(socket
.getdefaulttimeout() is None)
258 socket
.setdefaulttimeout(30)
260 httpConn
= httplib
.HTTPConnection(HOST
, TimeoutTest
.PORT
)
263 socket
.setdefaulttimeout(None)
264 self
.assertEqual(httpConn
.sock
.gettimeout(), 30)
267 # no timeout -- do not use global socket default
268 self
.assertTrue(socket
.getdefaulttimeout() is None)
269 socket
.setdefaulttimeout(30)
271 httpConn
= httplib
.HTTPConnection(HOST
, TimeoutTest
.PORT
,
275 socket
.setdefaulttimeout(None)
276 self
.assertEqual(httpConn
.sock
.gettimeout(), None)
280 httpConn
= httplib
.HTTPConnection(HOST
, TimeoutTest
.PORT
, timeout
=30)
282 self
.assertEqual(httpConn
.sock
.gettimeout(), 30)
286 class HTTPSTimeoutTest(TestCase
):
287 # XXX Here should be tests for HTTPS, there isn't any right now!
289 def test_attributes(self
):
290 # simple test to check it's storing it
291 if hasattr(httplib
, 'HTTPSConnection'):
292 h
= httplib
.HTTPSConnection(HOST
, TimeoutTest
.PORT
, timeout
=30)
293 self
.assertEqual(h
.timeout
, 30)
295 def test_main(verbose
=None):
296 test_support
.run_unittest(HeaderTests
, OfflineTest
, BasicTest
, TimeoutTest
,
299 if __name__
== '__main__':