~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/http_server.py

  • Committer: John Arbash Meinel
  • Date: 2008-09-09 15:09:12 UTC
  • mto: This revision was merged to the branch mainline in revision 3699.
  • Revision ID: john@arbash-meinel.com-20080909150912-wyttm8he1zsls2ck
Use the right timing function on win32

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., 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
20
20
import posixpath
21
21
import random
22
22
import re
23
 
import select
24
23
import SimpleHTTPServer
25
24
import socket
26
25
import SocketServer
34
33
from bzrlib.transport import local
35
34
 
36
35
 
 
36
class WebserverNotAvailable(Exception):
 
37
    pass
 
38
 
 
39
 
37
40
class BadWebserverPath(ValueError):
38
41
    def __str__(self):
39
42
        return 'path %s is not in %s' % self.args
137
140
            # common)
138
141
            self.send_response(301)
139
142
            self.send_header("Location", self.path + "/")
140
 
            # Indicates that the body is empty for HTTP/1.1 clients
 
143
            # Indicates that the body is empty for HTTP/1.1 clients 
141
144
            self.send_header('Content-Length', '0')
142
145
            self.end_headers()
143
146
            return None
177
180
            content_length += self._header_line_length(
178
181
                'Content-Range', 'bytes %d-%d/%d' % (start, end, file_size))
179
182
            content_length += len('\r\n') # end headers
180
 
            content_length += end - start + 1
 
183
            content_length += end - start # + 1
181
184
        content_length += len(boundary_line)
182
185
        self.send_header('Content-length', content_length)
183
186
        self.end_headers()
318
321
        self.test_case_server = test_case_server
319
322
        self._home_dir = test_case_server._home_dir
320
323
 
321
 
    def stop_server(self):
 
324
    def tearDown(self):
322
325
         """Called to clean-up the server.
323
 
 
 
326
 
324
327
         Since the server may be (surely is, even) in a blocking listen, we
325
328
         shutdown its socket before closing it.
326
329
         """
343
346
             # WSAENOTCONN (10057) 'Socket is not connected' is harmless on
344
347
             # windows (occurs before the first connection attempt
345
348
             # vila--20071230)
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.stop_server() still being called -- vila20081106
351
 
             if not len(e.args) or e.args[0] not in (errno.ENOTCONN, 10057):
 
349
             if not len(e.args) or e.args[0] != 10057:
352
350
                 raise
353
351
         # Let the server properly close the socket
354
352
         self.server_close()
382
380
        # lying around.
383
381
        self.daemon_threads = True
384
382
 
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
 
 
402
383
 
403
384
class HttpServer(transport.Server):
404
385
    """A test server for http transports.
437
418
        # Allows tests to verify number of GET requests issued
438
419
        self.GET_request_nb = 0
439
420
 
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
 
 
447
421
    def _get_httpd(self):
448
422
        if self._httpd is None:
449
423
            rhandler = self.request_handler
461
435
            if serv_cls is None:
462
436
                raise httplib.UnknownProtocol(proto_vers)
463
437
            else:
464
 
                self._httpd = self.create_httpd(serv_cls, rhandler)
465
 
            self.host, self.port = self._httpd.socket.getsockname()
 
438
                self._httpd = serv_cls((self.host, self.port), rhandler, self)
 
439
            host, self.port = self._httpd.socket.getsockname()
466
440
        return self._httpd
467
441
 
468
442
    def _http_start(self):
493
467
                httpd.handle_request()
494
468
            except socket.timeout:
495
469
                pass
496
 
            except (socket.error, select.error), e:
497
 
                if (e[0] == errno.EBADF
498
 
                    or (sys.platform == 'win32' and e[0] == 10038)):
499
 
                    # Starting with python-2.6, handle_request may raise socket
500
 
                    # or select exceptions when the server is shut down (as we
501
 
                    # do).
502
 
                    # 10038 = WSAENOTSOCK
503
 
                    # http://msdn.microsoft.com/en-us/library/ms740668%28VS.85%29.aspx
504
 
                    pass
505
 
                else:
506
 
                    raise
507
470
 
508
471
    def _get_remote_url(self, path):
509
472
        path_parts = path.split(os.path.sep)
521
484
        """Capture Server log output."""
522
485
        self.logs.append(format % args)
523
486
 
524
 
    def start_server(self, backing_transport_server=None):
525
 
        """See bzrlib.transport.Server.start_server.
526
 
 
 
487
    def setUp(self, backing_transport_server=None):
 
488
        """See bzrlib.transport.Server.setUp.
 
489
        
527
490
        :param backing_transport_server: The transport that requests over this
528
491
            protocol should be forwarded to. Note that this is currently not
529
492
            supported for HTTP.
557
520
        self._http_starting.release()
558
521
        self.logs = []
559
522
 
560
 
    def stop_server(self):
561
 
        self._httpd.stop_server()
 
523
    def tearDown(self):
 
524
        """See bzrlib.transport.Server.tearDown."""
 
525
        self._httpd.tearDown()
562
526
        self._http_running = False
563
527
        # We don't need to 'self._http_thread.join()' here since the thread is
564
528
        # a daemonic one and will be garbage collected anyway. Joining just