~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/https_server.py

(jameinel) Allow 'bzr serve' to interpret SIGHUP as a graceful shutdown.
 (bug #795025) (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
 
1
# Copyright (C) 2007-2011 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., 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
"""HTTPS test server, available when ssl python module is available"""
18
18
 
19
19
import ssl
 
20
import sys
20
21
 
21
22
from bzrlib.tests import (
22
23
    http_server,
23
24
    ssl_certs,
 
25
    test_server,
24
26
    )
25
27
 
26
28
 
30
32
        self.key_file = key_file
31
33
        self.cert_file = cert_file
32
34
 
33
 
    def get_request (self):
34
 
        """Get the request and client address from the socket.
35
 
 
36
 
        This is called in response to a connection issued to the server, we
37
 
        wrap the socket with SSL.
 
35
    def _get_ssl_request (self, sock, addr):
 
36
        """Wrap the socket with SSL"""
 
37
        ssl_sock = ssl.wrap_socket(sock, server_side=True,
 
38
                                   keyfile=self.key_file,
 
39
                                   certfile=self.cert_file,
 
40
                                   do_handshake_on_connect=False)
 
41
        return ssl_sock, addr
 
42
 
 
43
    def verify_request(self, request, client_address):
 
44
        """Verify the request.
 
45
 
 
46
        Return True if we should proceed with this request, False if we should
 
47
        not even touch a single byte in the socket !
38
48
        """
39
 
        sock, addr = self.socket.accept()
40
 
        sslconn = ssl.wrap_socket(sock, server_side=True,
41
 
                                  keyfile=self.key_file,
42
 
                                  certfile=self.cert_file)
43
 
        return sslconn, addr
 
49
        serving = test_server.TestingTCPServerMixin.verify_request(
 
50
            self, request, client_address)
 
51
        if serving:
 
52
            request.do_handshake()
 
53
        return serving
 
54
 
 
55
    def ignored_exceptions_during_shutdown(self, e):
 
56
        if (sys.version < (2, 7) and isinstance(e, TypeError)
 
57
            and e.args[0] == "'member_descriptor' object is not callable"):
 
58
            # Fixed in python-2.7 (and some Ubuntu 2.6) there is a bug where
 
59
            # the ssl socket fail to raise a socket.error when trying to read
 
60
            # from a closed socket. This is rarely observed in practice but
 
61
            # still make valid selftest runs fail if not caught.
 
62
            return True
 
63
        base = test_server.TestingTCPServerMixin
 
64
        return base.ignored_exceptions_during_shutdown(self, e)
44
65
 
45
66
 
46
67
class TestingHTTPSServer(TestingHTTPSServerMixin,
52
73
        http_server.TestingHTTPServer.__init__(
53
74
            self, server_address, request_handler_class, test_case_server)
54
75
 
 
76
    def get_request(self):
 
77
        sock, addr = http_server.TestingHTTPServer.get_request(self)
 
78
        return self._get_ssl_request(sock, addr)
 
79
 
55
80
 
56
81
class TestingThreadingHTTPSServer(TestingHTTPSServerMixin,
57
82
                                  http_server.TestingThreadingHTTPServer):
62
87
        http_server.TestingThreadingHTTPServer.__init__(
63
88
            self, server_address, request_handler_class, test_case_server)
64
89
 
 
90
    def get_request(self):
 
91
        sock, addr = http_server.TestingThreadingHTTPServer.get_request(self)
 
92
        return self._get_ssl_request(sock, addr)
 
93
 
65
94
 
66
95
class HTTPSServer(http_server.HttpServer):
67
96
 
73
102
                         }
74
103
 
75
104
    # Provides usable defaults since an https server requires both a
76
 
    # private key and certificate to work.
 
105
    # private key and a certificate to work.
77
106
    def __init__(self, request_handler=http_server.TestingHTTPRequestHandler,
78
107
                 protocol_version=None,
79
108
                 key_file=ssl_certs.build_path('server_without_pass.key'),
84
113
        self.cert_file = cert_file
85
114
        self.temp_files = []
86
115
 
87
 
    def create_httpd(self, serv_cls, rhandler_cls):
88
 
        return serv_cls((self.host, self.port), self.request_handler,
89
 
                        self, self.key_file, self.cert_file)
 
116
    def create_server(self):
 
117
        return self.server_class(
 
118
            (self.host, self.port), self.request_handler_class, self,
 
119
            self.key_file, self.cert_file)
90
120
 
91
121
 
92
122
class HTTPSServer_urllib(HTTPSServer):