~bzr-pqm/bzr/bzr.dev

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