/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3245.4.31 by Andrew Bennetts
Fix year in copyright statement of message.py
1
# Copyright (C) 2008 Canonical Ltd
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
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
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
16
6379.6.3 by Jelmer Vernooij
Use absolute_import.
17
from __future__ import absolute_import
18
3195.3.24 by Andrew Bennetts
Implement read_streamed_body on ConventionalResponseHandler.
19
import collections
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
20
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
21
from .. import (
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
22
    debug,
23
    errors,
24
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
25
from ..sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
26
    BytesIO,
27
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
28
from ..trace import mutter
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
29
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
30
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
31
class MessageHandler(object):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
32
    """Base class for handling messages received via the smart protocol.
33
34
    As parts of a message are received, the corresponding PART_received method
35
    will be called.
36
    """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
37
38
    def __init__(self):
39
        self.headers = None
40
41
    def headers_received(self, headers):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
42
        """Called when message headers are received.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
43
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
44
        This default implementation just stores them in self.headers.
45
        """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
46
        self.headers = headers
47
48
    def byte_part_received(self, byte):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
49
        """Called when a 'byte' part is received.
50
51
        Note that a 'byte' part is a message part consisting of exactly one
52
        byte.
53
        """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
54
        raise NotImplementedError(self.byte_received)
55
56
    def bytes_part_received(self, bytes):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
57
        """Called when a 'bytes' part is received.
58
59
        A 'bytes' message part can contain any number of bytes.  It should not
60
        be confused with a 'byte' part, which is always a single byte.
61
        """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
62
        raise NotImplementedError(self.bytes_received)
63
64
    def structure_part_received(self, structure):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
65
        """Called when a 'structure' part is received.
66
67
        :param structure: some structured data, which will be some combination
68
            of list, dict, int, and str objects.
69
        """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
70
        raise NotImplementedError(self.bytes_received)
71
72
    def protocol_error(self, exception):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
73
        """Called when there is a protocol decoding error.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
74
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
75
        The default implementation just re-raises the exception.
76
        """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
77
        raise
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
78
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
79
    def end_received(self):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
80
        """Called when the end of the message is received."""
3245.4.27 by Andrew Bennetts
Tidy some XXXs in bzrlib/smart/message.py.
81
        # No-op by default.
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
82
        pass
83
84
85
class ConventionalRequestHandler(MessageHandler):
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
86
    """A message handler for "conventional" requests.
87
88
    "Conventional" is used in the sense described in
89
    doc/developers/network-protocol.txt: a simple message with arguments and an
90
    optional body.
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
91
92
    Possible states:
3842.3.19 by Andrew Bennetts
Tweaks suggested by review.
93
     * args: expecting args
94
     * body: expecting body (terminated by receiving a post-body status)
95
     * error: expecting post-body error
96
     * end: expecting end of message
97
     * nothing: finished
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
98
    """
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
99
100
    def __init__(self, request_handler, responder):
101
        MessageHandler.__init__(self)
102
        self.request_handler = request_handler
103
        self.responder = responder
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
104
        self.expecting = 'args'
105
        self._should_finish_body = False
106
        self._response_sent = False
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
107
108
    def protocol_error(self, exception):
3245.4.50 by Andrew Bennetts
Clarify the code a little.
109
        if self.responder.response_sent:
110
            # We can only send one response to a request, no matter how many
111
            # errors happen while processing it.
112
            return
113
        self.responder.send_error(exception)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
114
115
    def byte_part_received(self, byte):
3923.5.1 by Andrew Bennetts
Add _SmartClient.call_with_body_bytes, plus some server-side code for handling bodies delivered in multiple parts.
116
        if self.expecting == 'body':
3923.5.4 by Andrew Bennetts
Allow a request's body part(s) to be followed by an error.
117
            if byte == 'S':
118
                # Success.  Nothing more to come except the end of message.
119
                self.expecting = 'end'
120
            elif byte == 'E':
121
                # Error.  Expect an error structure.
122
                self.expecting = 'error'
123
            else:
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
124
                raise errors.SmartProtocolError(
125
                    'Non-success status byte in request body: %r' % (byte,))
126
        else:
127
            raise errors.SmartProtocolError(
128
                'Unexpected message part: byte(%r)' % (byte,))
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
129
130
    def structure_part_received(self, structure):
3923.5.4 by Andrew Bennetts
Allow a request's body part(s) to be followed by an error.
131
        if self.expecting == 'args':
132
            self._args_received(structure)
133
        elif self.expecting == 'error':
134
            self._error_received(structure)
135
        else:
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
136
            raise errors.SmartProtocolError(
137
                'Unexpected message part: structure(%r)' % (structure,))
3923.5.4 by Andrew Bennetts
Allow a request's body part(s) to be followed by an error.
138
139
    def _args_received(self, args):
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
140
        self.expecting = 'body'
4634.6.30 by Andrew Bennetts
Remove SmartServerRequest.dispatch_command, fix SmartServerRequest.args_received.
141
        self.request_handler.args_received(args)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
142
        if self.request_handler.finished_reading:
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
143
            self._response_sent = True
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
144
            self.responder.send_response(self.request_handler.response)
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
145
            self.expecting = 'end'
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
146
3923.5.4 by Andrew Bennetts
Allow a request's body part(s) to be followed by an error.
147
    def _error_received(self, error_args):
148
        self.expecting = 'end'
149
        self.request_handler.post_body_error_received(error_args)
150
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
151
    def bytes_part_received(self, bytes):
152
        if self.expecting == 'body':
153
            self._should_finish_body = True
154
            self.request_handler.accept_body(bytes)
155
        else:
156
            raise errors.SmartProtocolError(
157
                'Unexpected message part: bytes(%r)' % (bytes,))
158
159
    def end_received(self):
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.
160
        if self.expecting not in ['body', 'end']:
3923.5.3 by Andrew Bennetts
Raise a better exception if a premature message end happens.
161
            raise errors.SmartProtocolError(
162
                'End of message received prematurely (while expecting %s)'
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.
163
                % (self.expecting,))
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
164
        self.expecting = 'nothing'
165
        self.request_handler.end_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.
166
        if not self.request_handler.finished_reading:
167
            raise errors.SmartProtocolError(
168
                "Complete conventional request was received, but request "
169
                "handler has not finished reading.")
3842.3.4 by Andrew Bennetts
TestStacking.test_fetch_copies_from_stacked_on now passes using the VersionedFile.insert_record_stream RPC; lots of debugging cruft needs removal though.
170
        if not self._response_sent:
171
            self.responder.send_response(self.request_handler.response)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
172
173
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
174
class ResponseHandler(object):
175
    """Abstract base class for an object that handles a smart response."""
176
177
    def read_response_tuple(self, expect_body=False):
178
        """Reads and returns the response tuple for the current request.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
179
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
180
        :keyword expect_body: a boolean indicating if a body is expected in the
181
            response.  Some protocol versions needs this information to know
182
            when a response is finished.  If False, read_body_bytes should
183
            *not* be called afterwards.  Defaults to False.
184
        :returns: tuple of response arguments.
185
        """
186
        raise NotImplementedError(self.read_response_tuple)
187
188
    def read_body_bytes(self, count=-1):
189
        """Read and return some bytes from the body.
190
191
        :param count: if specified, read up to this many bytes.  By default,
192
            reads the entire body.
193
        :returns: str of bytes from the response body.
194
        """
195
        raise NotImplementedError(self.read_body_bytes)
196
197
    def read_streamed_body(self):
198
        """Returns an iterable that reads and returns a series of body chunks.
199
        """
200
        raise NotImplementedError(self.read_streamed_body)
201
202
    def cancel_read_body(self):
203
        """Stop expecting a body for this response.
204
205
        If expect_body was passed to read_response_tuple, this cancels that
206
        expectation (and thus finishes reading the response, allowing a new
207
        request to be issued).  This is useful if a response turns out to be an
208
        error rather than a normal result with a body.
209
        """
210
        raise NotImplementedError(self.cancel_read_body)
211
212
213
class ConventionalResponseHandler(MessageHandler, ResponseHandler):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
214
215
    def __init__(self):
216
        MessageHandler.__init__(self)
217
        self.status = None
218
        self.args = None
3195.3.24 by Andrew Bennetts
Implement read_streamed_body on ConventionalResponseHandler.
219
        self._bytes_parts = collections.deque()
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
220
        self._body_started = False
221
        self._body_stream_status = None
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
222
        self._body = None
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
223
        self._body_error_args = None
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
224
        self.finished_reading = False
225
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
226
    def setProtoAndMediumRequest(self, protocol_decoder, medium_request):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
227
        self._protocol_decoder = protocol_decoder
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
228
        self._medium_request = medium_request
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
229
230
    def byte_part_received(self, byte):
231
        if byte not in ['E', 'S']:
232
            raise errors.SmartProtocolError(
233
                'Unknown response status: %r' % (byte,))
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
234
        if self._body_started:
235
            if self._body_stream_status is not None:
236
                raise errors.SmartProtocolError(
237
                    'Unexpected byte part received: %r' % (byte,))
238
            self._body_stream_status = byte
239
        else:
240
            if self.status is not None:
241
                raise errors.SmartProtocolError(
242
                    'Unexpected byte part received: %r' % (byte,))
243
            self.status = byte
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
244
245
    def bytes_part_received(self, bytes):
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
246
        self._body_started = True
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
247
        self._bytes_parts.append(bytes)
248
249
    def structure_part_received(self, structure):
6619.3.18 by Jelmer Vernooij
Run 2to3 idioms fixer.
250
        if not isinstance(structure, tuple):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
251
            raise errors.SmartProtocolError(
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
252
                'Args structure is not a sequence: %r' % (structure,))
253
        if not self._body_started:
254
            if self.args is not None:
255
                raise errors.SmartProtocolError(
256
                    'Unexpected structure received: %r (already got %r)'
257
                    % (structure, self.args))
258
            self.args = structure
259
        else:
260
            if self._body_stream_status != 'E':
261
                raise errors.SmartProtocolError(
262
                    'Unexpected structure received after body: %r'
263
                    % (structure,))
264
            self._body_error_args = structure
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
265
266
    def _wait_for_response_args(self):
267
        while self.args is None and not self.finished_reading:
268
            self._read_more()
269
270
    def _wait_for_response_end(self):
271
        while not self.finished_reading:
272
            self._read_more()
273
274
    def _read_more(self):
275
        next_read_size = self._protocol_decoder.next_read_size()
276
        if next_read_size == 0:
277
            # a complete request has been read.
278
            self.finished_reading = True
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
279
            self._medium_request.finished_reading()
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
280
            return
3750.1.2 by Vincent Ladeuil
Fixed as per Andrew's review.
281
        bytes = self._medium_request.read_bytes(next_read_size)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
282
        if bytes == '':
283
            # end of file encountered reading from server
3461.2.1 by Andrew Bennetts
Avoid unnecessary reconnections to old servers when the first HPSS is an error in the right protocol version.
284
            if 'hpss' in debug.debug_flags:
285
                mutter(
286
                    'decoder state: buf[:10]=%r, state_accept=%s',
3702.2.1 by Andrew Bennetts
Fix '_in_buffer' AttributeError when using the -Dhpss debug flag.
287
                    self._protocol_decoder._get_in_buffer()[:10],
3461.2.2 by Andrew Bennetts
Tweak suggested by John.
288
                    self._protocol_decoder.state_accept.__name__)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
289
            raise errors.ConnectionReset(
4509.2.1 by Martin Pool
Tweak hpss connection-dropped error message
290
                "Unexpected end of message. "
291
                "Please check connectivity and permissions, and report a bug "
292
                "if problems persist.")
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
293
        self._protocol_decoder.accept_bytes(bytes)
294
3245.4.47 by Andrew Bennetts
Don't automatically send 'hello' requests from RemoteBzrDirFormat.probe_transport unless we have to (i.e. the transport is HTTP).
295
    def protocol_error(self, exception):
296
        # Whatever the error is, we're done with this request.
297
        self.finished_reading = True
298
        self._medium_request.finished_reading()
299
        raise
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
300
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
301
    def read_response_tuple(self, expect_body=False):
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
302
        """Read a response tuple from the wire."""
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
303
        self._wait_for_response_args()
3195.3.18 by Andrew Bennetts
call_with_body_bytes now works with v3 (e.g. test_copy_content_remote_to_local passes). Lots of debugging cruft, though.
304
        if not expect_body:
305
            self._wait_for_response_end()
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
306
        if 'hpss' in debug.debug_flags:
307
            mutter('   result:   %r', self.args)
308
        if self.status == 'E':
309
            self._wait_for_response_end()
5677.2.3 by Martin
Gut smart.message._translate_error as it duplicates logic in remote
310
            _raise_smart_server_error(self.args)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
311
        return tuple(self.args)
312
313
    def read_body_bytes(self, count=-1):
314
        """Read bytes from the body, decoding into a byte stream.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
315
316
        We read all bytes at once to ensure we've checked the trailer for
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
317
        errors, and then feed the buffer back as read_body_bytes is called.
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
318
319
        Like the builtin file.read in Python, a count of -1 (the default) means
320
        read the entire body.
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
321
        """
3245.4.39 by Andrew Bennetts
Tweaks to bzrlib/smart/message.py suggested by John's review.
322
        # TODO: we don't necessarily need to buffer the full request if count
323
        # != -1.  (2008/04/30, Andrew Bennetts)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
324
        if self._body is None:
3195.3.18 by Andrew Bennetts
call_with_body_bytes now works with v3 (e.g. test_copy_content_remote_to_local passes). Lots of debugging cruft, though.
325
            self._wait_for_response_end()
3245.4.25 by Andrew Bennetts
Add some -Dhpss mutters to the protocol v3 code, so that it gives comparable debug logging to earlier protocols.
326
            body_bytes = ''.join(self._bytes_parts)
327
            if 'hpss' in debug.debug_flags:
328
                mutter('              %d body bytes read', len(body_bytes))
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
329
            self._body = BytesIO(body_bytes)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
330
            self._bytes_parts = None
331
        return self._body.read(count)
332
3195.3.24 by Andrew Bennetts
Implement read_streamed_body on ConventionalResponseHandler.
333
    def read_streamed_body(self):
334
        while not self.finished_reading:
335
            while self._bytes_parts:
3245.4.25 by Andrew Bennetts
Add some -Dhpss mutters to the protocol v3 code, so that it gives comparable debug logging to earlier protocols.
336
                bytes_part = self._bytes_parts.popleft()
4574.1.1 by Martin Pool
Move 'byte part read' messages to -Dhpssdetail
337
                if 'hpssdetail' in debug.debug_flags:
4070.9.10 by Andrew Bennetts
Revert some cruft.
338
                    mutter('              %d byte part read', len(bytes_part))
3245.4.25 by Andrew Bennetts
Add some -Dhpss mutters to the protocol v3 code, so that it gives comparable debug logging to earlier protocols.
339
                yield bytes_part
3195.3.24 by Andrew Bennetts
Implement read_streamed_body on ConventionalResponseHandler.
340
            self._read_more()
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
341
        if self._body_stream_status == 'E':
5677.2.3 by Martin
Gut smart.message._translate_error as it duplicates logic in remote
342
            _raise_smart_server_error(self._body_error_args)
3195.3.24 by Andrew Bennetts
Implement read_streamed_body on ConventionalResponseHandler.
343
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
344
    def cancel_read_body(self):
345
        self._wait_for_response_end()
3245.4.5 by Andrew Bennetts
Implement interrupting body streams with an error.
346
347
5677.2.3 by Martin
Gut smart.message._translate_error as it duplicates logic in remote
348
def _raise_smart_server_error(error_tuple):
349
    """Raise exception based on tuple received from smart server
350
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
351
    Specific error translation is handled by breezy.remote._translate_error
5677.2.3 by Martin
Gut smart.message._translate_error as it duplicates logic in remote
352
    """
353
    if error_tuple[0] == 'UnknownMethod':
354
        raise errors.UnknownSmartMethod(error_tuple[1])
355
    raise errors.ErrorFromSmartServer(error_tuple)