~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/http_server.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-08-20 05:20:56 UTC
  • mfrom: (5380.3.3 doc)
  • Revision ID: pqm@pqm.ubuntu.com-20100820052056-gwad7dz2otckrjax
(mbp) Start whatsnew for 2.3; update ppa developer docs (Martin Pool)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
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
31
31
import urlparse
32
32
 
33
33
from bzrlib import transport
 
34
from bzrlib.tests import test_server
34
35
from bzrlib.transport import local
35
36
 
36
37
 
88
89
                                     errno.ECONNABORTED, errno.EBADF)):
89
90
                raise
90
91
 
 
92
    error_content_type = 'text/plain'
 
93
    error_message_format = '''\
 
94
Error code: %(code)s.
 
95
Message: %(message)s.
 
96
'''
 
97
 
 
98
    def send_error(self, code, message=None):
 
99
        """Send and log an error reply.
 
100
 
 
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
 
103
        (see bug #568421).
 
104
 
 
105
        :param code: The HTTP error code.
 
106
 
 
107
        :param message: The explanation of the error code, Defaults to a short
 
108
             entry.
 
109
        """
 
110
 
 
111
        if message is None:
 
112
            try:
 
113
                message = self.responses[code][0]
 
114
            except KeyError:
 
115
                message = '???'
 
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')
 
123
        self.end_headers()
 
124
        if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
 
125
            self.wfile.write(content)
 
126
 
91
127
    _range_regexp = re.compile(r'^(?P<start>\d+)-(?P<end>\d+)$')
92
128
    _tail_regexp = re.compile(r'^-(?P<tail>\d+)$')
93
129
 
318
354
        self.test_case_server = test_case_server
319
355
        self._home_dir = test_case_server._home_dir
320
356
 
321
 
    def tearDown(self):
 
357
    def stop_server(self):
322
358
         """Called to clean-up the server.
323
359
 
324
360
         Since the server may be (surely is, even) in a blocking listen, we
347
383
             # 'Socket is not connected' can also occur on OSX, with a
348
384
             # "regular" ENOTCONN (when something went wrong during test case
349
385
             # setup leading to self.setUp() *not* being called but
350
 
             # self.tearDown() still being called -- vila20081106
 
386
             # self.stop_server() still being called -- vila20081106
351
387
             if not len(e.args) or e.args[0] not in (errno.ENOTCONN, 10057):
352
388
                 raise
353
389
         # Let the server properly close the socket
462
498
                raise httplib.UnknownProtocol(proto_vers)
463
499
            else:
464
500
                self._httpd = self.create_httpd(serv_cls, rhandler)
465
 
            host, self.port = self._httpd.socket.getsockname()
 
501
            self.host, self.port = self._httpd.socket.getsockname()
466
502
        return self._httpd
467
503
 
468
504
    def _http_start(self):
494
530
            except socket.timeout:
495
531
                pass
496
532
            except (socket.error, select.error), e:
497
 
               if e[0] == errno.EBADF:
498
 
                   # Starting with python-2.6, handle_request may raise socket
499
 
                   # or select exceptions when the server is shut down (as we
500
 
                   # do).
501
 
                   pass
502
 
               else:
503
 
                   raise
 
533
                if (e[0] == errno.EBADF
 
534
                    or (sys.platform == 'win32' and e[0] == 10038)):
 
535
                    # Starting with python-2.6, handle_request may raise socket
 
536
                    # or select exceptions when the server is shut down (as we
 
537
                    # do).
 
538
                    # 10038 = WSAENOTSOCK
 
539
                    # http://msdn.microsoft.com/en-us/library/ms740668%28VS.85%29.aspx
 
540
                    pass
 
541
                else:
 
542
                    raise
504
543
 
505
544
    def _get_remote_url(self, path):
506
545
        path_parts = path.split(os.path.sep)
518
557
        """Capture Server log output."""
519
558
        self.logs.append(format % args)
520
559
 
521
 
    def setUp(self, backing_transport_server=None):
522
 
        """See bzrlib.transport.Server.setUp.
 
560
    def start_server(self, backing_transport_server=None):
 
561
        """See bzrlib.transport.Server.start_server.
523
562
 
524
563
        :param backing_transport_server: The transport that requests over this
525
564
            protocol should be forwarded to. Note that this is currently not
527
566
        """
528
567
        # XXX: TODO: make the server back onto vfs_server rather than local
529
568
        # disk.
530
 
        if not (backing_transport_server is None or \
531
 
                isinstance(backing_transport_server, local.LocalURLServer)):
 
569
        if not (backing_transport_server is None
 
570
                or isinstance(backing_transport_server,
 
571
                              test_server.LocalURLServer)):
532
572
            raise AssertionError(
533
573
                "HTTPServer currently assumes local transport, got %s" % \
534
574
                backing_transport_server)
554
594
        self._http_starting.release()
555
595
        self.logs = []
556
596
 
557
 
    def tearDown(self):
558
 
        """See bzrlib.transport.Server.tearDown."""
559
 
        self._httpd.tearDown()
 
597
    def stop_server(self):
 
598
        self._httpd.stop_server()
560
599
        self._http_running = False
561
600
        # We don't need to 'self._http_thread.join()' here since the thread is
562
601
        # a daemonic one and will be garbage collected anyway. Joining just