~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2007-2011 Canonical Ltd
2929.3.10 by Vincent Ladeuil
Add a fake https server and test facilities.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2929.3.10 by Vincent Ladeuil
Add a fake https server and test facilities.
16
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
17
"""HTTPS test server, available when ssl python module is available"""
18
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
19
import ssl
5560.1.1 by Vincent Ladeuil
Catch the bogus ssl exception for closed sockets.
20
import sys
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
21
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
22
from bzrlib.tests import (
23
    http_server,
24
    ssl_certs,
5247.3.16 by Vincent Ladeuil
All http tests passing (including https).
25
    test_server,
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
26
    )
27
2929.3.10 by Vincent Ladeuil
Add a fake https server and test facilities.
28
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
29
class TestingHTTPSServerMixin:
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
30
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
31
    def __init__(self, key_file, cert_file):
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
32
        self.key_file = key_file
33
        self.cert_file = cert_file
34
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
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 !
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
48
        """
5247.3.16 by Vincent Ladeuil
All http tests passing (including https).
49
        serving = test_server.TestingTCPServerMixin.verify_request(
50
            self, request, client_address)
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
51
        if serving:
6238.2.21 by Vincent Ladeuil
The https test server will now refuse connections if an ssl error occurs during the handshake. Ssl errors and certificate errors aborts requests without re-trying them.
52
            try:
53
                request.do_handshake()
54
            except ssl.SSLError, e:
55
                # FIXME: We proabaly want more tests to capture which ssl
56
                # errors are worth reporting but mostly our tests want an https
57
                # server that works -- vila 2012-01-19
58
                return False
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
59
        return serving
2929.3.27 by Vincent Ladeuil
Fixed as per Ian's review.
60
5560.1.1 by Vincent Ladeuil
Catch the bogus ssl exception for closed sockets.
61
    def ignored_exceptions_during_shutdown(self, e):
62
        if (sys.version < (2, 7) and isinstance(e, TypeError)
63
            and e.args[0] == "'member_descriptor' object is not callable"):
64
            # Fixed in python-2.7 (and some Ubuntu 2.6) there is a bug where
65
            # the ssl socket fail to raise a socket.error when trying to read
66
            # from a closed socket. This is rarely observed in practice but
67
            # still make valid selftest runs fail if not caught.
68
            return True
69
        base = test_server.TestingTCPServerMixin
70
        return base.ignored_exceptions_during_shutdown(self, e)
71
5247.3.16 by Vincent Ladeuil
All http tests passing (including https).
72
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
73
class TestingHTTPSServer(TestingHTTPSServerMixin,
74
                         http_server.TestingHTTPServer):
75
76
    def __init__(self, server_address, request_handler_class,
77
                 test_case_server, key_file, cert_file):
78
        TestingHTTPSServerMixin.__init__(self, key_file, cert_file)
79
        http_server.TestingHTTPServer.__init__(
80
            self, server_address, request_handler_class, test_case_server)
81
5247.6.9 by Vincent Ladeuil
Fix vicious spurious spaces.
82
    def get_request(self):
5247.3.16 by Vincent Ladeuil
All http tests passing (including https).
83
        sock, addr = http_server.TestingHTTPServer.get_request(self)
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
84
        return self._get_ssl_request(sock, addr)
85
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
86
87
class TestingThreadingHTTPSServer(TestingHTTPSServerMixin,
88
                                  http_server.TestingThreadingHTTPServer):
89
90
    def __init__(self, server_address, request_handler_class,
91
                 test_case_server, key_file, cert_file):
92
        TestingHTTPSServerMixin.__init__(self, key_file, cert_file)
93
        http_server.TestingThreadingHTTPServer.__init__(
94
            self, server_address, request_handler_class, test_case_server)
95
5247.6.9 by Vincent Ladeuil
Fix vicious spurious spaces.
96
    def get_request(self):
5247.3.16 by Vincent Ladeuil
All http tests passing (including https).
97
        sock, addr = http_server.TestingThreadingHTTPServer.get_request(self)
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
98
        return self._get_ssl_request(sock, addr)
99
2929.3.10 by Vincent Ladeuil
Add a fake https server and test facilities.
100
101
class HTTPSServer(http_server.HttpServer):
102
103
    _url_protocol = 'https'
104
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
105
    # The real servers depending on the protocol
106
    http_server_class = {'HTTP/1.0': TestingHTTPSServer,
107
                         'HTTP/1.1': TestingThreadingHTTPSServer,
108
                         }
109
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
110
    # Provides usable defaults since an https server requires both a
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
111
    # private key and a certificate to work.
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
112
    def __init__(self, request_handler=http_server.TestingHTTPRequestHandler,
3945.1.7 by Vincent Ladeuil
Test against https.
113
                 protocol_version=None,
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
114
                 key_file=ssl_certs.build_path('server_without_pass.key'),
115
                 cert_file=ssl_certs.build_path('server.crt')):
3945.1.7 by Vincent Ladeuil
Test against https.
116
        http_server.HttpServer.__init__(self, request_handler=request_handler,
117
                                        protocol_version=protocol_version)
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
118
        self.key_file = key_file
119
        self.cert_file = cert_file
120
        self.temp_files = []
121
5247.3.16 by Vincent Ladeuil
All http tests passing (including https).
122
    def create_server(self):
123
        return self.server_class(
124
            (self.host, self.port), self.request_handler_class, self,
125
            self.key_file, self.cert_file)
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
126
2929.3.10 by Vincent Ladeuil
Add a fake https server and test facilities.
127
128
class HTTPSServer_urllib(HTTPSServer):
129
    """Subclass of HTTPSServer that gives https+urllib urls.
130
131
    This is for use in testing: connections to this server will always go
132
    through urllib where possible.
133
    """
134
135
    # urls returned by this server should require the urllib client impl
136
    _url_protocol = 'https+urllib'
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
137
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
138
139
class HTTPSServer_PyCurl(HTTPSServer):
140
    """Subclass of HTTPSServer that gives http+pycurl urls.
141
142
    This is for use in testing: connections to this server will always go
143
    through pycurl where possible.
144
    """
145
146
    # We don't care about checking the pycurl availability as
147
    # this server will be required only when pycurl is present
148
149
    # urls returned by this server should require the pycurl client impl
150
    _url_protocol = 'https+pycurl'