~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2006-2010 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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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.
16
4160.2.14 by Andrew Bennetts
Merge bzr.dev, improve NEWS entry and bzrlib.smart.request docs.
17
"""Infrastructure for server-side request handlers.
18
19
Interesting module attributes:
20
    * The request_handlers registry maps verb names to SmartServerRequest
21
      classes.
22
    * The jail_info threading.local() object is used to prevent accidental
23
      opening of BzrDirs outside of the backing transport, or any other
24
      transports placed in jail_info.transports.  The jail_info is reset on
25
      every call into a request handler (which can happen an arbitrary number
26
      of times during a request).
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
27
"""
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
28
4160.2.14 by Andrew Bennetts
Merge bzr.dev, improve NEWS entry and bzrlib.smart.request docs.
29
# XXX: The class names are a little confusing: the protocol will instantiate a
30
# SmartServerRequestHandler, whose dispatch_command method creates an instance
31
# of a SmartServerRequest subclass.
32
33
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
34
import threading
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
35
2402.1.2 by Andrew Bennetts
Deal with review comments.
36
from bzrlib import (
37
    bzrdir,
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
38
    debug,
2402.1.2 by Andrew Bennetts
Deal with review comments.
39
    errors,
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
40
    osutils,
2402.1.2 by Andrew Bennetts
Deal with review comments.
41
    registry,
42
    revision,
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
43
    trace,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
44
    urlutils,
2402.1.2 by Andrew Bennetts
Deal with review comments.
45
    )
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
46
from bzrlib.lazy_import import lazy_import
47
lazy_import(globals(), """
48
from bzrlib.bundle import serializer
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
49
50
import tempfile
51
import thread
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
52
""")
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
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
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
55
jail_info = threading.local()
56
jail_info.transports = None
57
58
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
59
def _install_hook():
60
    bzrdir.BzrDir.hooks.install_named_hook(
61
        'pre_open', _pre_open_hook, 'checking server jail')
62
63
64
def _pre_open_hook(transport):
4205.2.1 by Andrew Bennetts
Fix BzrDir.open in non-main (and non-server-request) thread when bzrlib.smart.request's _pre_open_hook is installed.
65
    allowed_transports = getattr(jail_info, 'transports', None)
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
66
    if allowed_transports is None:
67
        return
68
    abspath = transport.base
69
    for allowed_transport in allowed_transports:
70
        try:
71
            allowed_transport.relpath(abspath)
72
        except errors.PathNotChild:
73
            continue
74
        else:
75
            return
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
76
    raise errors.JailBreak(abspath)
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
77
78
79
_install_hook()
80
81
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.
82
class SmartServerRequest(object):
2692.1.10 by Andrew Bennetts
More docstring polish
83
    """Base class for request handlers.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
84
2692.1.10 by Andrew Bennetts
More docstring polish
85
    To define a new request, subclass this class and override the `do` method
86
    (and if appropriate, `do_body` as well).  Request implementors should take
87
    care to call `translate_client_path` and `transport_from_client_path` as
88
    appropriate when dealing with paths received from the client.
89
    """
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
90
    # XXX: rename this class to BaseSmartServerRequestHandler ?  A request
91
    # *handler* is a different concept to the request.
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.
92
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
93
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
2402.1.2 by Andrew Bennetts
Deal with review comments.
94
        """Constructor.
95
96
        :param backing_transport: the base transport to be used when performing
97
            this request.
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
98
        :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.
99
            backing_transport.  This is used to interpret relpaths received
100
            from the client.  Clients will not be able to refer to paths above
2692.1.16 by Andrew Bennetts
Improve comments.
101
            this root.  If root_client_path is None, then no translation will
102
            be performed on client paths.  Default is '/'.
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
103
        :param jail_root: if specified, the root of the BzrDir.open jail to use
104
            instead of backing_transport.
2402.1.2 by Andrew Bennetts
Deal with review comments.
105
        """
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.
106
        self._backing_transport = backing_transport
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
107
        if jail_root is None:
108
            jail_root = backing_transport
109
        self._jail_root = jail_root
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
110
        if root_client_path is not None:
111
            if not root_client_path.startswith('/'):
112
                root_client_path = '/' + root_client_path
113
            if not root_client_path.endswith('/'):
114
                root_client_path += '/'
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
115
        self._root_client_path = root_client_path
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
116
        self._body_chunks = []
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
117
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)
118
    def _check_enabled(self):
119
        """Raises DisabledMethod if this method is disabled."""
120
        pass
121
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
122
    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)
123
        """Mandatory extension point for SmartServerRequest subclasses.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
124
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)
125
        Subclasses must implement this.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
126
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
127
        This should return a SmartServerResponse if this command expects to
128
        receive no body.
129
        """
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
130
        raise NotImplementedError(self.do)
131
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)
132
    def execute(self, *args):
133
        """Public entry point to execute this request.
134
135
        It will return a SmartServerResponse if the command does not expect a
136
        body.
137
5891.1.3 by Andrew Bennetts
Move docstring formatting fixes.
138
        :param args: the arguments of the request.
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)
139
        """
140
        self._check_enabled()
141
        return self.do(*args)
142
2018.5.5 by Andrew Bennetts
Pass body_bytes directly to SmartServerRequest.do_body
143
    def do_body(self, body_bytes):
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
144
        """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.
145
146
        The do() method is still called, and must have returned None.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
147
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
148
        Must return a SmartServerResponse.
149
        """
3990.3.2 by Andrew Bennetts
Fix the do_body NotImplementedError log spam.
150
        if body_bytes != '':
3990.3.3 by Andrew Bennetts
Add a test that unexpected request bodies trigger a SmartProtocolError from request implementations.
151
            raise errors.SmartProtocolError('Request does not expect a body')
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.
152
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
153
    def do_chunk(self, chunk_bytes):
154
        """Called with each body chunk if the request has a streamed body.
155
156
        The do() method is still called, and must have returned None.
157
        """
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
158
        self._body_chunks.append(chunk_bytes)
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
159
160
    def do_end(self):
161
        """Called when the end of the request has been received."""
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
162
        body_bytes = ''.join(self._body_chunks)
163
        self._body_chunks = None
3923.5.2 by Andrew Bennetts
Completely delegate handling of request body chunks to the command object. The default implementation accumulates, like the existing behaviour.
164
        return self.do_body(body_bytes)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
165
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
166
    def setup_jail(self):
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
167
        jail_info.transports = [self._jail_root]
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
168
169
    def teardown_jail(self):
170
        jail_info.transports = None
171
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
172
    def translate_client_path(self, client_path):
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
173
        """Translate a path received from a network client into a local
174
        relpath.
175
176
        All paths received from the client *must* be translated.
177
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
178
        :param client_path: the path from the client.
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
179
        :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.
180
            (unlike the untranslated client_path, which must not be used with
181
            the backing transport).
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
182
        """
2692.1.14 by Andrew Bennetts
All WSGI tests passing, and manual testing works too.
183
        if self._root_client_path is None:
184
            # no translation necessary!
185
            return client_path
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
186
        if not client_path.startswith('/'):
187
            client_path = '/' + client_path
4294.2.1 by Robert Collins
Move directory checking for bzr push options into Branch.create_clone_on_transport.
188
        if client_path + '/' == self._root_client_path:
189
            return '.'
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
190
        if client_path.startswith(self._root_client_path):
191
            path = client_path[len(self._root_client_path):]
192
            relpath = urlutils.joinpath('/', path)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
193
            if not relpath.startswith('/'):
194
                raise ValueError(relpath)
4760.2.1 by Michael Hudson
very simple fix
195
            return urlutils.escape('.' + relpath)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
196
        else:
197
            raise errors.PathNotChild(client_path, self._root_client_path)
198
199
    def transport_from_client_path(self, client_path):
2692.1.9 by Andrew Bennetts
Docstrings for translate_client_path and transport_from_client_path.
200
        """Get a backing transport corresponding to the location referred to by
201
        a network client.
202
203
        :seealso: translate_client_path
204
        :returns: a transport cloned from self._backing_transport
205
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
206
        relpath = self.translate_client_path(client_path)
2692.1.16 by Andrew Bennetts
Improve comments.
207
        return self._backing_transport.clone(relpath)
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
208
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
209
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
210
class SmartServerResponse(object):
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
211
    """A response to a client request.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
212
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
213
    This base class should not be used. Instead use
214
    SuccessfulSmartServerResponse and FailedSmartServerResponse as appropriate.
215
    """
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
216
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
217
    def __init__(self, args, body=None, body_stream=None):
218
        """Constructor.
219
220
        :param args: tuple of response arguments.
221
        :param body: string of a response body.
222
        :param body_stream: iterable of bytestrings to be streamed to the
223
            client.
224
        """
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
225
        self.args = args
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
226
        if body is not None and body_stream is not None:
227
            raise errors.BzrError(
228
                "'body' and 'body_stream' are mutually exclusive.")
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
229
        self.body = body
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
230
        self.body_stream = body_stream
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
231
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
232
    def __eq__(self, other):
233
        if other is None:
234
            return False
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
235
        return (other.args == self.args and
236
                other.body == self.body and
237
                other.body_stream is self.body_stream)
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
238
239
    def __repr__(self):
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
240
        return "<%s args=%r body=%r>" % (self.__class__.__name__,
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
241
            self.args, self.body)
2402.1.1 by Andrew Bennetts
Use the Command pattern for handling smart server commands.
242
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
243
2432.4.2 by Robert Collins
Add FailedSmartServerResponse.
244
class FailedSmartServerResponse(SmartServerResponse):
245
    """A SmartServerResponse for a request which failed."""
246
247
    def is_successful(self):
248
        """FailedSmartServerResponse are not successful."""
249
        return False
250
251
2432.4.1 by Robert Collins
Add SuccessfulSmartServerResponse.
252
class SuccessfulSmartServerResponse(SmartServerResponse):
253
    """A SmartServerResponse for a successfully completed request."""
254
255
    def is_successful(self):
256
        """SuccessfulSmartServerResponse are successful."""
257
        return True
258
2018.5.16 by Andrew Bennetts
Move SmartServerResponse to smart/request.py, untangling more import dependencies.
259
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
260
class SmartServerRequestHandler(object):
261
    """Protocol logic for smart server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
262
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
263
    This doesn't handle serialization at all, it just processes requests and
264
    creates responses.
265
    """
266
267
    # IMPORTANT FOR IMPLEMENTORS: It is important that SmartServerRequestHandler
268
    # not contain encoding or decoding logic to allow the wire protocol to vary
269
    # from the object protocol: we will want to tweak the wire protocol separate
270
    # from the object model, and ideally we will be able to do that without
271
    # having a SmartServerRequestHandler subclass for each wire protocol, rather
272
    # just a Protocol subclass.
273
274
    # TODO: Better way of representing the body for commands that take it,
275
    # and allow it to be streamed into the server.
276
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
277
    def __init__(self, backing_transport, commands, root_client_path,
4760.1.4 by Andrew Bennetts
Make jail_root param of SmartServerRequestHandler optional for convenience of tests.
278
        jail_root=None):
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
279
        """Constructor.
280
281
        :param backing_transport: a Transport to handle requests for.
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
282
        :param commands: a registry mapping command names to SmartServerRequest
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
283
            subclasses. e.g. bzrlib.transport.smart.vfs.vfs_commands.
284
        """
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
285
        self._backing_transport = backing_transport
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
286
        self._root_client_path = root_client_path
2018.5.17 by Andrew Bennetts
Paramaterise the commands handled by SmartServerRequestHandler.
287
        self._commands = commands
4760.1.4 by Andrew Bennetts
Make jail_root param of SmartServerRequestHandler optional for convenience of tests.
288
        if jail_root is None:
289
            jail_root = backing_transport
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
290
        self._jail_root = jail_root
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
291
        self.response = None
292
        self.finished_reading = False
293
        self._command = None
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
294
        if 'hpss' in debug.debug_flags:
295
            self._request_start_time = osutils.timer_func()
4913.1.1 by John Arbash Meinel
Switch to using thread.get_ident() which is available on all python versions.
296
            self._thread_id = thread.get_ident()
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
297
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
298
    def _trace(self, action, message, extra_bytes=None, include_time=False):
4889.2.3 by John Arbash Meinel
Get rid of -Dhpssthread, just always include it.
299
        # It is a bit of a shame that this functionality overlaps with that of 
300
        # ProtocolThreeRequester._trace. However, there is enough difference
301
        # that just putting it in a helper doesn't help a lot. And some state
302
        # is taken from the instance.
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
303
        if include_time:
304
            t = '%5.3fs ' % (osutils.timer_func() - self._request_start_time)
305
        else:
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
306
            t = ''
307
        if extra_bytes is None:
308
            extra = ''
309
        else:
310
            extra = ' ' + repr(extra_bytes[:40])
311
            if len(extra) > 33:
312
                extra = extra[:29] + extra[-1] + '...'
4889.2.3 by John Arbash Meinel
Get rid of -Dhpssthread, just always include it.
313
        trace.mutter('%12s: [%s] %s%s%s'
314
                     % (action, self._thread_id, t, message, extra))
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
315
316
    def accept_body(self, bytes):
317
        """Accept body data."""
4475.2.2 by Andrew Bennetts
Don't try call do_chunk or do_end if there's no active command (e.g. while consuming a request for an unknown method)
318
        if self._command is None:
319
            # no active command object, so ignore the event.
320
            return
3923.5.2 by Andrew Bennetts
Completely delegate handling of request body chunks to the command object. The default implementation accumulates, like the existing behaviour.
321
        self._run_handler_code(self._command.do_chunk, (bytes,), {})
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
322
        if 'hpss' in debug.debug_flags:
323
            self._trace('accept body',
324
                        '%d bytes' % (len(bytes),), bytes)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
325
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
326
    def end_of_body(self):
327
        """No more body data will be received."""
3923.5.2 by Andrew Bennetts
Completely delegate handling of request body chunks to the command object. The default implementation accumulates, like the existing behaviour.
328
        self._run_handler_code(self._command.do_end, (), {})
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
329
        # cannot read after this.
330
        self.finished_reading = True
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
331
        if 'hpss' in debug.debug_flags:
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
332
            self._trace('end of body', '', include_time=True)
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
333
334
    def _run_handler_code(self, callable, args, kwargs):
335
        """Run some handler specific code 'callable'.
336
337
        If a result is returned, it is considered to be the commands response,
338
        and finished_reading is set true, and its assigned to self.response.
339
340
        Any exceptions caught are translated and a response object created
341
        from them.
342
        """
343
        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.
344
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
345
        if result is not None:
346
            self.response = result
347
            self.finished_reading = True
348
349
    def _call_converting_errors(self, callable, args, kwargs):
350
        """Call callable converting errors to Response objects."""
351
        # XXX: most of this error conversion is VFS-related, and thus ought to
352
        # be in SmartServerVFSRequestHandler somewhere.
353
        try:
4160.2.2 by Andrew Bennetts
Add setup_jail and teardown_jail to SmartServerRequest.
354
            self._command.setup_jail()
355
            try:
356
                return callable(*args, **kwargs)
357
            finally:
358
                self._command.teardown_jail()
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
359
        except (KeyboardInterrupt, SystemExit):
360
            raise
361
        except Exception, err:
362
            err_struct = _translate_error(err)
363
            return FailedSmartServerResponse(err_struct)
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
364
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
365
    def headers_received(self, headers):
3245.4.33 by Andrew Bennetts
Remove unused no_body_received method on SmartServerRequestHandler.
366
        # Just a no-op at the moment.
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
367
        if 'hpss' in debug.debug_flags:
368
            self._trace('headers', repr(headers))
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
369
370
    def args_received(self, args):
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
371
        cmd = args[0]
372
        args = args[1:]
373
        try:
374
            command = self._commands.get(cmd)
375
        except LookupError:
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
376
            if 'hpss' in debug.debug_flags:
377
                self._trace('hpss unknown request', 
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
378
                            cmd, repr(args)[1:-1])
3245.4.48 by Andrew Bennetts
raise UnknownSmartMethod from dispatch_command.
379
            raise errors.UnknownSmartMethod(cmd)
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
380
        if 'hpss' in debug.debug_flags:
381
            from bzrlib.smart import vfs
382
            if issubclass(command, vfs.VfsRequest):
383
                action = 'hpss vfs req'
384
            else:
385
                action = 'hpss request'
386
            self._trace(action, 
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
387
                        '%s %s' % (cmd, repr(args)[1:-1]))
4634.6.30 by Andrew Bennetts
Remove SmartServerRequest.dispatch_command, fix SmartServerRequest.args_received.
388
        self._command = command(
4760.1.1 by Andrew Bennetts
Add optional jail_root argument to SmartServerRequest and friends, and use it in the WSGI glue. Allows opening branches in shared repos via bzr+http (assuming the repo should be accessible).
389
            self._backing_transport, self._root_client_path, self._jail_root)
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
390
        self._run_handler_code(self._command.execute, args, {})
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
391
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
392
    def end_received(self):
4475.2.2 by Andrew Bennetts
Don't try call do_chunk or do_end if there's no active command (e.g. while consuming a request for an unknown method)
393
        if self._command is None:
394
            # no active command object, so ignore the event.
395
            return
3195.3.4 by Andrew Bennetts
Make the general request handler dispatch version 3 events to the specific request handler (i.e. to the SmartServerRequest instance).
396
        self._run_handler_code(self._command.do_end, (), {})
4889.2.1 by John Arbash Meinel
Make -Dhpss log debug information for the server process.
397
        if 'hpss' in debug.debug_flags:
4889.2.4 by John Arbash Meinel
Clean up some bits, we don't really need the time reported except for end time.
398
            self._trace('end', '', include_time=True)
3195.3.2 by Andrew Bennetts
Checkpoint first rough cut of SmartServerRequestProtocolThree, this implementation reuses the _StatefulDecoder class. Plus some attempts to start tidying the smart protocol tests.
399
3923.5.4 by Andrew Bennetts
Allow a request's body part(s) to be followed by an error.
400
    def post_body_error_received(self, error_args):
401
        # Just a no-op at the moment.
402
        pass
403
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
404
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
405
def _translate_error(err):
406
    if isinstance(err, errors.NoSuchFile):
407
        return ('NoSuchFile', err.path)
408
    elif isinstance(err, errors.FileExists):
409
        return ('FileExists', err.path)
410
    elif isinstance(err, errors.DirectoryNotEmpty):
411
        return ('DirectoryNotEmpty', err.path)
4650.2.2 by Robert Collins
Serialize IncompatibleRepositories from the server too.
412
    elif isinstance(err, errors.IncompatibleRepositories):
413
        return ('IncompatibleRepositories', str(err.source), str(err.target),
414
            str(err.details))
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
415
    elif isinstance(err, errors.ShortReadvError):
416
        return ('ShortReadvError', err.path, str(err.offset), str(err.length),
417
                str(err.actual))
418
    elif isinstance(err, errors.UnstackableRepositoryFormat):
419
        return (('UnstackableRepositoryFormat', str(err.format), err.url))
420
    elif isinstance(err, errors.UnstackableBranchFormat):
421
        return ('UnstackableBranchFormat', str(err.format), err.url)
422
    elif isinstance(err, errors.NotStacked):
423
        return ('NotStacked',)
424
    elif isinstance(err, UnicodeError):
425
        # If it is a DecodeError, than most likely we are starting
426
        # with a plain string
427
        str_or_unicode = err.object
428
        if isinstance(str_or_unicode, unicode):
429
            # XXX: UTF-8 might have \x01 (our protocol v1 and v2 seperator
430
            # byte) in it, so this encoding could cause broken responses.
431
            # Newer clients use protocol v3, so will be fine.
432
            val = 'u:' + str_or_unicode.encode('utf-8')
433
        else:
434
            val = 's:' + str_or_unicode.encode('base64')
435
        # This handles UnicodeEncodeError or UnicodeDecodeError
436
        return (err.__class__.__name__, err.encoding, val, str(err.start),
437
                str(err.end), err.reason)
438
    elif isinstance(err, errors.TransportNotPossible):
439
        if err.msg == "readonly transport":
440
            return ('ReadOnlyError', )
441
    elif isinstance(err, errors.ReadError):
442
        # cannot read the file
443
        return ('ReadError', err.path)
444
    elif isinstance(err, errors.PermissionDenied):
445
        return ('PermissionDenied', err.path, err.extra)
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
446
    elif isinstance(err, errors.TokenMismatch):
447
        return ('TokenMismatch', err.given_token, err.lock_token)
448
    elif isinstance(err, errors.LockContention):
4556.2.6 by Andrew Bennetts
More conservative fix for LockContention serialisation.
449
        return ('LockContention',)
5677.2.1 by Martin
Detect and report MemoryError during a smart server request
450
    elif isinstance(err, MemoryError):
451
        # GZ 2011-02-24: Copy bzrlib.trace -Dmem_dump functionality here?
452
        return ('MemoryError',)
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
453
    # Unserialisable error.  Log it, and return a generic error
454
    trace.log_exception_quietly()
5677.2.7 by Martin
Store exception name after initial 'error' slot as suggested in review
455
    return ('error', trace._qualified_exception_name(err.__class__, True),
456
        str(err))
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
457
458
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
459
class HelloRequest(SmartServerRequest):
2432.2.6 by Andrew Bennetts
Improve HelloRequest's docstring.
460
    """Answer a version request with the highest protocol version this server
461
    supports.
462
    """
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
463
464
    def do(self):
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
465
        return SuccessfulSmartServerResponse(('ok', '2'))
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
466
467
468
class GetBundleRequest(SmartServerRequest):
2402.1.2 by Andrew Bennetts
Deal with review comments.
469
    """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.
470
471
    def do(self, path, revision_id):
472
        # open transport relative to our base
2692.1.7 by Andrew Bennetts
Translate path in GetBundleRequest too.
473
        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.
474
        control, extra_path = bzrdir.BzrDir.open_containing_from_transport(t)
475
        repo = control.open_repository()
476
        tmpf = tempfile.TemporaryFile()
477
        base_revision = revision.NULL_REVISION
3224.5.6 by Andrew Bennetts
Don't import bzrlib.bundle in bzrlib.smart.request until it's needed.
478
        serializer.write_bundle(repo, revision_id, base_revision, tmpf)
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
479
        tmpf.seek(0)
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
480
        return SuccessfulSmartServerResponse((), tmpf.read())
2018.5.6 by Andrew Bennetts
Tidy ups, and turn do_hello and do_get_bundle into command objects.
481
482
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.
483
class SmartServerIsReadonly(SmartServerRequest):
484
    # XXX: this request method belongs somewhere else.
485
486
    def do(self):
487
        if self._backing_transport.is_readonly():
488
            answer = 'yes'
489
        else:
490
            answer = 'no'
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
491
        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.
492
493
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
494
request_handlers = registry.Registry()
495
request_handlers.register_lazy(
496
    'append', 'bzrlib.smart.vfs', 'AppendRequest')
497
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
498
    'Branch.get_config_file', 'bzrlib.smart.branch',
499
    'SmartServerBranchGetConfigFile')
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
500
request_handlers.register_lazy(
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
501
    'Branch.get_parent', 'bzrlib.smart.branch', 'SmartServerBranchGetParent')
502
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
503
    'Branch.get_tags_bytes', 'bzrlib.smart.branch',
504
    'SmartServerBranchGetTagsBytes')
505
request_handlers.register_lazy(
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
506
    'Branch.set_tags_bytes', 'bzrlib.smart.branch',
507
    'SmartServerBranchSetTagsBytes')
508
request_handlers.register_lazy(
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
509
    'Branch.heads_to_fetch', 'bzrlib.smart.branch',
510
    'SmartServerBranchHeadsToFetch')
511
request_handlers.register_lazy(
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
512
    'Branch.get_stacked_on_url', 'bzrlib.smart.branch', 'SmartServerBranchRequestGetStackedOnURL')
513
request_handlers.register_lazy(
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
514
    'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
515
request_handlers.register_lazy(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
516
    'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
4226.2.1 by Robert Collins
Set branch config options via a smart method.
517
request_handlers.register_lazy( 'Branch.revision_history',
518
    'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
519
request_handlers.register_lazy( 'Branch.set_config_option',
520
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
521
request_handlers.register_lazy( 'Branch.set_config_option_dict',
522
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOptionDict')
4226.2.1 by Robert Collins
Set branch config options via a smart method.
523
request_handlers.register_lazy( 'Branch.set_last_revision',
524
    '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.
525
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.
526
    'Branch.set_last_revision_info', 'bzrlib.smart.branch',
527
    'SmartServerBranchRequestSetLastRevisionInfo')
528
request_handlers.register_lazy(
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
529
    'Branch.set_last_revision_ex', 'bzrlib.smart.branch',
530
    'SmartServerBranchRequestSetLastRevisionEx')
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
531
request_handlers.register_lazy(
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
532
    'Branch.set_parent_location', 'bzrlib.smart.branch',
533
    'SmartServerBranchRequestSetParentLocation')
534
request_handlers.register_lazy(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
535
    'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock')
536
request_handlers.register_lazy(
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
537
    'BzrDir.cloning_metadir', 'bzrlib.smart.bzrdir',
538
    'SmartServerBzrDirRequestCloningMetaDir')
539
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
540
    'BzrDir.create_branch', 'bzrlib.smart.bzrdir',
541
    'SmartServerRequestCreateBranch')
542
request_handlers.register_lazy(
543
    'BzrDir.create_repository', 'bzrlib.smart.bzrdir',
544
    'SmartServerRequestCreateRepository')
545
request_handlers.register_lazy(
546
    'BzrDir.find_repository', 'bzrlib.smart.bzrdir',
547
    'SmartServerRequestFindRepositoryV1')
548
request_handlers.register_lazy(
549
    'BzrDir.find_repositoryV2', 'bzrlib.smart.bzrdir',
550
    'SmartServerRequestFindRepositoryV2')
551
request_handlers.register_lazy(
552
    'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir',
553
    'SmartServerRequestFindRepositoryV3')
554
request_handlers.register_lazy(
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
555
    'BzrDir.get_config_file', 'bzrlib.smart.bzrdir',
556
    'SmartServerBzrDirRequestConfigFile')
557
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
558
    'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir',
559
    'SmartServerRequestInitializeBzrDir')
560
request_handlers.register_lazy(
4436.1.1 by Andrew Bennetts
Rename BzrDirFormat.initialize_ex verb to BzrDirFormat.initialize_ex_1.16.
561
    'BzrDirFormat.initialize_ex_1.16', 'bzrlib.smart.bzrdir',
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
562
    'SmartServerRequestBzrDirInitializeEx')
563
request_handlers.register_lazy(
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
564
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')
565
request_handlers.register_lazy(
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
566
    'BzrDir.open_2.1', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir_2_1')
567
request_handlers.register_lazy(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
568
    'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
569
    'SmartServerRequestOpenBranch')
570
request_handlers.register_lazy(
571
    'BzrDir.open_branchV2', 'bzrlib.smart.bzrdir',
572
    'SmartServerRequestOpenBranchV2')
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
573
request_handlers.register_lazy(
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
574
    'BzrDir.open_branchV3', 'bzrlib.smart.bzrdir',
575
    'SmartServerRequestOpenBranchV3')
576
request_handlers.register_lazy(
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
577
    'delete', 'bzrlib.smart.vfs', 'DeleteRequest')
578
request_handlers.register_lazy(
579
    'get', 'bzrlib.smart.vfs', 'GetRequest')
580
request_handlers.register_lazy(
581
    'get_bundle', 'bzrlib.smart.request', 'GetBundleRequest')
582
request_handlers.register_lazy(
583
    'has', 'bzrlib.smart.vfs', 'HasRequest')
584
request_handlers.register_lazy(
585
    'hello', 'bzrlib.smart.request', 'HelloRequest')
586
request_handlers.register_lazy(
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
587
    'iter_files_recursive', 'bzrlib.smart.vfs', 'IterFilesRecursiveRequest')
2018.5.23 by Andrew Bennetts
Use a Registry for smart server command handlers.
588
request_handlers.register_lazy(
589
    'list_dir', 'bzrlib.smart.vfs', 'ListDirRequest')
590
request_handlers.register_lazy(
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
591
    'mkdir', 'bzrlib.smart.vfs', 'MkdirRequest')
592
request_handlers.register_lazy(
593
    'move', 'bzrlib.smart.vfs', 'MoveRequest')
594
request_handlers.register_lazy(
595
    'put', 'bzrlib.smart.vfs', 'PutRequest')
596
request_handlers.register_lazy(
597
    'put_non_atomic', 'bzrlib.smart.vfs', 'PutNonAtomicRequest')
598
request_handlers.register_lazy(
599
    'readv', 'bzrlib.smart.vfs', 'ReadvRequest')
600
request_handlers.register_lazy(
601
    'rename', 'bzrlib.smart.vfs', 'RenameRequest')
3452.2.2 by Andrew Bennetts
Experimental PackRepository.{check_references,autopack} RPCs.
602
request_handlers.register_lazy(
603
    'PackRepository.autopack', 'bzrlib.smart.packrepository',
604
    'SmartServerPackRepositoryAutopack')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
605
request_handlers.register_lazy('Repository.gather_stats',
606
                               'bzrlib.smart.repository',
607
                               'SmartServerRepositoryGatherStats')
3842.3.3 by Andrew Bennetts
Remove RPC registration for VersionedFiles.get_parent_map, not Repository.get_parent_map.
608
request_handlers.register_lazy('Repository.get_parent_map',
609
                               'bzrlib.smart.repository',
610
                               'SmartServerRepositoryGetParentMap')
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
611
request_handlers.register_lazy(
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
612
    'Repository.get_revision_graph', 'bzrlib.smart.repository', 'SmartServerRepositoryGetRevisionGraph')
613
request_handlers.register_lazy(
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
614
    'Repository.has_revision', 'bzrlib.smart.repository', 'SmartServerRequestHasRevision')
615
request_handlers.register_lazy(
4022.1.6 by Robert Collins
Cherrypick and polish the RemoteSink for streaming push.
616
    'Repository.insert_stream', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream')
617
request_handlers.register_lazy(
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
618
    'Repository.insert_stream_1.19', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream_1_19')
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
619
request_handlers.register_lazy(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
620
    'Repository.insert_stream_locked', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStreamLocked')
621
request_handlers.register_lazy(
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
622
    'Repository.is_shared', 'bzrlib.smart.repository', 'SmartServerRepositoryIsShared')
623
request_handlers.register_lazy(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
624
    'Repository.lock_write', 'bzrlib.smart.repository', 'SmartServerRepositoryLockWrite')
625
request_handlers.register_lazy(
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
626
    'Repository.set_make_working_trees', 'bzrlib.smart.repository',
627
    'SmartServerRepositorySetMakeWorkingTrees')
628
request_handlers.register_lazy(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
629
    'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock')
630
request_handlers.register_lazy(
4419.2.4 by Andrew Bennetts
Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
631
    'Repository.get_rev_id_for_revno', 'bzrlib.smart.repository',
632
    'SmartServerRepositoryGetRevIdForRevno')
633
request_handlers.register_lazy(
4060.1.5 by Robert Collins
Verb change name requested by Andrew.
634
    'Repository.get_stream', 'bzrlib.smart.repository',
635
    'SmartServerRepositoryGetStream')
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
636
request_handlers.register_lazy(
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
637
    'Repository.get_stream_1.19', 'bzrlib.smart.repository',
638
    'SmartServerRepositoryGetStream_1_19')
4476.3.29 by Andrew Bennetts
Add Repository.get_stream_1.18 verb.
639
request_handlers.register_lazy(
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
640
    'Repository.tarball', 'bzrlib.smart.repository',
641
    'SmartServerRepositoryTarball')
642
request_handlers.register_lazy(
2018.5.37 by Andrew Bennetts
Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names.
643
    'rmdir', 'bzrlib.smart.vfs', 'RmdirRequest')
644
request_handlers.register_lazy(
645
    '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.
646
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.
647
    'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly')