~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.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
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.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
16
2018.5.19 by Andrew Bennetts
Add docstrings to all the new modules, and a few other places.
17
"""Wire-level encoding and decoding of requests and responses for the smart
18
client and server.
19
"""
20
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
21
import collections
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
22
from cStringIO import StringIO
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.
23
import struct
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
24
import sys
2664.4.1 by John Arbash Meinel
Add timing information for call/response groups for hpss
25
import time
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
26
3195.3.13 by Andrew Bennetts
Start writing call* methods for version 3 of the HPSS client protocol.
27
import bzrlib
2593.3.1 by Andrew Bennetts
Add a -Dhpss debug flag.
28
from bzrlib import debug
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
29
from bzrlib import errors
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
30
from bzrlib.smart import message, request
2621.3.1 by Andrew Bennetts
Log errors from the smart server in the trace file, to make debugging test failures (and live failures!) easier.
31
from bzrlib.trace import log_exception_quietly, mutter
2694.5.4 by Jelmer Vernooij
Move bzrlib.util.bencode to bzrlib._bencode_py.
32
from bzrlib.bencode import bdecode_as_tuple, bencode
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
33
34
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
35
# Protocol version strings.  These are sent as prefixes of bzr requests and
36
# responses to identify the protocol version being used. (There are no version
37
# one strings because that version doesn't send any).
38
REQUEST_VERSION_TWO = 'bzr request 2\n'
39
RESPONSE_VERSION_TWO = 'bzr response 2\n'
40
3245.4.60 by Andrew Bennetts
Update the protocol v3 version string to say 'bzr 1.6'.
41
MESSAGE_VERSION_THREE = 'bzr message 3 (bzr 1.6)\n'
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
42
RESPONSE_VERSION_THREE = REQUEST_VERSION_THREE = MESSAGE_VERSION_THREE
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.
43
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
44
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
45
def _recv_tuple(from_file):
46
    req_line = from_file.readline()
47
    return _decode_tuple(req_line)
48
49
50
def _decode_tuple(req_line):
3376.2.11 by Martin Pool
Compare to None using is/is not not ==
51
    if req_line is None or req_line == '':
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
52
        return None
53
    if req_line[-1] != '\n':
54
        raise errors.SmartProtocolError("request %r not terminated" % req_line)
55
    return tuple(req_line[:-1].split('\x01'))
56
57
58
def _encode_tuple(args):
59
    """Encode the tuple args to a bytestream."""
60
    return '\x01'.join(args) + '\n'
61
62
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
63
class Requester(object):
64
    """Abstract base class for an object that can issue requests on a smart
65
    medium.
66
    """
67
68
    def call(self, *args):
69
        """Make a remote call.
70
71
        :param args: the arguments of this call.
72
        """
73
        raise NotImplementedError(self.call)
74
75
    def call_with_body_bytes(self, args, body):
76
        """Make a remote call with a body.
77
78
        :param args: the arguments of this call.
79
        :type body: str
80
        :param body: the body to send with the request.
81
        """
82
        raise NotImplementedError(self.call_with_body_bytes)
83
84
    def call_with_body_readv_array(self, args, body):
85
        """Make a remote call with a readv array.
86
87
        :param args: the arguments of this call.
88
        :type body: iterable of (start, length) tuples.
89
        :param body: the readv ranges to send with this request.
90
        """
91
        raise NotImplementedError(self.call_with_body_readv_array)
92
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
93
    def set_headers(self, headers):
94
        raise NotImplementedError(self.set_headers)
95
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
96
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
97
class SmartProtocolBase(object):
98
    """Methods common to client and server"""
99
100
    # TODO: this only actually accomodates a single block; possibly should
101
    # support multiple chunks?
102
    def _encode_bulk_data(self, body):
103
        """Encode body as a bulk data chunk."""
104
        return ''.join(('%d\n' % len(body), body, 'done\n'))
105
106
    def _serialise_offsets(self, offsets):
107
        """Serialise a readv offset list."""
108
        txt = []
109
        for start, length in offsets:
110
            txt.append('%d,%d' % (start, length))
111
        return '\n'.join(txt)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
112
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
113
114
class SmartServerRequestProtocolOne(SmartProtocolBase):
115
    """Server-side encoding and decoding logic for smart version 1."""
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
116
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).
117
    def __init__(self, backing_transport, write_func, root_client_path='/',
118
            jail_root=None):
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
119
        self._backing_transport = backing_transport
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
120
        self._root_client_path = root_client_path
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).
121
        self._jail_root = jail_root
3245.4.21 by Andrew Bennetts
Remove 'excess_buffer' attribute and another crufty comment.
122
        self.unused_data = ''
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
123
        self._finished = False
124
        self.in_buffer = ''
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
125
        self._has_dispatched = False
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
126
        self.request = None
127
        self._body_decoder = None
2664.4.6 by John Arbash Meinel
Restore a line that shouldn't have been removed
128
        self._write_func = write_func
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
129
130
    def accept_bytes(self, bytes):
131
        """Take bytes, and advance the internal state machine appropriately.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
132
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
133
        :param bytes: must be a byte string
134
        """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
135
        if not isinstance(bytes, str):
136
            raise ValueError(bytes)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
137
        self.in_buffer += bytes
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
138
        if not self._has_dispatched:
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
139
            if '\n' not in self.in_buffer:
140
                # no command line yet
141
                return
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
142
            self._has_dispatched = True
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
143
            try:
144
                first_line, self.in_buffer = self.in_buffer.split('\n', 1)
145
                first_line += '\n'
146
                req_args = _decode_tuple(first_line)
2018.5.14 by Andrew Bennetts
Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py.
147
                self.request = request.SmartServerRequestHandler(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
148
                    self._backing_transport, commands=request.request_handlers,
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).
149
                    root_client_path=self._root_client_path,
150
                    jail_root=self._jail_root)
4634.6.30 by Andrew Bennetts
Remove SmartServerRequest.dispatch_command, fix SmartServerRequest.args_received.
151
                self.request.args_received(req_args)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
152
                if self.request.finished_reading:
153
                    # trivial request
3245.4.21 by Andrew Bennetts
Remove 'excess_buffer' attribute and another crufty comment.
154
                    self.unused_data = self.in_buffer
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
155
                    self.in_buffer = ''
2432.4.3 by Robert Collins
Refactor the HPSS Response code to take SmartServerResponse rather than args and body.
156
                    self._send_response(self.request.response)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
157
            except KeyboardInterrupt:
158
                raise
3245.4.29 by Andrew Bennetts
Add/tidy some comments, remove dud test_errors_are_logged test, add explicit UnknownSmartMethod to v3.
159
            except errors.UnknownSmartMethod, err:
160
                protocol_error = errors.SmartProtocolError(
161
                    "bad request %r" % (err.verb,))
162
                failure = request.FailedSmartServerResponse(
163
                    ('error', str(protocol_error)))
164
                self._send_response(failure)
165
                return
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
166
            except Exception, exception:
167
                # everything else: pass to client, flush, and quit
2621.3.1 by Andrew Bennetts
Log errors from the smart server in the trace file, to make debugging test failures (and live failures!) easier.
168
                log_exception_quietly()
2432.4.3 by Robert Collins
Refactor the HPSS Response code to take SmartServerResponse rather than args and body.
169
                self._send_response(request.FailedSmartServerResponse(
170
                    ('error', str(exception))))
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
171
                return
172
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
173
        if self._has_dispatched:
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
174
            if self._finished:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
175
                # nothing to do.XXX: this routine should be a single state
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
176
                # machine too.
3245.4.21 by Andrew Bennetts
Remove 'excess_buffer' attribute and another crufty comment.
177
                self.unused_data += self.in_buffer
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
178
                self.in_buffer = ''
179
                return
180
            if self._body_decoder is None:
181
                self._body_decoder = LengthPrefixedBodyDecoder()
182
            self._body_decoder.accept_bytes(self.in_buffer)
183
            self.in_buffer = self._body_decoder.unused_data
184
            body_data = self._body_decoder.read_pending_data()
185
            self.request.accept_body(body_data)
186
            if self._body_decoder.finished_reading:
187
                self.request.end_of_body()
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
188
                if not self.request.finished_reading:
189
                    raise AssertionError("no more body, request not finished")
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
190
            if self.request.response is not None:
2432.4.3 by Robert Collins
Refactor the HPSS Response code to take SmartServerResponse rather than args and body.
191
                self._send_response(self.request.response)
3245.4.21 by Andrew Bennetts
Remove 'excess_buffer' attribute and another crufty comment.
192
                self.unused_data = self.in_buffer
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
193
                self.in_buffer = ''
194
            else:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
195
                if self.request.finished_reading:
196
                    raise AssertionError(
197
                        "no response and we have finished reading.")
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
198
2432.4.3 by Robert Collins
Refactor the HPSS Response code to take SmartServerResponse rather than args and body.
199
    def _send_response(self, response):
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
200
        """Send a smart server response down the output stream."""
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
201
        if self._finished:
202
            raise AssertionError('response already sent')
2432.4.3 by Robert Collins
Refactor the HPSS Response code to take SmartServerResponse rather than args and body.
203
        args = response.args
204
        body = response.body
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
205
        self._finished = True
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
206
        self._write_protocol_version()
2432.4.6 by Robert Collins
Include success/failure feedback in SmartProtocolTwo responses to allow robust handling in the future.
207
        self._write_success_or_failure_prefix(response)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
208
        self._write_func(_encode_tuple(args))
209
        if body is not None:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
210
            if not isinstance(body, str):
211
                raise ValueError(body)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
212
            bytes = self._encode_bulk_data(body)
213
            self._write_func(bytes)
214
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
215
    def _write_protocol_version(self):
216
        """Write any prefixes this protocol requires.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
217
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
218
        Version one doesn't send protocol versions.
219
        """
220
2432.4.6 by Robert Collins
Include success/failure feedback in SmartProtocolTwo responses to allow robust handling in the future.
221
    def _write_success_or_failure_prefix(self, response):
222
        """Write the protocol specific success/failure prefix.
223
224
        For SmartServerRequestProtocolOne this is omitted but we
225
        call is_successful to ensure that the response is valid.
226
        """
227
        response.is_successful()
228
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
229
    def next_read_size(self):
230
        if self._finished:
231
            return 0
232
        if self._body_decoder is None:
233
            return 1
234
        else:
235
            return self._body_decoder.next_read_size()
236
237
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
238
class SmartServerRequestProtocolTwo(SmartServerRequestProtocolOne):
239
    r"""Version two of the server side of the smart protocol.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
240
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
241
    This prefixes responses with the value of RESPONSE_VERSION_TWO.
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
242
    """
243
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.
244
    response_marker = RESPONSE_VERSION_TWO
245
    request_marker = REQUEST_VERSION_TWO
246
2432.4.6 by Robert Collins
Include success/failure feedback in SmartProtocolTwo responses to allow robust handling in the future.
247
    def _write_success_or_failure_prefix(self, response):
248
        """Write the protocol specific success/failure prefix."""
249
        if response.is_successful():
250
            self._write_func('success\n')
251
        else:
252
            self._write_func('failed\n')
253
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
254
    def _write_protocol_version(self):
255
        r"""Write any prefixes this protocol requires.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
256
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
257
        Version two sends the value of RESPONSE_VERSION_TWO.
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
258
        """
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.
259
        self._write_func(self.response_marker)
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
260
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
261
    def _send_response(self, response):
262
        """Send a smart server response down the output stream."""
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
263
        if (self._finished):
264
            raise AssertionError('response already sent')
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
265
        self._finished = True
266
        self._write_protocol_version()
267
        self._write_success_or_failure_prefix(response)
268
        self._write_func(_encode_tuple(response.args))
269
        if response.body is not None:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
270
            if not isinstance(response.body, str):
271
                raise AssertionError('body must be a str')
272
            if not (response.body_stream is None):
273
                raise AssertionError(
274
                    'body_stream and body cannot both be set')
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
275
            bytes = self._encode_bulk_data(response.body)
276
            self._write_func(bytes)
277
        elif response.body_stream is not None:
2748.4.10 by Andrew Bennetts
Fix chunking serialisation to be current with the latest changes to the protocol, and improve the tests to make it harder to have them desynchronised.
278
            _send_stream(response.body_stream, self._write_func)
279
280
281
def _send_stream(stream, write_func):
2748.4.16 by Andrew Bennetts
Tweaks suggested by review.
282
    write_func('chunked\n')
2748.4.10 by Andrew Bennetts
Fix chunking serialisation to be current with the latest changes to the protocol, and improve the tests to make it harder to have them desynchronised.
283
    _send_chunks(stream, write_func)
284
    write_func('END\n')
2748.4.4 by Andrew Bennetts
Extract a _send_chunks function to make testing easier.
285
286
287
def _send_chunks(stream, write_func):
288
    for chunk in stream:
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
289
        if isinstance(chunk, str):
290
            bytes = "%x\n%s" % (len(chunk), chunk)
291
            write_func(bytes)
292
        elif isinstance(chunk, request.FailedSmartServerResponse):
2748.4.10 by Andrew Bennetts
Fix chunking serialisation to be current with the latest changes to the protocol, and improve the tests to make it harder to have them desynchronised.
293
            write_func('ERR\n')
294
            _send_chunks(chunk.args, write_func)
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
295
            return
296
        else:
2535.4.19 by Andrew Bennetts
Fix some trivial NameErrors in error handling.
297
            raise errors.BzrError(
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
298
                'Chunks must be str or FailedSmartServerResponse, got %r'
2535.4.19 by Andrew Bennetts
Fix some trivial NameErrors in error handling.
299
                % chunk)
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
300
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
301
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
302
class _NeedMoreBytes(Exception):
303
    """Raise this inside a _StatefulDecoder to stop decoding until more bytes
304
    have been received.
305
    """
306
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.
307
    def __init__(self, count=None):
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
308
        """Constructor.
309
310
        :param count: the total number of bytes needed by the current state.
311
            May be None if the number of bytes needed is unknown.
312
        """
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.
313
        self.count = count
314
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
315
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
316
class _StatefulDecoder(object):
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
317
    """Base class for writing state machines to decode byte streams.
318
319
    Subclasses should provide a self.state_accept attribute that accepts bytes
320
    and, if appropriate, updates self.state_accept to a different function.
321
    accept_bytes will call state_accept as often as necessary to make sure the
322
    state machine has progressed as far as possible before it returns.
323
324
    See ProtocolThreeDecoder for an example subclass.
325
    """
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
326
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
327
    def __init__(self):
328
        self.finished_reading = False
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
329
        self._in_buffer_list = []
330
        self._in_buffer_len = 0
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
331
        self.unused_data = ''
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
332
        self.bytes_left = None
3195.3.22 by Andrew Bennetts
Fix more tests.
333
        self._number_needed_bytes = None
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
334
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
335
    def _get_in_buffer(self):
336
        if len(self._in_buffer_list) == 1:
337
            return self._in_buffer_list[0]
338
        in_buffer = ''.join(self._in_buffer_list)
3649.5.5 by John Arbash Meinel
Fix the test suite.
339
        if len(in_buffer) != self._in_buffer_len:
340
            raise AssertionError(
341
                "Length of buffer did not match expected value: %s != %s"
342
                % self._in_buffer_len, len(in_buffer))
3649.5.2 by John Arbash Meinel
When we are waiting on a big stream, allow
343
        self._in_buffer_list = [in_buffer]
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
344
        return in_buffer
345
3649.5.2 by John Arbash Meinel
When we are waiting on a big stream, allow
346
    def _get_in_bytes(self, count):
347
        """Grab X bytes from the input_buffer.
348
349
        Callers should have already checked that self._in_buffer_len is >
350
        count. Note, this does not consume the bytes from the buffer. The
351
        caller will still need to call _get_in_buffer() and then
352
        _set_in_buffer() if they actually need to consume the bytes.
353
        """
354
        # check if we can yield the bytes from just the first entry in our list
3649.5.5 by John Arbash Meinel
Fix the test suite.
355
        if len(self._in_buffer_list) == 0:
356
            raise AssertionError('Callers must be sure we have buffered bytes'
357
                ' before calling _get_in_bytes')
3649.5.2 by John Arbash Meinel
When we are waiting on a big stream, allow
358
        if len(self._in_buffer_list[0]) > count:
359
            return self._in_buffer_list[0][:count]
360
        # We can't yield it from the first buffer, so collapse all buffers, and
361
        # yield it from that
362
        in_buf = self._get_in_buffer()
363
        return in_buf[:count]
364
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
365
    def _set_in_buffer(self, new_buf):
366
        if new_buf is not None:
367
            self._in_buffer_list = [new_buf]
368
            self._in_buffer_len = len(new_buf)
369
        else:
370
            self._in_buffer_list = []
371
            self._in_buffer_len = 0
372
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
373
    def accept_bytes(self, bytes):
374
        """Decode as much of bytes as possible.
375
376
        If 'bytes' contains too much data it will be appended to
377
        self.unused_data.
378
379
        finished_reading will be set when no more data is required.  Further
380
        data will be appended to self.unused_data.
381
        """
382
        # accept_bytes is allowed to change the state
3195.3.22 by Andrew Bennetts
Fix more tests.
383
        self._number_needed_bytes = None
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
384
        # lsprof puts a very large amount of time on this specific call for
385
        # large readv arrays
386
        self._in_buffer_list.append(bytes)
387
        self._in_buffer_len += len(bytes)
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
388
        try:
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
389
            # Run the function for the current state.
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
390
            current_state = self.state_accept
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
391
            self.state_accept()
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
392
            while current_state != self.state_accept:
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
393
                # The current state has changed.  Run the function for the new
394
                # current state, so that it can:
395
                #   - decode any unconsumed bytes left in a buffer, and
396
                #   - signal how many more bytes are expected (via raising
397
                #     _NeedMoreBytes).
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
398
                current_state = self.state_accept
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
399
                self.state_accept()
3195.3.22 by Andrew Bennetts
Fix more tests.
400
        except _NeedMoreBytes, e:
401
            self._number_needed_bytes = e.count
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
402
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
403
404
class ChunkedBodyDecoder(_StatefulDecoder):
405
    """Decoder for chunked body data.
406
2748.4.9 by Andrew Bennetts
Merge from hpss-protocol-docs.
407
    This is very similar the HTTP's chunked encoding.  See the description of
408
    streamed body data in `doc/developers/network-protocol.txt` for details.
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
409
    """
410
411
    def __init__(self):
412
        _StatefulDecoder.__init__(self)
2748.4.16 by Andrew Bennetts
Tweaks suggested by review.
413
        self.state_accept = self._state_accept_expecting_header
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
414
        self.chunk_in_progress = None
415
        self.chunks = collections.deque()
2748.4.6 by Andrew Bennetts
Use chunks for stream errors, rather than the response tuple format.
416
        self.error = False
417
        self.error_in_progress = None
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
418
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
419
    def next_read_size(self):
2748.4.7 by Andrew Bennetts
Change the end-of-body marker to something clearer than a zero-length chunk.
420
        # Note: the shortest possible chunk is 2 bytes: '0\n', and the
421
        # end-of-body marker is 4 bytes: 'END\n'.
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
422
        if self.state_accept == self._state_accept_reading_chunk:
423
            # We're expecting more chunk content.  So we're expecting at least
2748.4.7 by Andrew Bennetts
Change the end-of-body marker to something clearer than a zero-length chunk.
424
            # the rest of this chunk plus an END chunk.
425
            return self.bytes_left + 4
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
426
        elif self.state_accept == self._state_accept_expecting_length:
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
427
            if self._in_buffer_len == 0:
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
428
                # We're expecting a chunk length.  There's at least two bytes
429
                # left: a digit plus '\n'.
430
                return 2
431
            else:
432
                # We're in the middle of reading a chunk length.  So there's at
433
                # least one byte left, the '\n' that terminates the length.
434
                return 1
435
        elif self.state_accept == self._state_accept_reading_unused:
436
            return 1
2748.4.16 by Andrew Bennetts
Tweaks suggested by review.
437
        elif self.state_accept == self._state_accept_expecting_header:
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
438
            return max(0, len('chunked\n') - self._in_buffer_len)
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
439
        else:
440
            raise AssertionError("Impossible state: %r" % (self.state_accept,))
441
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
442
    def read_next_chunk(self):
443
        try:
444
            return self.chunks.popleft()
445
        except IndexError:
446
            return None
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
447
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
448
    def _extract_line(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
449
        in_buf = self._get_in_buffer()
450
        pos = in_buf.find('\n')
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
451
        if pos == -1:
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
452
            # We haven't read a complete line yet, so request more bytes before
453
            # we continue.
3245.4.29 by Andrew Bennetts
Add/tidy some comments, remove dud test_errors_are_logged test, add explicit UnknownSmartMethod to v3.
454
            raise _NeedMoreBytes(1)
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
455
        line = in_buf[:pos]
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
456
        # Trim the prefix (including '\n' delimiter) from the _in_buffer.
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
457
        self._set_in_buffer(in_buf[pos+1:])
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
458
        return line
459
460
    def _finished(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
461
        self.unused_data = self._get_in_buffer()
462
        self._in_buffer_list = []
463
        self._in_buffer_len = 0
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
464
        self.state_accept = self._state_accept_reading_unused
2748.4.6 by Andrew Bennetts
Use chunks for stream errors, rather than the response tuple format.
465
        if self.error:
466
            error_args = tuple(self.error_in_progress)
467
            self.chunks.append(request.FailedSmartServerResponse(error_args))
468
            self.error_in_progress = None
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
469
        self.finished_reading = True
470
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
471
    def _state_accept_expecting_header(self):
2748.4.16 by Andrew Bennetts
Tweaks suggested by review.
472
        prefix = self._extract_line()
3195.3.8 by Andrew Bennetts
Use _NeedMoreBytes to improve earlier protocol implementations a little, and make test_errors_are_logged pass.
473
        if prefix == 'chunked':
2748.4.16 by Andrew Bennetts
Tweaks suggested by review.
474
            self.state_accept = self._state_accept_expecting_length
475
        else:
476
            raise errors.SmartProtocolError(
477
                'Bad chunked body header: "%s"' % (prefix,))
478
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
479
    def _state_accept_expecting_length(self):
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
480
        prefix = self._extract_line()
3195.3.8 by Andrew Bennetts
Use _NeedMoreBytes to improve earlier protocol implementations a little, and make test_errors_are_logged pass.
481
        if prefix == 'ERR':
2748.4.6 by Andrew Bennetts
Use chunks for stream errors, rather than the response tuple format.
482
            self.error = True
483
            self.error_in_progress = []
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
484
            self._state_accept_expecting_length()
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
485
            return
2748.4.7 by Andrew Bennetts
Change the end-of-body marker to something clearer than a zero-length chunk.
486
        elif prefix == 'END':
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
487
            # We've read the end-of-body marker.
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
488
            # Any further bytes are unused data, including the bytes left in
489
            # the _in_buffer.
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
490
            self._finished()
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
491
            return
2748.4.7 by Andrew Bennetts
Change the end-of-body marker to something clearer than a zero-length chunk.
492
        else:
493
            self.bytes_left = int(prefix, 16)
494
            self.chunk_in_progress = ''
495
            self.state_accept = self._state_accept_reading_chunk
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
496
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
497
    def _state_accept_reading_chunk(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
498
        in_buf = self._get_in_buffer()
499
        in_buffer_len = len(in_buf)
500
        self.chunk_in_progress += in_buf[:self.bytes_left]
501
        self._set_in_buffer(in_buf[self.bytes_left:])
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
502
        self.bytes_left -= in_buffer_len
503
        if self.bytes_left <= 0:
504
            # Finished with chunk
505
            self.bytes_left = None
2748.4.6 by Andrew Bennetts
Use chunks for stream errors, rather than the response tuple format.
506
            if self.error:
507
                self.error_in_progress.append(self.chunk_in_progress)
508
            else:
509
                self.chunks.append(self.chunk_in_progress)
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
510
            self.chunk_in_progress = None
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
511
            self.state_accept = self._state_accept_expecting_length
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
512
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
513
    def _state_accept_reading_unused(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
514
        self.unused_data += self._get_in_buffer()
515
        self._in_buffer_list = []
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
516
517
518
class LengthPrefixedBodyDecoder(_StatefulDecoder):
519
    """Decodes the length-prefixed bulk data."""
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
520
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
521
    def __init__(self):
522
        _StatefulDecoder.__init__(self)
523
        self.state_accept = self._state_accept_expecting_length
524
        self.state_read = self._state_read_no_data
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
525
        self._body = ''
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
526
        self._trailer_buffer = ''
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
527
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
528
    def next_read_size(self):
529
        if self.bytes_left is not None:
530
            # Ideally we want to read all the remainder of the body and the
531
            # trailer in one go.
532
            return self.bytes_left + 5
533
        elif self.state_accept == self._state_accept_reading_trailer:
534
            # Just the trailer left
535
            return 5 - len(self._trailer_buffer)
536
        elif self.state_accept == self._state_accept_expecting_length:
537
            # There's still at least 6 bytes left ('\n' to end the length, plus
538
            # 'done\n').
539
            return 6
540
        else:
541
            # Reading excess data.  Either way, 1 byte at a time is fine.
542
            return 1
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
543
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
544
    def read_pending_data(self):
545
        """Return any pending data that has been decoded."""
546
        return self.state_read()
547
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
548
    def _state_accept_expecting_length(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
549
        in_buf = self._get_in_buffer()
550
        pos = in_buf.find('\n')
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
551
        if pos == -1:
552
            return
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
553
        self.bytes_left = int(in_buf[:pos])
554
        self._set_in_buffer(in_buf[pos+1:])
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
555
        self.state_accept = self._state_accept_reading_body
556
        self.state_read = self._state_read_body_buffer
557
558
    def _state_accept_reading_body(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
559
        in_buf = self._get_in_buffer()
560
        self._body += in_buf
561
        self.bytes_left -= len(in_buf)
562
        self._set_in_buffer(None)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
563
        if self.bytes_left <= 0:
564
            # Finished with body
565
            if self.bytes_left != 0:
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
566
                self._trailer_buffer = self._body[self.bytes_left:]
567
                self._body = self._body[:self.bytes_left]
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
568
            self.bytes_left = None
569
            self.state_accept = self._state_accept_reading_trailer
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
570
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
571
    def _state_accept_reading_trailer(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
572
        self._trailer_buffer += self._get_in_buffer()
573
        self._set_in_buffer(None)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
574
        # TODO: what if the trailer does not match "done\n"?  Should this raise
575
        # a ProtocolViolation exception?
576
        if self._trailer_buffer.startswith('done\n'):
577
            self.unused_data = self._trailer_buffer[len('done\n'):]
578
            self.state_accept = self._state_accept_reading_unused
579
            self.finished_reading = True
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
580
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
581
    def _state_accept_reading_unused(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
582
        self.unused_data += self._get_in_buffer()
583
        self._set_in_buffer(None)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
584
585
    def _state_read_no_data(self):
586
        return ''
587
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
588
    def _state_read_body_buffer(self):
589
        result = self._body
590
        self._body = ''
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
591
        return result
592
593
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
594
class SmartClientRequestProtocolOne(SmartProtocolBase, Requester,
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
595
                                    message.ResponseHandler):
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
596
    """The client-side protocol for smart version 1."""
597
598
    def __init__(self, request):
599
        """Construct a SmartClientRequestProtocolOne.
600
601
        :param request: A SmartClientMediumRequest to serialise onto and
602
            deserialise from.
603
        """
604
        self._request = request
605
        self._body_buffer = None
2664.4.1 by John Arbash Meinel
Add timing information for call/response groups for hpss
606
        self._request_start_time = None
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
607
        self._last_verb = None
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
608
        self._headers = None
609
610
    def set_headers(self, headers):
611
        self._headers = dict(headers)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
612
613
    def call(self, *args):
2593.3.1 by Andrew Bennetts
Add a -Dhpss debug flag.
614
        if 'hpss' in debug.debug_flags:
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
615
            mutter('hpss call:   %s', repr(args)[1:-1])
3104.4.2 by Andrew Bennetts
All tests passing.
616
            if getattr(self._request._medium, 'base', None) is not None:
617
                mutter('             (to %s)', self._request._medium.base)
2664.4.1 by John Arbash Meinel
Add timing information for call/response groups for hpss
618
            self._request_start_time = time.time()
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
619
        self._write_args(args)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
620
        self._request.finished_writing()
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
621
        self._last_verb = args[0]
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
622
623
    def call_with_body_bytes(self, args, body):
624
        """Make a remote call of args with body bytes 'body'.
625
626
        After calling this, call read_response_tuple to find the result out.
627
        """
2593.3.1 by Andrew Bennetts
Add a -Dhpss debug flag.
628
        if 'hpss' in debug.debug_flags:
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
629
            mutter('hpss call w/body: %s (%r...)', repr(args)[1:-1], body[:20])
3104.4.2 by Andrew Bennetts
All tests passing.
630
            if getattr(self._request._medium, '_path', None) is not None:
631
                mutter('                  (to %s)', self._request._medium._path)
2664.4.4 by John Arbash Meinel
Switch around what bytes get logged.
632
            mutter('              %d bytes', len(body))
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
633
            self._request_start_time = time.time()
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
634
            if 'hpssdetail' in debug.debug_flags:
635
                mutter('hpss body content: %s', body)
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
636
        self._write_args(args)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
637
        bytes = self._encode_bulk_data(body)
638
        self._request.accept_bytes(bytes)
639
        self._request.finished_writing()
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
640
        self._last_verb = args[0]
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
641
642
    def call_with_body_readv_array(self, args, body):
643
        """Make a remote call with a readv array.
644
645
        The body is encoded with one line per readv offset pair. The numbers in
646
        each pair are separated by a comma, and no trailing \n is emitted.
647
        """
2593.3.1 by Andrew Bennetts
Add a -Dhpss debug flag.
648
        if 'hpss' in debug.debug_flags:
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
649
            mutter('hpss call w/readv: %s', repr(args)[1:-1])
3104.4.2 by Andrew Bennetts
All tests passing.
650
            if getattr(self._request._medium, '_path', None) is not None:
651
                mutter('                  (to %s)', self._request._medium._path)
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
652
            self._request_start_time = time.time()
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
653
        self._write_args(args)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
654
        readv_bytes = self._serialise_offsets(body)
655
        bytes = self._encode_bulk_data(readv_bytes)
656
        self._request.accept_bytes(bytes)
657
        self._request.finished_writing()
2664.4.2 by John Arbash Meinel
Add debug timings for operations that have to send data
658
        if 'hpss' in debug.debug_flags:
2664.4.4 by John Arbash Meinel
Switch around what bytes get logged.
659
            mutter('              %d bytes in readv request', len(readv_bytes))
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
660
        self._last_verb = args[0]
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
661
3842.3.5 by Andrew Bennetts
Remove some debugging cruft, make more tests pass.
662
    def call_with_body_stream(self, args, stream):
663
        # Protocols v1 and v2 don't support body streams.  So it's safe to
664
        # assume that a v1/v2 server doesn't support whatever method we're
665
        # trying to call with a body stream.
3842.3.7 by Andrew Bennetts
Implement a simple fallback (that buffers the whole record stream) for dealing with older servers.
666
        self._request.finished_writing()
667
        self._request.finished_reading()
3842.3.5 by Andrew Bennetts
Remove some debugging cruft, make more tests pass.
668
        raise errors.UnknownSmartMethod(args[0])
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
669
670
    def cancel_read_body(self):
671
        """After expecting a body, a response code may indicate one otherwise.
672
673
        This method lets the domain client inform the protocol that no body
674
        will be transmitted. This is a terminal method: after calling it the
675
        protocol is not able to be used further.
676
        """
677
        self._request.finished_reading()
678
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
679
    def _read_response_tuple(self):
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
680
        result = self._recv_tuple()
2593.3.1 by Andrew Bennetts
Add a -Dhpss debug flag.
681
        if 'hpss' in debug.debug_flags:
2664.4.1 by John Arbash Meinel
Add timing information for call/response groups for hpss
682
            if self._request_start_time is not None:
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
683
                mutter('   result:   %6.3fs  %s',
2664.4.1 by John Arbash Meinel
Add timing information for call/response groups for hpss
684
                       time.time() - self._request_start_time,
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
685
                       repr(result)[1:-1])
2664.4.1 by John Arbash Meinel
Add timing information for call/response groups for hpss
686
                self._request_start_time = None
687
            else:
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
688
                mutter('   result:   %s', repr(result)[1:-1])
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
689
        return result
690
691
    def read_response_tuple(self, expect_body=False):
692
        """Read a response tuple from the wire.
693
694
        This should only be called once.
695
        """
696
        result = self._read_response_tuple()
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
697
        self._response_is_unknown_method(result)
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
698
        self._raise_args_if_error(result)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
699
        if not expect_body:
700
            self._request.finished_reading()
701
        return result
702
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
703
    def _raise_args_if_error(self, result_tuple):
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
704
        # Later protocol versions have an explicit flag in the protocol to say
705
        # if an error response is "failed" or not.  In version 1 we don't have
706
        # that luxury.  So here is a complete list of errors that can be
707
        # returned in response to existing version 1 smart requests.  Responses
708
        # starting with these codes are always "failed" responses.
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
709
        v1_error_codes = [
710
            'norepository',
711
            'NoSuchFile',
712
            'FileExists',
713
            'DirectoryNotEmpty',
714
            'ShortReadvError',
715
            'UnicodeEncodeError',
716
            'UnicodeDecodeError',
717
            'ReadOnlyError',
718
            'nobranch',
719
            'NoSuchRevision',
720
            'nosuchrevision',
721
            'LockContention',
722
            'UnlockableTransport',
723
            'LockFailed',
724
            'TokenMismatch',
725
            'ReadError',
726
            'PermissionDenied',
727
            ]
728
        if result_tuple[0] in v1_error_codes:
729
            self._request.finished_reading()
730
            raise errors.ErrorFromSmartServer(result_tuple)
731
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
732
    def _response_is_unknown_method(self, result_tuple):
733
        """Raise UnexpectedSmartServerResponse if the response is an 'unknonwn
734
        method' response to the request.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
735
3297.3.1 by Andrew Bennetts
Raise UnknownSmartMethod automatically from read_response_tuple.
736
        :param response: The response from a smart client call_expecting_body
737
            call.
738
        :param verb: The verb used in that call.
739
        :raises: UnexpectedSmartServerResponse
740
        """
741
        if (result_tuple == ('error', "Generic bzr smart protocol error: "
742
                "bad request '%s'" % self._last_verb) or
743
              result_tuple == ('error', "Generic bzr smart protocol error: "
744
                "bad request u'%s'" % self._last_verb)):
745
            # The response will have no body, so we've finished reading.
746
            self._request.finished_reading()
747
            raise errors.UnknownSmartMethod(self._last_verb)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
748
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
749
    def read_body_bytes(self, count=-1):
750
        """Read bytes from the body, decoding into a byte stream.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
751
752
        We read all bytes at once to ensure we've checked the trailer for
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
753
        errors, and then feed the buffer back as read_body_bytes is called.
754
        """
755
        if self._body_buffer is not None:
756
            return self._body_buffer.read(count)
757
        _body_decoder = LengthPrefixedBodyDecoder()
758
759
        while not _body_decoder.finished_reading:
3565.1.1 by Andrew Bennetts
Read no more then 64k at a time in the smart protocol code.
760
            bytes = self._request.read_bytes(_body_decoder.next_read_size())
3464.4.1 by Andrew Bennetts
Fix infinite busy-loop caused by connection loss during read of response body in HPSS v1 and v2.
761
            if bytes == '':
762
                # end of file encountered reading from server
763
                raise errors.ConnectionReset(
764
                    "Connection lost while reading response body.")
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
765
            _body_decoder.accept_bytes(bytes)
766
        self._request.finished_reading()
767
        self._body_buffer = StringIO(_body_decoder.read_pending_data())
768
        # XXX: TODO check the trailer result.
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
769
        if 'hpss' in debug.debug_flags:
2664.4.4 by John Arbash Meinel
Switch around what bytes get logged.
770
            mutter('              %d body bytes read',
2664.4.3 by John Arbash Meinel
Update to include a bit better formatting
771
                   len(self._body_buffer.getvalue()))
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
772
        return self._body_buffer.read(count)
773
774
    def _recv_tuple(self):
775
        """Receive a tuple from the medium request."""
3565.1.1 by Andrew Bennetts
Read no more then 64k at a time in the smart protocol code.
776
        return _decode_tuple(self._request.read_line())
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
777
778
    def query_version(self):
779
        """Return protocol version number of the server."""
780
        self.call('hello')
781
        resp = self.read_response_tuple()
782
        if resp == ('ok', '1'):
783
            return 1
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
784
        elif resp == ('ok', '2'):
785
            return 2
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
786
        else:
787
            raise errors.SmartProtocolError("bad response %r" % (resp,))
788
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
789
    def _write_args(self, args):
790
        self._write_protocol_version()
791
        bytes = _encode_tuple(args)
792
        self._request.accept_bytes(bytes)
793
794
    def _write_protocol_version(self):
795
        """Write any prefixes this protocol requires.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
796
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
797
        Version one doesn't send protocol versions.
798
        """
799
800
801
class SmartClientRequestProtocolTwo(SmartClientRequestProtocolOne):
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
802
    """Version two of the client side of the smart protocol.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
803
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
804
    This prefixes the request with the value of REQUEST_VERSION_TWO.
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
805
    """
806
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.
807
    response_marker = RESPONSE_VERSION_TWO
808
    request_marker = REQUEST_VERSION_TWO
809
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
810
    def read_response_tuple(self, expect_body=False):
811
        """Read a response tuple from the wire.
812
813
        This should only be called once.
814
        """
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
815
        version = self._request.read_line()
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.
816
        if version != self.response_marker:
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).
817
            self._request.finished_reading()
3245.4.43 by Andrew Bennetts
Improve tests for automatic detection of protocol version.
818
            raise errors.UnexpectedProtocolVersionMarker(version)
3565.1.1 by Andrew Bennetts
Read no more then 64k at a time in the smart protocol code.
819
        response_status = self._request.read_line()
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
820
        result = SmartClientRequestProtocolOne._read_response_tuple(self)
3245.4.55 by Andrew Bennetts
Test improvements suggested by John's review.
821
        self._response_is_unknown_method(result)
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
822
        if response_status == 'success\n':
823
            self.response_status = True
824
            if not expect_body:
825
                self._request.finished_reading()
826
            return result
827
        elif response_status == 'failed\n':
828
            self.response_status = False
829
            self._request.finished_reading()
830
            raise errors.ErrorFromSmartServer(result)
831
        else:
2432.4.6 by Robert Collins
Include success/failure feedback in SmartProtocolTwo responses to allow robust handling in the future.
832
            raise errors.SmartProtocolError(
833
                'bad protocol status %r' % response_status)
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
834
835
    def _write_protocol_version(self):
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
836
        """Write any prefixes this protocol requires.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
837
2432.2.7 by Andrew Bennetts
Use less confusing version strings, and define REQUEST_VERSION_TWO/RESPONSE_VERSION_TWO constants for them.
838
        Version two sends the value of REQUEST_VERSION_TWO.
2432.2.1 by Andrew Bennetts
Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.
839
        """
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.
840
        self._request.accept_bytes(self.request_marker)
2018.5.3 by Andrew Bennetts
Split up more smart server code, this time into bzrlib/transport/smart/protocol.py
841
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
842
    def read_streamed_body(self):
843
        """Read bytes from the body, decoding into a byte stream.
844
        """
3170.5.1 by Andrew Bennetts
Fix the other half of bug #115781: don't read more than 64k at a time either.
845
        # Read no more than 64k at a time so that we don't risk error 10055 (no
846
        # buffer space available) on Windows.
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
847
        _body_decoder = ChunkedBodyDecoder()
848
        while not _body_decoder.finished_reading:
3565.1.1 by Andrew Bennetts
Read no more then 64k at a time in the smart protocol code.
849
            bytes = self._request.read_bytes(_body_decoder.next_read_size())
3464.4.1 by Andrew Bennetts
Fix infinite busy-loop caused by connection loss during read of response body in HPSS v1 and v2.
850
            if bytes == '':
851
                # end of file encountered reading from server
852
                raise errors.ConnectionReset(
853
                    "Connection lost while reading streamed body.")
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
854
            _body_decoder.accept_bytes(bytes)
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
855
            for body_bytes in iter(_body_decoder.read_next_chunk, None):
3245.4.18 by Andrew Bennetts
Remove a bunch of cruft, especially the SmartClientRequestProtocolThree class.
856
                if 'hpss' in debug.debug_flags and type(body_bytes) is str:
2748.4.5 by Andrew Bennetts
Allow an error to interrupt (and terminate) a streamed response body.
857
                    mutter('              %d byte chunk read',
2535.4.3 by Andrew Bennetts
Remove some useless mutters.
858
                           len(body_bytes))
2748.4.2 by Andrew Bennetts
Add protocol (version two) support for streaming bodies (using chunking) in responses.
859
                yield body_bytes
860
        self._request.finished_reading()
861
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.
862
3245.4.14 by Andrew Bennetts
Merge from bzr.dev (via loom thread).
863
def build_server_protocol_three(backing_transport, write_func,
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).
864
                                root_client_path, jail_root=None):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
865
    request_handler = request.SmartServerRequestHandler(
3245.4.14 by Andrew Bennetts
Merge from bzr.dev (via loom thread).
866
        backing_transport, commands=request.request_handlers,
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).
867
        root_client_path=root_client_path, jail_root=jail_root)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
868
    responder = ProtocolThreeResponder(write_func)
869
    message_handler = message.ConventionalRequestHandler(request_handler, responder)
3245.4.7 by Andrew Bennetts
Rename _ProtocolThreeBase to ProtocolThreeDecoder, remove SmartServerRequestProtocolThree.
870
    return ProtocolThreeDecoder(message_handler)
871
872
873
class ProtocolThreeDecoder(_StatefulDecoder):
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.
874
875
    response_marker = RESPONSE_VERSION_THREE
876
    request_marker = REQUEST_VERSION_THREE
877
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
878
    def __init__(self, message_handler, expect_version_marker=False):
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.
879
        _StatefulDecoder.__init__(self)
3245.4.59 by Andrew Bennetts
Various tweaks in response to Martin's review.
880
        self._has_dispatched = False
3195.3.5 by Andrew Bennetts
Start writing the client-side protocol logic for HPSS v3.
881
        # Initial state
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
882
        if expect_version_marker:
883
            self.state_accept = self._state_accept_expecting_protocol_version
884
            # We're expecting at least the protocol version marker + some
885
            # headers.
886
            self._number_needed_bytes = len(MESSAGE_VERSION_THREE) + 4
887
        else:
888
            self.state_accept = self._state_accept_expecting_headers
889
            self._number_needed_bytes = 4
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
890
        self.decoding_failed = False
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
891
        self.request_handler = self.message_handler = message_handler
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.
892
3195.3.8 by Andrew Bennetts
Use _NeedMoreBytes to improve earlier protocol implementations a little, and make test_errors_are_logged pass.
893
    def accept_bytes(self, bytes):
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.
894
        self._number_needed_bytes = None
3195.3.8 by Andrew Bennetts
Use _NeedMoreBytes to improve earlier protocol implementations a little, and make test_errors_are_logged pass.
895
        try:
896
            _StatefulDecoder.accept_bytes(self, bytes)
897
        except KeyboardInterrupt:
898
            raise
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
899
        except errors.SmartMessageHandlerError, exception:
900
            # We do *not* set self.decoding_failed here.  The message handler
901
            # has raised an error, but the decoder is still able to parse bytes
902
            # and determine when this message ends.
4475.2.1 by Andrew Bennetts
Don't log UnknownSmartMethod errors on the server.
903
            if not isinstance(exception.exc_value, errors.UnknownSmartMethod):
904
                log_exception_quietly()
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
905
            self.message_handler.protocol_error(exception.exc_value)
906
            # The state machine is ready to continue decoding, but the
907
            # exception has interrupted the loop that runs the state machine.
908
            # So we call accept_bytes again to restart it.
909
            self.accept_bytes('')
3195.3.8 by Andrew Bennetts
Use _NeedMoreBytes to improve earlier protocol implementations a little, and make test_errors_are_logged pass.
910
        except Exception, exception:
3245.4.50 by Andrew Bennetts
Clarify the code a little.
911
            # The decoder itself has raised an exception.  We cannot continue
912
            # decoding.
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
913
            self.decoding_failed = True
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).
914
            if isinstance(exception, errors.UnexpectedProtocolVersionMarker):
915
                # This happens during normal operation when the client tries a
916
                # protocol version the server doesn't understand, so no need to
917
                # log a traceback every time.
3245.4.51 by Andrew Bennetts
Add another comment.
918
                # Note that this can only happen when
919
                # expect_version_marker=True, which is only the case on the
920
                # client side.
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).
921
                pass
922
            else:
923
                log_exception_quietly()
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
924
            self.message_handler.protocol_error(exception)
3195.3.8 by Andrew Bennetts
Use _NeedMoreBytes to improve earlier protocol implementations a little, and make test_errors_are_logged pass.
925
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.
926
    def _extract_length_prefixed_bytes(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
927
        if self._in_buffer_len < 4:
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.
928
            # A length prefix by itself is 4 bytes, and we don't even have that
929
            # many yet.
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.
930
            raise _NeedMoreBytes(4)
3649.5.2 by John Arbash Meinel
When we are waiting on a big stream, allow
931
        (length,) = struct.unpack('!L', self._get_in_bytes(4))
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.
932
        end_of_bytes = 4 + length
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
933
        if self._in_buffer_len < end_of_bytes:
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.
934
            # We haven't yet read as many bytes as the length-prefix says there
935
            # are.
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.
936
            raise _NeedMoreBytes(end_of_bytes)
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.
937
        # Extract the bytes from the buffer.
3649.5.2 by John Arbash Meinel
When we are waiting on a big stream, allow
938
        in_buf = self._get_in_buffer()
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
939
        bytes = in_buf[4:end_of_bytes]
940
        self._set_in_buffer(in_buf[end_of_bytes:])
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.
941
        return bytes
942
943
    def _extract_prefixed_bencoded_data(self):
944
        prefixed_bytes = self._extract_length_prefixed_bytes()
945
        try:
3842.3.21 by Andrew Bennetts
Merge bzr.dev.
946
            decoded = bdecode_as_tuple(prefixed_bytes)
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.
947
        except ValueError:
948
            raise errors.SmartProtocolError(
949
                'Bytes %r not bencoded' % (prefixed_bytes,))
950
        return decoded
951
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
952
    def _extract_single_byte(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
953
        if self._in_buffer_len == 0:
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
954
            # The buffer is empty
3245.4.28 by Andrew Bennetts
Remove another XXX, and include test ID in smart server thread names.
955
            raise _NeedMoreBytes(1)
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
956
        in_buf = self._get_in_buffer()
957
        one_byte = in_buf[0]
958
        self._set_in_buffer(in_buf[1:])
3195.3.7 by Andrew Bennetts
Make the '_extract_* helpers more robust by adding a _NeedMoreBytes exception to _StatefulDecoder.
959
        return one_byte
960
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
961
    def _state_accept_expecting_protocol_version(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
962
        needed_bytes = len(MESSAGE_VERSION_THREE) - self._in_buffer_len
963
        in_buf = self._get_in_buffer()
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
964
        if needed_bytes > 0:
3245.4.46 by Andrew Bennetts
Apply John's review comments.
965
            # We don't have enough bytes to check if the protocol version
966
            # marker is right.  But we can check if it is already wrong by
967
            # checking that the start of MESSAGE_VERSION_THREE matches what
968
            # we've read so far.
969
            # [In fact, if the remote end isn't bzr we might never receive
970
            # len(MESSAGE_VERSION_THREE) bytes.  So if the bytes we have so far
971
            # are wrong then we should just raise immediately rather than
972
            # stall.]
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
973
            if not MESSAGE_VERSION_THREE.startswith(in_buf):
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
974
                # We have enough bytes to know the protocol version is wrong
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
975
                raise errors.UnexpectedProtocolVersionMarker(in_buf)
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
976
            raise _NeedMoreBytes(len(MESSAGE_VERSION_THREE))
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
977
        if not in_buf.startswith(MESSAGE_VERSION_THREE):
978
            raise errors.UnexpectedProtocolVersionMarker(in_buf)
979
        self._set_in_buffer(in_buf[len(MESSAGE_VERSION_THREE):])
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
980
        self.state_accept = self._state_accept_expecting_headers
981
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
982
    def _state_accept_expecting_headers(self):
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.
983
        decoded = self._extract_prefixed_bencoded_data()
984
        if type(decoded) is not dict:
985
            raise errors.SmartProtocolError(
986
                'Header object %r is not a dict' % (decoded,))
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
987
        self.state_accept = self._state_accept_expecting_message_part
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
988
        try:
989
            self.message_handler.headers_received(decoded)
990
        except:
991
            raise errors.SmartMessageHandlerError(sys.exc_info())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
992
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
993
    def _state_accept_expecting_message_part(self):
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
994
        message_part_kind = self._extract_single_byte()
995
        if message_part_kind == 'o':
996
            self.state_accept = self._state_accept_expecting_one_byte
997
        elif message_part_kind == 's':
998
            self.state_accept = self._state_accept_expecting_structure
999
        elif message_part_kind == 'b':
1000
            self.state_accept = self._state_accept_expecting_bytes
1001
        elif message_part_kind == 'e':
1002
            self.done()
1003
        else:
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.
1004
            raise errors.SmartProtocolError(
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
1005
                'Bad message kind byte: %r' % (message_part_kind,))
1006
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
1007
    def _state_accept_expecting_one_byte(self):
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
1008
        byte = self._extract_single_byte()
1009
        self.state_accept = self._state_accept_expecting_message_part
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
1010
        try:
1011
            self.message_handler.byte_part_received(byte)
1012
        except:
1013
            raise errors.SmartMessageHandlerError(sys.exc_info())
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
1014
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
1015
    def _state_accept_expecting_bytes(self):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1016
        # XXX: this should not buffer whole message part, but instead deliver
1017
        # the bytes as they arrive.
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.
1018
        prefixed_bytes = self._extract_length_prefixed_bytes()
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
1019
        self.state_accept = self._state_accept_expecting_message_part
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
1020
        try:
1021
            self.message_handler.bytes_part_received(prefixed_bytes)
1022
        except:
1023
            raise errors.SmartMessageHandlerError(sys.exc_info())
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
1024
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
1025
    def _state_accept_expecting_structure(self):
3195.3.16 by Andrew Bennetts
Update tests for revised v3 spec.
1026
        structure = self._extract_prefixed_bencoded_data()
1027
        self.state_accept = self._state_accept_expecting_message_part
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
1028
        try:
1029
            self.message_handler.structure_part_received(structure)
1030
        except:
1031
            raise errors.SmartMessageHandlerError(sys.exc_info())
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.
1032
1033
    def done(self):
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
1034
        self.unused_data = self._get_in_buffer()
1035
        self._set_in_buffer(None)
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.
1036
        self.state_accept = self._state_accept_reading_unused
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
1037
        try:
1038
            self.message_handler.end_received()
1039
        except:
1040
            raise errors.SmartMessageHandlerError(sys.exc_info())
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.
1041
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
1042
    def _state_accept_reading_unused(self):
4515.1.1 by Andrew Bennetts
Fix bug in HPSS v3 decoder when receiving multiple lots of excess bytes.
1043
        self.unused_data += self._get_in_buffer()
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
1044
        self._set_in_buffer(None)
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.
1045
1046
    def next_read_size(self):
1047
        if self.state_accept == self._state_accept_reading_unused:
1048
            return 0
3245.4.49 by Andrew Bennetts
Distinguish between errors in decoding a message into message parts from errors in handling decoded message parts, and use that to make sure that entire requests are read even when they result in exceptions.
1049
        elif self.decoding_failed:
3245.4.29 by Andrew Bennetts
Add/tidy some comments, remove dud test_errors_are_logged test, add explicit UnknownSmartMethod to v3.
1050
            # An exception occured while processing this message, probably from
1051
            # self.message_handler.  We're not sure that this state machine is
1052
            # in a consistent state, so just signal that we're done (i.e. give
1053
            # up).
3245.4.28 by Andrew Bennetts
Remove another XXX, and include test ID in smart server thread names.
1054
            return 0
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.
1055
        else:
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.
1056
            if self._number_needed_bytes is not None:
3649.5.1 by John Arbash Meinel
Change _StatefulDecoder._in_bytes into a _in_bytes_list
1057
                return self._number_needed_bytes - self._in_buffer_len
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.
1058
            else:
3245.4.28 by Andrew Bennetts
Remove another XXX, and include test ID in smart server thread names.
1059
                raise AssertionError("don't know how many bytes are expected!")
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.
1060
1061
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1062
class _ProtocolThreeEncoder(object):
1063
3245.4.18 by Andrew Bennetts
Remove a bunch of cruft, especially the SmartClientRequestProtocolThree class.
1064
    response_marker = request_marker = MESSAGE_VERSION_THREE
1065
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1066
    def __init__(self, write_func):
4078.1.1 by Andrew Bennetts
Slightly better buffering logic when generating protocol v3 messages, especially during streamed bodies.
1067
        self._buf = []
3441.3.1 by Andrew Bennetts
Buffer encoding of v3 messages to minimise write/send calls. Doubles the speed of pushing over TCP with 500ms latency loopback.
1068
        self._real_write_func = write_func
1069
1070
    def _write_func(self, bytes):
4078.1.1 by Andrew Bennetts
Slightly better buffering logic when generating protocol v3 messages, especially during streamed bodies.
1071
        self._buf.append(bytes)
1072
        if len(self._buf) > 100:
1073
            self.flush()
3441.3.1 by Andrew Bennetts
Buffer encoding of v3 messages to minimise write/send calls. Doubles the speed of pushing over TCP with 500ms latency loopback.
1074
1075
    def flush(self):
1076
        if self._buf:
4078.1.1 by Andrew Bennetts
Slightly better buffering logic when generating protocol v3 messages, especially during streamed bodies.
1077
            self._real_write_func(''.join(self._buf))
1078
            del self._buf[:]
3441.3.1 by Andrew Bennetts
Buffer encoding of v3 messages to minimise write/send calls. Doubles the speed of pushing over TCP with 500ms latency loopback.
1079
3245.4.18 by Andrew Bennetts
Remove a bunch of cruft, especially the SmartClientRequestProtocolThree class.
1080
    def _serialise_offsets(self, offsets):
1081
        """Serialise a readv offset list."""
1082
        txt = []
1083
        for start, length in offsets:
1084
            txt.append('%d,%d' % (start, length))
1085
        return '\n'.join(txt)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1086
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1087
    def _write_protocol_version(self):
1088
        self._write_func(MESSAGE_VERSION_THREE)
1089
1090
    def _write_prefixed_bencode(self, structure):
1091
        bytes = bencode(structure)
1092
        self._write_func(struct.pack('!L', len(bytes)))
1093
        self._write_func(bytes)
1094
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1095
    def _write_headers(self, headers):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1096
        self._write_prefixed_bencode(headers)
1097
1098
    def _write_structure(self, args):
1099
        self._write_func('s')
3195.3.23 by Andrew Bennetts
Improve the error handling, fixing more tests.
1100
        utf8_args = []
1101
        for arg in args:
1102
            if type(arg) is unicode:
1103
                utf8_args.append(arg.encode('utf8'))
1104
            else:
1105
                utf8_args.append(arg)
1106
        self._write_prefixed_bencode(utf8_args)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1107
1108
    def _write_end(self):
1109
        self._write_func('e')
3441.3.2 by Andrew Bennetts
Simplify buffering logic in _ProtocolThreeEncoder.
1110
        self.flush()
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1111
1112
    def _write_prefixed_body(self, bytes):
1113
        self._write_func('b')
1114
        self._write_func(struct.pack('!L', len(bytes)))
1115
        self._write_func(bytes)
1116
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.
1117
    def _write_chunked_body_start(self):
1118
        self._write_func('oC')
1119
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1120
    def _write_error_status(self):
1121
        self._write_func('oE')
1122
1123
    def _write_success_status(self):
1124
        self._write_func('oS')
1125
1126
1127
class ProtocolThreeResponder(_ProtocolThreeEncoder):
1128
1129
    def __init__(self, write_func):
1130
        _ProtocolThreeEncoder.__init__(self, write_func)
1131
        self.response_sent = False
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1132
        self._headers = {'Software version': bzrlib.__version__}
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1133
1134
    def send_error(self, exception):
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
1135
        if self.response_sent:
1136
            raise AssertionError(
1137
                "send_error(%s) called, but response already sent."
1138
                % (exception,))
3245.4.29 by Andrew Bennetts
Add/tidy some comments, remove dud test_errors_are_logged test, add explicit UnknownSmartMethod to v3.
1139
        if isinstance(exception, errors.UnknownSmartMethod):
3245.4.37 by Andrew Bennetts
Add test for sending ProtocolThreeResponder.send_error(UnknownSmartMethod(...)).
1140
            failure = request.FailedSmartServerResponse(
1141
                ('UnknownMethod', exception.verb))
3245.4.29 by Andrew Bennetts
Add/tidy some comments, remove dud test_errors_are_logged test, add explicit UnknownSmartMethod to v3.
1142
            self.send_response(failure)
1143
            return
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1144
        self.response_sent = True
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1145
        self._write_protocol_version()
1146
        self._write_headers(self._headers)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1147
        self._write_error_status()
1148
        self._write_structure(('error', str(exception)))
1149
        self._write_end()
1150
1151
    def send_response(self, response):
3245.4.54 by Andrew Bennetts
Improve _StatefulDecoder after John's review.
1152
        if self.response_sent:
1153
            raise AssertionError(
1154
                "send_response(%r) called, but response already sent."
1155
                % (response,))
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1156
        self.response_sent = True
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1157
        self._write_protocol_version()
1158
        self._write_headers(self._headers)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1159
        if response.is_successful():
1160
            self._write_success_status()
1161
        else:
1162
            self._write_error_status()
1163
        self._write_structure(response.args)
1164
        if response.body is not None:
1165
            self._write_prefixed_body(response.body)
1166
        elif response.body_stream is not None:
4064.1.3 by Andrew Bennetts
Fix bug in _iter_with_errors; it should not report StopIteration as an exception.
1167
            for exc_info, chunk in _iter_with_errors(response.body_stream):
1168
                if exc_info is not None:
4064.1.1 by Andrew Bennetts
Add TestResponseEncodingProtocolThree.test_send_broken_body_stream, and make it pass.
1169
                    self._write_error_status()
4064.1.3 by Andrew Bennetts
Fix bug in _iter_with_errors; it should not report StopIteration as an exception.
1170
                    error_struct = request._translate_error(exc_info[1])
4064.1.1 by Andrew Bennetts
Add TestResponseEncodingProtocolThree.test_send_broken_body_stream, and make it pass.
1171
                    self._write_structure(error_struct)
1172
                    break
1173
                else:
4070.9.2 by Andrew Bennetts
Rough prototype of allowing a SearchResult to be passed to fetch, and using that to improve network conversations.
1174
                    if isinstance(chunk, request.FailedSmartServerResponse):
1175
                        self._write_error_status()
1176
                        self._write_structure(chunk.args)
1177
                        break
4064.1.1 by Andrew Bennetts
Add TestResponseEncodingProtocolThree.test_send_broken_body_stream, and make it pass.
1178
                    self._write_prefixed_body(chunk)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1179
        self._write_end()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1180
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1181
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
1182
def _iter_with_errors(iterable):
1183
    """Handle errors from iterable.next().
1184
1185
    Use like::
1186
1187
        for exc_info, value in _iter_with_errors(iterable):
1188
            ...
1189
1190
    This is a safer alternative to::
1191
1192
        try:
1193
            for value in iterable:
1194
               ...
1195
        except:
1196
            ...
1197
1198
    Because the latter will catch errors from the for-loop body, not just
1199
    iterable.next()
1200
1201
    If an error occurs, exc_info will be a exc_info tuple, and the generator
1202
    will terminate.  Otherwise exc_info will be None, and value will be the
1203
    value from iterable.next().  Note that KeyboardInterrupt and SystemExit
1204
    will not be itercepted.
1205
    """
4064.1.1 by Andrew Bennetts
Add TestResponseEncodingProtocolThree.test_send_broken_body_stream, and make it pass.
1206
    iterator = iter(iterable)
1207
    while True:
1208
        try:
1209
            yield None, iterator.next()
4064.1.3 by Andrew Bennetts
Fix bug in _iter_with_errors; it should not report StopIteration as an exception.
1210
        except StopIteration:
1211
            return
4064.1.2 by Andrew Bennetts
Refactor server-side error translation, improve tests.
1212
        except (KeyboardInterrupt, SystemExit):
1213
            raise
1214
        except Exception:
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
1215
            mutter('_iter_with_errors caught error')
1216
            log_exception_quietly()
4064.1.1 by Andrew Bennetts
Add TestResponseEncodingProtocolThree.test_send_broken_body_stream, and make it pass.
1217
            yield sys.exc_info(), None
1218
            return
1219
1220
3245.4.26 by Andrew Bennetts
Rename 'setProtoAndMedium' to more accurate 'setProtoAndMediumRequest', add ABCs for Requesters and ResponseHandlers.
1221
class ProtocolThreeRequester(_ProtocolThreeEncoder, Requester):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1222
1223
    def __init__(self, medium_request):
1224
        _ProtocolThreeEncoder.__init__(self, medium_request.accept_bytes)
1225
        self._medium_request = medium_request
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1226
        self._headers = {}
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1227
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1228
    def set_headers(self, headers):
3245.4.46 by Andrew Bennetts
Apply John's review comments.
1229
        self._headers = headers.copy()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1230
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1231
    def call(self, *args):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1232
        if 'hpss' in debug.debug_flags:
1233
            mutter('hpss call:   %s', repr(args)[1:-1])
1234
            base = getattr(self._medium_request._medium, 'base', None)
1235
            if base is not None:
1236
                mutter('             (to %s)', base)
1237
            self._request_start_time = time.time()
1238
        self._write_protocol_version()
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1239
        self._write_headers(self._headers)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1240
        self._write_structure(args)
1241
        self._write_end()
1242
        self._medium_request.finished_writing()
1243
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1244
    def call_with_body_bytes(self, args, body):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1245
        """Make a remote call of args with body bytes 'body'.
1246
1247
        After calling this, call read_response_tuple to find the result out.
1248
        """
1249
        if 'hpss' in debug.debug_flags:
3842.3.2 by Andrew Bennetts
Revert the RemoteVersionedFiles.get_parent_map implementation, leaving just the skeleton of RemoteVersionedFiles.
1250
            mutter('hpss call w/body: %s (%r...)', repr(args)[1:-1], body[:20])
3245.4.3 by Andrew Bennetts
Fix crash in -Dhpss.
1251
            path = getattr(self._medium_request._medium, '_path', None)
1252
            if path is not None:
1253
                mutter('                  (to %s)', path)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1254
            mutter('              %d bytes', len(body))
1255
            self._request_start_time = time.time()
1256
        self._write_protocol_version()
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1257
        self._write_headers(self._headers)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1258
        self._write_structure(args)
1259
        self._write_prefixed_body(body)
1260
        self._write_end()
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.
1261
        self._medium_request.finished_writing()
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1262
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1263
    def call_with_body_readv_array(self, args, body):
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1264
        """Make a remote call with a readv array.
1265
1266
        The body is encoded with one line per readv offset pair. The numbers in
1267
        each pair are separated by a comma, and no trailing \n is emitted.
1268
        """
1269
        if 'hpss' in debug.debug_flags:
1270
            mutter('hpss call w/readv: %s', repr(args)[1:-1])
3245.4.3 by Andrew Bennetts
Fix crash in -Dhpss.
1271
            path = getattr(self._medium_request._medium, '_path', None)
1272
            if path is not None:
1273
                mutter('                  (to %s)', path)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1274
            self._request_start_time = time.time()
1275
        self._write_protocol_version()
3245.4.42 by Andrew Bennetts
Make _SmartClient automatically detect and use the highest protocol version compatible with the server.
1276
        self._write_headers(self._headers)
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1277
        self._write_structure(args)
1278
        readv_bytes = self._serialise_offsets(body)
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
1279
        if 'hpss' in debug.debug_flags:
1280
            mutter('              %d bytes in readv request', len(readv_bytes))
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1281
        self._write_prefixed_body(readv_bytes)
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
1282
        self._write_end()
1283
        self._medium_request.finished_writing()
3195.3.17 by Andrew Bennetts
Some tests now passing using protocol 3.
1284
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.
1285
    def call_with_body_stream(self, args, stream):
1286
        if 'hpss' in debug.debug_flags:
1287
            mutter('hpss call w/body stream: %r', args)
1288
            path = getattr(self._medium_request._medium, '_path', None)
1289
            if path is not None:
1290
                mutter('                  (to %s)', path)
1291
            self._request_start_time = time.time()
1292
        self._write_protocol_version()
1293
        self._write_headers(self._headers)
1294
        self._write_structure(args)
3923.5.5 by Andrew Bennetts
Cleanly abort the request if an error occurs while iterating a body stream.
1295
        # TODO: notice if the server has sent an early error reply before we
1296
        #       have finished sending the stream.  We would notice at the end
1297
        #       anyway, but if the medium can deliver it early then it's good
1298
        #       to short-circuit the whole request...
4064.1.3 by Andrew Bennetts
Fix bug in _iter_with_errors; it should not report StopIteration as an exception.
1299
        for exc_info, part in _iter_with_errors(stream):
1300
            if exc_info is not None:
1301
                # Iterating the stream failed.  Cleanly abort the request.
1302
                self._write_error_status()
1303
                # Currently the client unconditionally sends ('error',) as the
1304
                # error args.
1305
                self._write_structure(('error',))
1306
                self._write_end()
1307
                self._medium_request.finished_writing()
1308
                raise exc_info[0], exc_info[1], exc_info[2]
1309
            else:
3923.5.5 by Andrew Bennetts
Cleanly abort the request if an error occurs while iterating a body stream.
1310
                self._write_prefixed_body(part)
1311
                self.flush()
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.
1312
        self._write_end()
1313
        self._medium_request.finished_writing()
1314