/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/http_server.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-12-12 01:24:50 UTC
  • mfrom: (3882.4.2 doc-hacking)
  • Revision ID: pqm@pqm.ubuntu.com-20081212012450-3gw576prpztxziib
(mbp) Developer documentation about when to add new exception classes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006, 2007 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import errno
18
18
import httplib
31
31
import urlparse
32
32
 
33
33
from bzrlib import transport
34
 
from bzrlib.tests import test_server
35
34
from bzrlib.transport import local
36
35
 
37
36
 
 
37
class WebserverNotAvailable(Exception):
 
38
    pass
 
39
 
 
40
 
38
41
class BadWebserverPath(ValueError):
39
42
    def __str__(self):
40
43
        return 'path %s is not in %s' % self.args
138
141
            # common)
139
142
            self.send_response(301)
140
143
            self.send_header("Location", self.path + "/")
141
 
            # Indicates that the body is empty for HTTP/1.1 clients
 
144
            # Indicates that the body is empty for HTTP/1.1 clients 
142
145
            self.send_header('Content-Length', '0')
143
146
            self.end_headers()
144
147
            return None
178
181
            content_length += self._header_line_length(
179
182
                'Content-Range', 'bytes %d-%d/%d' % (start, end, file_size))
180
183
            content_length += len('\r\n') # end headers
181
 
            content_length += end - start + 1
 
184
            content_length += end - start # + 1
182
185
        content_length += len(boundary_line)
183
186
        self.send_header('Content-length', content_length)
184
187
        self.end_headers()
319
322
        self.test_case_server = test_case_server
320
323
        self._home_dir = test_case_server._home_dir
321
324
 
322
 
    def stop_server(self):
 
325
    def tearDown(self):
323
326
         """Called to clean-up the server.
324
 
 
 
327
 
325
328
         Since the server may be (surely is, even) in a blocking listen, we
326
329
         shutdown its socket before closing it.
327
330
         """
348
351
             # 'Socket is not connected' can also occur on OSX, with a
349
352
             # "regular" ENOTCONN (when something went wrong during test case
350
353
             # setup leading to self.setUp() *not* being called but
351
 
             # self.stop_server() still being called -- vila20081106
 
354
             # self.tearDown() still being called -- vila20081106
352
355
             if not len(e.args) or e.args[0] not in (errno.ENOTCONN, 10057):
353
356
                 raise
354
357
         # Let the server properly close the socket
383
386
        # lying around.
384
387
        self.daemon_threads = True
385
388
 
386
 
    def process_request_thread(self, request, client_address):
387
 
        SocketServer.ThreadingTCPServer.process_request_thread(
388
 
            self, request, client_address)
389
 
        # Under some circumstances (as in bug #383920), we need to force the
390
 
        # shutdown as python delays it until gc occur otherwise and the client
391
 
        # may hang.
392
 
        try:
393
 
            # The request process has been completed, the thread is about to
394
 
            # die, let's shutdown the socket if we can.
395
 
            request.shutdown(socket.SHUT_RDWR)
396
 
        except (socket.error, select.error), e:
397
 
            if e[0] in (errno.EBADF, errno.ENOTCONN):
398
 
                # Right, the socket is already down
399
 
                pass
400
 
            else:
401
 
                raise
402
 
 
403
389
 
404
390
class HttpServer(transport.Server):
405
391
    """A test server for http transports.
438
424
        # Allows tests to verify number of GET requests issued
439
425
        self.GET_request_nb = 0
440
426
 
441
 
    def create_httpd(self, serv_cls, rhandler_cls):
442
 
        return serv_cls((self.host, self.port), self.request_handler, self)
443
 
 
444
427
    def __repr__(self):
445
428
        return "%s(%s:%s)" % \
446
429
            (self.__class__.__name__, self.host, self.port)
462
445
            if serv_cls is None:
463
446
                raise httplib.UnknownProtocol(proto_vers)
464
447
            else:
465
 
                self._httpd = self.create_httpd(serv_cls, rhandler)
466
 
            self.host, self.port = self._httpd.socket.getsockname()
 
448
                self._httpd = serv_cls((self.host, self.port), rhandler, self)
 
449
            host, self.port = self._httpd.socket.getsockname()
467
450
        return self._httpd
468
451
 
469
452
    def _http_start(self):
495
478
            except socket.timeout:
496
479
                pass
497
480
            except (socket.error, select.error), e:
498
 
                if (e[0] == errno.EBADF
499
 
                    or (sys.platform == 'win32' and e[0] == 10038)):
500
 
                    # Starting with python-2.6, handle_request may raise socket
501
 
                    # or select exceptions when the server is shut down (as we
502
 
                    # do).
503
 
                    # 10038 = WSAENOTSOCK
504
 
                    # http://msdn.microsoft.com/en-us/library/ms740668%28VS.85%29.aspx
505
 
                    pass
506
 
                else:
507
 
                    raise
 
481
               if e[0] == errno.EBADF:
 
482
                   # Starting with python-2.6, handle_request may raise socket
 
483
                   # or select exceptions when the server is shut down (as we
 
484
                   # do).
 
485
                   pass
 
486
               else:
 
487
                   raise
508
488
 
509
489
    def _get_remote_url(self, path):
510
490
        path_parts = path.split(os.path.sep)
522
502
        """Capture Server log output."""
523
503
        self.logs.append(format % args)
524
504
 
525
 
    def start_server(self, backing_transport_server=None):
526
 
        """See bzrlib.transport.Server.start_server.
527
 
 
 
505
    def setUp(self, backing_transport_server=None):
 
506
        """See bzrlib.transport.Server.setUp.
 
507
        
528
508
        :param backing_transport_server: The transport that requests over this
529
509
            protocol should be forwarded to. Note that this is currently not
530
510
            supported for HTTP.
531
511
        """
532
512
        # XXX: TODO: make the server back onto vfs_server rather than local
533
513
        # disk.
534
 
        if not (backing_transport_server is None
535
 
                or isinstance(backing_transport_server,
536
 
                              test_server.LocalURLServer)):
 
514
        if not (backing_transport_server is None or \
 
515
                isinstance(backing_transport_server, local.LocalURLServer)):
537
516
            raise AssertionError(
538
517
                "HTTPServer currently assumes local transport, got %s" % \
539
518
                backing_transport_server)
559
538
        self._http_starting.release()
560
539
        self.logs = []
561
540
 
562
 
    def stop_server(self):
563
 
        self._httpd.stop_server()
 
541
    def tearDown(self):
 
542
        """See bzrlib.transport.Server.tearDown."""
 
543
        self._httpd.tearDown()
564
544
        self._http_running = False
565
545
        # We don't need to 'self._http_thread.join()' here since the thread is
566
546
        # a daemonic one and will be garbage collected anyway. Joining just