~bzr-pqm/bzr/bzr.dev

2018.5.157 by Andrew Bennetts
Remove unnecessary trivial divergences from bzr.dev.
1
# Copyright (C) 2006, 2007 Canonical Ltd
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
17
"""Basic server-side logic for dealing with requests."""
18
19
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
20
import tempfile
21
2402.1.2 by Andrew Bennetts
Deal with review comments.
22
from bzrlib import (
23
    bzrdir,
24
    errors,
25
    registry,
26
    revision,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
27
    urlutils,
2402.1.2 by Andrew Bennetts
Deal with review comments.
28
    )
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
29
from bzrlib.bundle.serializer import write_bundle
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
30
from bzrlib.transport import get_transport
31
from bzrlib.transport.chroot import ChrootServer
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
32
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
33
34
class SmartServerRequest(object):
2692.1.10 by Andrew Bennetts
More docstring polish
35
    """Base class for request handlers.
36
    
37
    To define a new request, subclass this class and override the `do` method
38
    (and if appropriate, `do_body` as well).  Request implementors should take
39
    care to call `translate_client_path` and `transport_from_client_path` as
40
    appropriate when dealing with paths received from the client.
41
    """
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
42
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
43
    def __init__(self, backing_transport, root_client_path='/'):
2402.1.2 by Andrew Bennetts
Deal with review comments.
44
        """Constructor.
45
46
        :param backing_transport: the base transport to be used when performing
47
            this request.
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
48
        :param root_client_path: the client path that maps to the root of
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
49
            backing_transport.  This is used to interpret relpaths received
50
            from the client.  Clients will not be able to refer to paths above
2692.1.16 by Andrew Bennetts
Improve comments.
51
            this root.  If root_client_path is None, then no translation will
52
            be performed on client paths.  Default is '/'.
2402.1.2 by Andrew Bennetts
Deal with review comments.
53
        """
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
54
        self._backing_transport = backing_transport
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
55
        if root_client_path is not None:
56
            if not root_client_path.startswith('/'):
57
                root_client_path = '/' + root_client_path
58
            if not root_client_path.endswith('/'):
59
                root_client_path += '/'
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
60
        self._root_client_path = root_client_path
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
61
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
62
    def _check_enabled(self):
63
        """Raises DisabledMethod if this method is disabled."""
64
        pass
65
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
66
    def do(self, *args):
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
67
        """Mandatory extension point for SmartServerRequest subclasses.
68
        
69
        Subclasses must implement this.
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
70
        
71
        This should return a SmartServerResponse if this command expects to
72
        receive no body.
73
        """
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
74
        raise NotImplementedError(self.do)
75
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
76
    def execute(self, *args):
77
        """Public entry point to execute this request.
78
79
        It will return a SmartServerResponse if the command does not expect a
80
        body.
81
82
        :param *args: the arguments of the request.
83
        """
84
        self._check_enabled()
85
        return self.do(*args)
86
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
87
    def do_body(self, body_bytes):
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
88
        """Called if the client sends a body with the request.
3184.1.10 by Robert Collins
Change the smart server verb for Repository.stream_revisions_chunked to use SearchResults as the request mechanism for downloads.
89
90
        The do() method is still called, and must have returned None.
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
91
        
92
        Must return a SmartServerResponse.
93
        """
94
        # TODO: if a client erroneously sends a request that shouldn't have a
95
        # body, what to do?  Probably SmartServerRequestHandler should catch
96
        # this NotImplementedError and translate it into a 'bad request' error
97
        # to send to the client.
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
98
        raise NotImplementedError(self.do_body)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
99
    
100
    def translate_client_path(self, client_path):
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
101
        """Translate a path received from a network client into a local
102
        relpath.
103
104
        All paths received from the client *must* be translated.
105
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
106
        :param client_path: the path from the client.
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
107
        :returns: a relpath that may be used with self._backing_transport
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
108
            (unlike the untranslated client_path, which must not be used with
109
            the backing transport).
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
110
        """
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
111
        if self._root_client_path is None:
112
            # no translation necessary!
113
            return client_path
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
114
        if not client_path.startswith('/'):
115
            client_path = '/' + client_path
116
        if client_path.startswith(self._root_client_path):
117
            path = client_path[len(self._root_client_path):]
118
            relpath = urlutils.joinpath('/', path)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
119
            if not relpath.startswith('/'):
120
                raise ValueError(relpath)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
121
            return '.' + relpath
122
        else:
123
            raise errors.PathNotChild(client_path, self._root_client_path)
124
125
    def transport_from_client_path(self, client_path):
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
126
        """Get a backing transport corresponding to the location referred to by
127
        a network client.
128
129
        :seealso: translate_client_path
130
        :returns: a transport cloned from self._backing_transport
131
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
132
        relpath = self.translate_client_path(client_path)
2692.1.16 by Andrew Bennetts
Improve comments.
133
        return self._backing_transport.clone(relpath)
2018.5.4 by Andrew Bennetts
Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler.
134
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
135
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
136
class SmartServerResponse(object):
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
137
    """A response to a client request.
138
    
139
    This base class should not be used. Instead use
140
    SuccessfulSmartServerResponse and FailedSmartServerResponse as appropriate.
141
    """
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
142
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
143
    def __init__(self, args, body=None, body_stream=None):
144
        """Constructor.
145
146
        :param args: tuple of response arguments.
147
        :param body: string of a response body.
148
        :param body_stream: iterable of bytestrings to be streamed to the
149
            client.
150
        """
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
151
        self.args = args
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
152
        if body is not None and body_stream is not None:
153
            raise errors.BzrError(
154
                "'body' and 'body_stream' are mutually exclusive.")
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
155
        self.body = body
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
156
        self.body_stream = body_stream
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
157
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
158
    def __eq__(self, other):
159
        if other is None:
160
            return False
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
161
        return (other.args == self.args and
162
                other.body == self.body and
163
                other.body_stream is self.body_stream)
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
164
165
    def __repr__(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
166
        status = {True: 'OK', False: 'ERR'}[self.is_successful()]
167
        return "<SmartServerResponse status=%s args=%r body=%r>" % (status,
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
168
            self.args, self.body)
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
169
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
170
2432.4.2 by Robert Collins
Add FailedSmartServerResponse.
171
class FailedSmartServerResponse(SmartServerResponse):
172
    """A SmartServerResponse for a request which failed."""
173
174
    def is_successful(self):
175
        """FailedSmartServerResponse are not successful."""
176
        return False
177
178
2432.4.1 by Robert Collins
Add SuccessfulSmartServerResponse.
179
class SuccessfulSmartServerResponse(SmartServerResponse):
180
    """A SmartServerResponse for a successfully completed request."""
181
182
    def is_successful(self):
183
        """SuccessfulSmartServerResponse are successful."""
184
        return True
185
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
186
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
187
class SmartServerRequestHandler(object):
188
    """Protocol logic for smart server.
189
    
190
    This doesn't handle serialization at all, it just processes requests and
191
    creates responses.
192
    """
193
194
    # IMPORTANT FOR IMPLEMENTORS: It is important that SmartServerRequestHandler
195
    # not contain encoding or decoding logic to allow the wire protocol to vary
196
    # from the object protocol: we will want to tweak the wire protocol separate
197
    # from the object model, and ideally we will be able to do that without
198
    # having a SmartServerRequestHandler subclass for each wire protocol, rather
199
    # just a Protocol subclass.
200
201
    # TODO: Better way of representing the body for commands that take it,
202
    # and allow it to be streamed into the server.
203
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
204
    def __init__(self, backing_transport, commands, root_client_path):
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
205
        """Constructor.
206
207
        :param backing_transport: a Transport to handle requests for.
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
208
        :param commands: a registry mapping command names to SmartServerRequest
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
209
            subclasses. e.g. bzrlib.transport.smart.vfs.vfs_commands.
210
        """
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
211
        self._backing_transport = backing_transport
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
212
        self._root_client_path = root_client_path
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
213
        self._commands = commands
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
214
        self._body_bytes = ''
215
        self.response = None
216
        self.finished_reading = False
217
        self._command = None
218
219
    def accept_body(self, bytes):
220
        """Accept body data."""
221
222
        # TODO: This should be overriden for each command that desired body data
223
        # to handle the right format of that data, i.e. plain bytes, a bundle,
224
        # etc.  The deserialisation into that format should be done in the
225
        # Protocol object.
226
227
        # default fallback is to accumulate bytes.
228
        self._body_bytes += bytes
229
        
230
    def end_of_body(self):
231
        """No more body data will be received."""
232
        self._run_handler_code(self._command.do_body, (self._body_bytes,), {})
233
        # cannot read after this.
234
        self.finished_reading = True
235
236
    def dispatch_command(self, cmd, args):
237
        """Deprecated compatibility method.""" # XXX XXX
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
238
        try:
239
            command = self._commands.get(cmd)
240
        except LookupError:
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
241
            raise errors.SmartProtocolError("bad request %r" % (cmd,))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
242
        self._command = command(self._backing_transport, self._root_client_path)
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
243
        self._run_handler_code(self._command.execute, args, {})
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
244
245
    def _run_handler_code(self, callable, args, kwargs):
246
        """Run some handler specific code 'callable'.
247
248
        If a result is returned, it is considered to be the commands response,
249
        and finished_reading is set true, and its assigned to self.response.
250
251
        Any exceptions caught are translated and a response object created
252
        from them.
253
        """
254
        result = self._call_converting_errors(callable, args, kwargs)
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
255
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
256
        if result is not None:
257
            self.response = result
258
            self.finished_reading = True
259
260
    def _call_converting_errors(self, callable, args, kwargs):
261
        """Call callable converting errors to Response objects."""
262
        # XXX: most of this error conversion is VFS-related, and thus ought to
263
        # be in SmartServerVFSRequestHandler somewhere.
264
        try:
265
            return callable(*args, **kwargs)
266
        except errors.NoSuchFile, e:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
267
            return FailedSmartServerResponse(('NoSuchFile', e.path))
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
268
        except errors.FileExists, e:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
269
            return FailedSmartServerResponse(('FileExists', e.path))
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
270
        except errors.DirectoryNotEmpty, e:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
271
            return FailedSmartServerResponse(('DirectoryNotEmpty', e.path))
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
272
        except errors.ShortReadvError, e:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
273
            return FailedSmartServerResponse(('ShortReadvError',
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
274
                e.path, str(e.offset), str(e.length), str(e.actual)))
275
        except UnicodeError, e:
276
            # If it is a DecodeError, than most likely we are starting
277
            # with a plain string
278
            str_or_unicode = e.object
279
            if isinstance(str_or_unicode, unicode):
280
                # XXX: UTF-8 might have \x01 (our seperator byte) in it.  We
281
                # should escape it somehow.
282
                val = 'u:' + str_or_unicode.encode('utf-8')
283
            else:
284
                val = 's:' + str_or_unicode.encode('base64')
285
            # This handles UnicodeEncodeError or UnicodeDecodeError
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
286
            return FailedSmartServerResponse((e.__class__.__name__,
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
287
                    e.encoding, val, str(e.start), str(e.end), e.reason))
288
        except errors.TransportNotPossible, e:
289
            if e.msg == "readonly transport":
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
290
                return FailedSmartServerResponse(('ReadOnlyError', ))
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
291
            else:
292
                raise
293
294
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
295
class HelloRequest(SmartServerRequest):
2432.2.6 by Andrew Bennetts
Improve HelloRequest's docstring.
296
    """Answer a version request with the highest protocol version this server
297
    supports.
298
    """
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
299
300
    def do(self):
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
301
        return SuccessfulSmartServerResponse(('ok', '2'))
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
302
303
304
class GetBundleRequest(SmartServerRequest):
2402.1.2 by Andrew Bennetts
Deal with review comments.
305
    """Get a bundle of from the null revision to the specified revision."""
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
306
307
    def do(self, path, revision_id):
308
        # open transport relative to our base
2692.1.7 by Andrew Bennetts
Translate path in GetBundleRequest too.
309
        t = self.transport_from_client_path(path)
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
310
        control, extra_path = bzrdir.BzrDir.open_containing_from_transport(t)
311
        repo = control.open_repository()
312
        tmpf = tempfile.TemporaryFile()
313
        base_revision = revision.NULL_REVISION
314
        write_bundle(repo, revision_id, base_revision, tmpf)
315
        tmpf.seek(0)
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
316
        return SuccessfulSmartServerResponse((), tmpf.read())
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
317
318
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
319
class SmartServerIsReadonly(SmartServerRequest):
320
    # XXX: this request method belongs somewhere else.
321
322
    def do(self):
323
        if self._backing_transport.is_readonly():
324
            answer = 'yes'
325
        else:
326
            answer = 'no'
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
327
        return SuccessfulSmartServerResponse((answer,))
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
328
329
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
330
request_handlers = registry.Registry()
331
request_handlers.register_lazy(
332
    'append', 'bzrlib.smart.vfs', 'AppendRequest')
333
request_handlers.register_lazy(
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
334
    'Branch.get_config_file', 'bzrlib.smart.branch', 'SmartServerBranchGetConfigFile')
335
request_handlers.register_lazy(
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
336
    'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
337
request_handlers.register_lazy(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
338
    'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
339
request_handlers.register_lazy(
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
340
    'Branch.revision_history', 'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
341
request_handlers.register_lazy(
2018.5.77 by Wouter van Heyst
Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration
342
    'Branch.set_last_revision', 'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
343
request_handlers.register_lazy(
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
344
    'Branch.set_last_revision_info', 'bzrlib.smart.branch',
345
    'SmartServerBranchRequestSetLastRevisionInfo')
346
request_handlers.register_lazy(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
347
    'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock')
348
request_handlers.register_lazy(
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
349
    'BzrDir.find_repository', 'bzrlib.smart.bzrdir', 'SmartServerRequestFindRepositoryV1')
350
request_handlers.register_lazy(
351
    'BzrDir.find_repositoryV2', 'bzrlib.smart.bzrdir', 'SmartServerRequestFindRepositoryV2')
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
352
request_handlers.register_lazy(
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
353
    'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir', 'SmartServerRequestInitializeBzrDir')
354
request_handlers.register_lazy(
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
355
    'BzrDir.open_branch', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBranch')
356
request_handlers.register_lazy(
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
357
    'delete', 'bzrlib.smart.vfs', 'DeleteRequest')
358
request_handlers.register_lazy(
359
    'get', 'bzrlib.smart.vfs', 'GetRequest')
360
request_handlers.register_lazy(
361
    'get_bundle', 'bzrlib.smart.request', 'GetBundleRequest')
362
request_handlers.register_lazy(
363
    'has', 'bzrlib.smart.vfs', 'HasRequest')
364
request_handlers.register_lazy(
365
    'hello', 'bzrlib.smart.request', 'HelloRequest')
366
request_handlers.register_lazy(
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
367
    'iter_files_recursive', 'bzrlib.smart.vfs', 'IterFilesRecursiveRequest')
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
368
request_handlers.register_lazy(
369
    'list_dir', 'bzrlib.smart.vfs', 'ListDirRequest')
370
request_handlers.register_lazy(
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
371
    'mkdir', 'bzrlib.smart.vfs', 'MkdirRequest')
372
request_handlers.register_lazy(
373
    'move', 'bzrlib.smart.vfs', 'MoveRequest')
374
request_handlers.register_lazy(
375
    'put', 'bzrlib.smart.vfs', 'PutRequest')
376
request_handlers.register_lazy(
377
    'put_non_atomic', 'bzrlib.smart.vfs', 'PutNonAtomicRequest')
378
request_handlers.register_lazy(
379
    'readv', 'bzrlib.smart.vfs', 'ReadvRequest')
380
request_handlers.register_lazy(
381
    'rename', 'bzrlib.smart.vfs', 'RenameRequest')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
382
request_handlers.register_lazy('Repository.gather_stats',
383
                               'bzrlib.smart.repository',
384
                               'SmartServerRepositoryGatherStats')
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
385
request_handlers.register_lazy('Repository.get_parent_map',
386
                               'bzrlib.smart.repository',
387
                               'SmartServerRepositoryGetParentMap')
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
388
request_handlers.register_lazy(
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
389
    'Repository.stream_knit_data_for_revisions',
390
    'bzrlib.smart.repository',
391
    'SmartServerRepositoryStreamKnitDataForRevisions')
392
request_handlers.register_lazy(
393
    'Repository.stream_revisions_chunked',
394
    'bzrlib.smart.repository',
395
    'SmartServerRepositoryStreamRevisionsChunked')
396
request_handlers.register_lazy(
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
397
    'Repository.get_revision_graph', 'bzrlib.smart.repository', 'SmartServerRepositoryGetRevisionGraph')
398
request_handlers.register_lazy(
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
399
    'Repository.has_revision', 'bzrlib.smart.repository', 'SmartServerRequestHasRevision')
400
request_handlers.register_lazy(
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
401
    'Repository.is_shared', 'bzrlib.smart.repository', 'SmartServerRepositoryIsShared')
402
request_handlers.register_lazy(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
403
    'Repository.lock_write', 'bzrlib.smart.repository', 'SmartServerRepositoryLockWrite')
404
request_handlers.register_lazy(
405
    'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock')
406
request_handlers.register_lazy(
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
407
    'Repository.tarball', 'bzrlib.smart.repository',
408
    'SmartServerRepositoryTarball')
409
request_handlers.register_lazy(
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
410
    'rmdir', 'bzrlib.smart.vfs', 'RmdirRequest')
411
request_handlers.register_lazy(
412
    'stat', 'bzrlib.smart.vfs', 'StatRequest')
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
413
request_handlers.register_lazy(
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
414
    'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly')
415
request_handlers.register_lazy(
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
416
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')