~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/http_server.py

  • Committer: John Ferlito
  • Date: 2009-09-02 04:31:45 UTC
  • mto: (4665.7.1 serve-init)
  • mto: This revision was merged to the branch mainline in revision 4913.
  • Revision ID: johnf@inodes.org-20090902043145-gxdsfw03ilcwbyn5
Add a debian init script for bzr --serve

Show diffs side-by-side

added added

removed removed

Lines of Context:
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
import errno
18
18
import httplib
20
20
import posixpath
21
21
import random
22
22
import re
 
23
import select
23
24
import SimpleHTTPServer
24
25
import socket
25
26
import SocketServer
33
34
from bzrlib.transport import local
34
35
 
35
36
 
36
 
class WebserverNotAvailable(Exception):
37
 
    pass
38
 
 
39
 
 
40
37
class BadWebserverPath(ValueError):
41
38
    def __str__(self):
42
39
        return 'path %s is not in %s' % self.args
140
137
            # common)
141
138
            self.send_response(301)
142
139
            self.send_header("Location", self.path + "/")
143
 
            # Indicates that the body is empty for HTTP/1.1 clients 
 
140
            # Indicates that the body is empty for HTTP/1.1 clients
144
141
            self.send_header('Content-Length', '0')
145
142
            self.end_headers()
146
143
            return None
180
177
            content_length += self._header_line_length(
181
178
                'Content-Range', 'bytes %d-%d/%d' % (start, end, file_size))
182
179
            content_length += len('\r\n') # end headers
183
 
            content_length += end - start # + 1
 
180
            content_length += end - start + 1
184
181
        content_length += len(boundary_line)
185
182
        self.send_header('Content-length', content_length)
186
183
        self.end_headers()
323
320
 
324
321
    def tearDown(self):
325
322
         """Called to clean-up the server.
326
 
 
 
323
 
327
324
         Since the server may be (surely is, even) in a blocking listen, we
328
325
         shutdown its socket before closing it.
329
326
         """
346
343
             # WSAENOTCONN (10057) 'Socket is not connected' is harmless on
347
344
             # windows (occurs before the first connection attempt
348
345
             # vila--20071230)
349
 
             if not len(e.args) or e.args[0] != 10057:
 
346
 
 
347
             # 'Socket is not connected' can also occur on OSX, with a
 
348
             # "regular" ENOTCONN (when something went wrong during test case
 
349
             # setup leading to self.setUp() *not* being called but
 
350
             # self.tearDown() still being called -- vila20081106
 
351
             if not len(e.args) or e.args[0] not in (errno.ENOTCONN, 10057):
350
352
                 raise
351
353
         # Let the server properly close the socket
352
354
         self.server_close()
380
382
        # lying around.
381
383
        self.daemon_threads = True
382
384
 
 
385
    def process_request_thread(self, request, client_address):
 
386
        SocketServer.ThreadingTCPServer.process_request_thread(
 
387
            self, request, client_address)
 
388
        # Under some circumstances (as in bug #383920), we need to force the
 
389
        # shutdown as python delays it until gc occur otherwise and the client
 
390
        # may hang.
 
391
        try:
 
392
            # The request process has been completed, the thread is about to
 
393
            # die, let's shutdown the socket if we can.
 
394
            request.shutdown(socket.SHUT_RDWR)
 
395
        except (socket.error, select.error), e:
 
396
            if e[0] in (errno.EBADF, errno.ENOTCONN):
 
397
                # Right, the socket is already down
 
398
                pass
 
399
            else:
 
400
                raise
 
401
 
383
402
 
384
403
class HttpServer(transport.Server):
385
404
    """A test server for http transports.
418
437
        # Allows tests to verify number of GET requests issued
419
438
        self.GET_request_nb = 0
420
439
 
 
440
    def create_httpd(self, serv_cls, rhandler_cls):
 
441
        return serv_cls((self.host, self.port), self.request_handler, self)
 
442
 
 
443
    def __repr__(self):
 
444
        return "%s(%s:%s)" % \
 
445
            (self.__class__.__name__, self.host, self.port)
 
446
 
421
447
    def _get_httpd(self):
422
448
        if self._httpd is None:
423
449
            rhandler = self.request_handler
435
461
            if serv_cls is None:
436
462
                raise httplib.UnknownProtocol(proto_vers)
437
463
            else:
438
 
                self._httpd = serv_cls((self.host, self.port), rhandler, self)
 
464
                self._httpd = self.create_httpd(serv_cls, rhandler)
439
465
            host, self.port = self._httpd.socket.getsockname()
440
466
        return self._httpd
441
467
 
467
493
                httpd.handle_request()
468
494
            except socket.timeout:
469
495
                pass
 
496
            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
470
504
 
471
505
    def _get_remote_url(self, path):
472
506
        path_parts = path.split(os.path.sep)
486
520
 
487
521
    def setUp(self, backing_transport_server=None):
488
522
        """See bzrlib.transport.Server.setUp.
489
 
        
 
523
 
490
524
        :param backing_transport_server: The transport that requests over this
491
525
            protocol should be forwarded to. Note that this is currently not
492
526
            supported for HTTP.