20
20
# TODO: Should be renamed to bzrlib.transport.http.tests?
25
from bzrlib.errors import DependencyNotPresent
28
from bzrlib.errors import DependencyNotPresent, UnsupportedProtocol
26
29
from bzrlib.tests import TestCase, TestSkipped
27
from bzrlib.transport import Transport
30
from bzrlib.transport import get_transport, Transport
28
31
from bzrlib.transport.http import extract_auth, HttpTransportBase
29
32
from bzrlib.transport.http._urllib import HttpTransport_urllib
30
33
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
33
class FakeManager (object):
36
class FakeManager(object):
35
38
def __init__(self):
36
39
self.credentials = []
39
42
self.credentials.append([realm, host, username, password])
45
class RecordingServer(object):
46
"""A fake HTTP server.
48
It records the bytes sent to it, and replies with a 200.
51
def __init__(self, expect_body_tail=None):
52
self._expect_body_tail = expect_body_tail
55
self.received_bytes = ''
58
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
59
self._sock.bind(('127.0.0.1', 0))
60
self.host, self.port = self._sock.getsockname()
61
self._ready = threading.Event()
62
self._thread = threading.Thread(target=self._accept_read_and_reply)
63
self._thread.setDaemon(True)
67
def _accept_read_and_reply(self):
70
self._sock.settimeout(5)
72
conn, address = self._sock.accept()
73
# On win32, the accepted connection will be non-blocking to start
74
# with because we're using settimeout.
75
conn.setblocking(True)
76
while not self.received_bytes.endswith(self._expect_body_tail):
77
self.received_bytes += conn.recv(4096)
78
conn.sendall('HTTP/1.1 200 OK\r\n')
79
except socket.timeout:
80
# Make sure the client isn't stuck waiting for us to e.g. accept.
87
# We might have already closed it. We don't care.
42
93
class TestHttpUrls(TestCase):
44
95
def test_url_parsing(self):
204
254
self.assertEqual([[10, 12], [22, 26]], ranges)
257
class TestPost(TestCase):
259
def _test_post_body_is_received(self, scheme):
260
server = RecordingServer(expect_body_tail='end-of-body')
262
self.addCleanup(server.tearDown)
263
url = '%s://%s:%s/' % (scheme, server.host, server.port)
265
http_transport = get_transport(url)
266
except UnsupportedProtocol:
267
raise TestSkipped('%s not available' % scheme)
268
code, response = http_transport._post('abc def end-of-body')
270
server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
271
self.assertTrue('content-length: 19\r' in server.received_bytes.lower())
272
# The transport should not be assuming that the server can accept
273
# chunked encoding the first time it connects, because HTTP/1.1, so we
274
# check for the literal string.
276
server.received_bytes.endswith('\r\n\r\nabc def end-of-body'))
278
def test_post_body_is_received_urllib(self):
279
self._test_post_body_is_received('http+urllib')
281
def test_post_body_is_received_pycurl(self):
282
self._test_post_body_is_received('http+pycurl')
207
285
class TestRangeHeader(TestCase):
208
286
"""Test range_header method"""
227
305
self.check_header('0-9,300-5000,-50',
228
306
ranges=[(0,9), (300,5000)],
310
class TestRecordingServer(TestCase):
312
def test_create(self):
313
server = RecordingServer(expect_body_tail=None)
314
self.assertEqual('', server.received_bytes)
315
self.assertEqual(None, server.host)
316
self.assertEqual(None, server.port)
318
def test_setUp_and_tearDown(self):
319
server = RecordingServer(expect_body_tail=None)
322
self.assertNotEqual(None, server.host)
323
self.assertNotEqual(None, server.port)
326
self.assertEqual(None, server.host)
327
self.assertEqual(None, server.port)
329
def test_send_receive_bytes(self):
330
server = RecordingServer(expect_body_tail='c')
332
self.addCleanup(server.tearDown)
333
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
334
sock.connect((server.host, server.port))
336
self.assertEqual('HTTP/1.1 200 OK\r\n',
337
sock.recv(4096, socket.MSG_WAITALL))
338
self.assertEqual('abc', server.received_bytes)