/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/https_server.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007-2011 Canonical Ltd
 
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""HTTPS test server, available when ssl python module is available"""
 
18
 
 
19
import ssl
 
20
import sys
 
21
 
 
22
from bzrlib.tests import (
 
23
    http_server,
 
24
    ssl_certs,
 
25
    test_server,
 
26
    )
 
27
 
 
28
 
 
29
class TestingHTTPSServerMixin:
 
30
 
 
31
    def __init__(self, key_file, cert_file):
 
32
        self.key_file = key_file
 
33
        self.cert_file = cert_file
 
34
 
 
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 !
 
48
        """
 
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)
 
65
 
 
66
 
 
67
class TestingHTTPSServer(TestingHTTPSServerMixin,
 
68
                         http_server.TestingHTTPServer):
 
69
 
 
70
    def __init__(self, server_address, request_handler_class,
 
71
                 test_case_server, key_file, cert_file):
 
72
        TestingHTTPSServerMixin.__init__(self, key_file, cert_file)
 
73
        http_server.TestingHTTPServer.__init__(
 
74
            self, server_address, request_handler_class, test_case_server)
 
75
 
 
76
    def get_request(self):
 
77
        sock, addr = http_server.TestingHTTPServer.get_request(self)
 
78
        return self._get_ssl_request(sock, addr)
 
79
 
 
80
 
 
81
class TestingThreadingHTTPSServer(TestingHTTPSServerMixin,
 
82
                                  http_server.TestingThreadingHTTPServer):
 
83
 
 
84
    def __init__(self, server_address, request_handler_class,
 
85
                 test_case_server, key_file, cert_file):
 
86
        TestingHTTPSServerMixin.__init__(self, key_file, cert_file)
 
87
        http_server.TestingThreadingHTTPServer.__init__(
 
88
            self, server_address, request_handler_class, test_case_server)
 
89
 
 
90
    def get_request(self):
 
91
        sock, addr = http_server.TestingThreadingHTTPServer.get_request(self)
 
92
        return self._get_ssl_request(sock, addr)
 
93
 
 
94
 
 
95
class HTTPSServer(http_server.HttpServer):
 
96
 
 
97
    _url_protocol = 'https'
 
98
 
 
99
    # The real servers depending on the protocol
 
100
    http_server_class = {'HTTP/1.0': TestingHTTPSServer,
 
101
                         'HTTP/1.1': TestingThreadingHTTPSServer,
 
102
                         }
 
103
 
 
104
    # Provides usable defaults since an https server requires both a
 
105
    # private key and a certificate to work.
 
106
    def __init__(self, request_handler=http_server.TestingHTTPRequestHandler,
 
107
                 protocol_version=None,
 
108
                 key_file=ssl_certs.build_path('server_without_pass.key'),
 
109
                 cert_file=ssl_certs.build_path('server.crt')):
 
110
        http_server.HttpServer.__init__(self, request_handler=request_handler,
 
111
                                        protocol_version=protocol_version)
 
112
        self.key_file = key_file
 
113
        self.cert_file = cert_file
 
114
        self.temp_files = []
 
115
 
 
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)
 
120
 
 
121
 
 
122
class HTTPSServer_urllib(HTTPSServer):
 
123
    """Subclass of HTTPSServer that gives https+urllib urls.
 
124
 
 
125
    This is for use in testing: connections to this server will always go
 
126
    through urllib where possible.
 
127
    """
 
128
 
 
129
    # urls returned by this server should require the urllib client impl
 
130
    _url_protocol = 'https+urllib'
 
131
 
 
132
 
 
133
class HTTPSServer_PyCurl(HTTPSServer):
 
134
    """Subclass of HTTPSServer that gives http+pycurl urls.
 
135
 
 
136
    This is for use in testing: connections to this server will always go
 
137
    through pycurl where possible.
 
138
    """
 
139
 
 
140
    # We don't care about checking the pycurl availability as
 
141
    # this server will be required only when pycurl is present
 
142
 
 
143
    # urls returned by this server should require the pycurl client impl
 
144
    _url_protocol = 'https+pycurl'