1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
89
88
errno.ECONNABORTED, errno.EBADF)):
92
error_content_type = 'text/plain'
93
error_message_format = '''\
98
def send_error(self, code, message=None):
99
"""Send and log an error reply.
101
We redefine the python-provided version to be able to set a
102
``Content-Length`` header as some http/1.1 clients complain otherwise
105
:param code: The HTTP error code.
107
:param message: The explanation of the error code, Defaults to a short
113
message = self.responses[code][0]
116
self.log_error("code %d, message %s", code, message)
117
content = (self.error_message_format %
118
{'code': code, 'message': message})
119
self.send_response(code, message)
120
self.send_header("Content-Type", self.error_content_type)
121
self.send_header("Content-Length", "%d" % len(content))
122
self.send_header('Connection', 'close')
124
if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
125
self.wfile.write(content)
127
91
_range_regexp = re.compile(r'^(?P<start>\d+)-(?P<end>\d+)$')
128
92
_tail_regexp = re.compile(r'^-(?P<tail>\d+)$')
354
318
self.test_case_server = test_case_server
355
319
self._home_dir = test_case_server._home_dir
357
def stop_server(self):
358
322
"""Called to clean-up the server.
360
324
Since the server may be (surely is, even) in a blocking listen, we
383
347
# 'Socket is not connected' can also occur on OSX, with a
384
348
# "regular" ENOTCONN (when something went wrong during test case
385
349
# setup leading to self.setUp() *not* being called but
386
# self.stop_server() still being called -- vila20081106
350
# self.tearDown() still being called -- vila20081106
387
351
if not len(e.args) or e.args[0] not in (errno.ENOTCONN, 10057):
389
353
# Let the server properly close the socket
557
521
"""Capture Server log output."""
558
522
self.logs.append(format % args)
560
def start_server(self, backing_transport_server=None):
561
"""See bzrlib.transport.Server.start_server.
524
def setUp(self, backing_transport_server=None):
525
"""See bzrlib.transport.Server.setUp.
563
527
:param backing_transport_server: The transport that requests over this
564
528
protocol should be forwarded to. Note that this is currently not
567
531
# XXX: TODO: make the server back onto vfs_server rather than local
569
if not (backing_transport_server is None
570
or isinstance(backing_transport_server,
571
test_server.LocalURLServer)):
533
if not (backing_transport_server is None or \
534
isinstance(backing_transport_server, local.LocalURLServer)):
572
535
raise AssertionError(
573
536
"HTTPServer currently assumes local transport, got %s" % \
574
537
backing_transport_server)
594
557
self._http_starting.release()
597
def stop_server(self):
598
self._httpd.stop_server()
561
"""See bzrlib.transport.Server.tearDown."""
562
self._httpd.tearDown()
599
563
self._http_running = False
600
564
# We don't need to 'self._http_thread.join()' here since the thread is
601
565
# a daemonic one and will be garbage collected anyway. Joining just