25
25
from bzrlib.smart import request
28
# Protocol version strings. These are sent as prefixes of bzr requests and
29
# responses to identify the protocol version being used. (There are no version
30
# one strings because that version doesn't send any).
31
REQUEST_VERSION_TWO = 'bzr request 2\n'
32
RESPONSE_VERSION_TWO = 'bzr response 2\n'
28
35
def _recv_tuple(from_file):
29
36
req_line = from_file.readline()
30
37
return _decode_tuple(req_line)
97
104
self.excess_buffer = self.in_buffer
98
105
self.in_buffer = ''
99
self._send_response(self.request.response.args,
100
self.request.response.body)
106
self._send_response(self.request.response)
101
107
except KeyboardInterrupt:
103
109
except Exception, exception:
104
110
# everything else: pass to client, flush, and quit
105
self._send_response(('error', str(exception)))
111
self._send_response(request.FailedSmartServerResponse(
112
('error', str(exception))))
108
115
if self.has_dispatched:
123
130
assert self.request.finished_reading, \
124
131
"no more body, request not finished"
125
132
if self.request.response is not None:
126
self._send_response(self.request.response.args,
127
self.request.response.body)
133
self._send_response(self.request.response)
128
134
self.excess_buffer = self.in_buffer
129
135
self.in_buffer = ''
131
137
assert not self.request.finished_reading, \
132
138
"no response and we have finished reading."
134
def _send_response(self, args, body=None):
140
def _send_response(self, response):
135
141
"""Send a smart server response down the output stream."""
136
142
assert not self._finished, 'response already sent'
137
145
self._finished = True
146
self._write_protocol_version()
147
self._write_success_or_failure_prefix(response)
138
148
self._write_func(_encode_tuple(args))
139
149
if body is not None:
140
150
assert isinstance(body, str), 'body must be a str'
141
151
bytes = self._encode_bulk_data(body)
142
152
self._write_func(bytes)
154
def _write_protocol_version(self):
155
"""Write any prefixes this protocol requires.
157
Version one doesn't send protocol versions.
160
def _write_success_or_failure_prefix(self, response):
161
"""Write the protocol specific success/failure prefix.
163
For SmartServerRequestProtocolOne this is omitted but we
164
call is_successful to ensure that the response is valid.
166
response.is_successful()
144
168
def next_read_size(self):
145
169
if self._finished:
150
174
return self._body_decoder.next_read_size()
177
class SmartServerRequestProtocolTwo(SmartServerRequestProtocolOne):
178
r"""Version two of the server side of the smart protocol.
180
This prefixes responses with the value of RESPONSE_VERSION_TWO.
183
def _write_success_or_failure_prefix(self, response):
184
"""Write the protocol specific success/failure prefix."""
185
if response.is_successful():
186
self._write_func('success\n')
188
self._write_func('failed\n')
190
def _write_protocol_version(self):
191
r"""Write any prefixes this protocol requires.
193
Version two sends the value of RESPONSE_VERSION_TWO.
195
self._write_func(RESPONSE_VERSION_TWO)
153
198
class LengthPrefixedBodyDecoder(object):
154
199
"""Decodes the length-prefixed bulk data."""
254
299
self._body_buffer = None
256
301
def call(self, *args):
257
bytes = _encode_tuple(args)
258
self._request.accept_bytes(bytes)
302
self._write_args(args)
259
303
self._request.finished_writing()
261
305
def call_with_body_bytes(self, args, body):
264
308
After calling this, call read_response_tuple to find the result out.
266
bytes = _encode_tuple(args)
267
self._request.accept_bytes(bytes)
310
self._write_args(args)
268
311
bytes = self._encode_bulk_data(body)
269
312
self._request.accept_bytes(bytes)
270
313
self._request.finished_writing()
275
318
The body is encoded with one line per readv offset pair. The numbers in
276
319
each pair are separated by a comma, and no trailing \n is emitted.
278
bytes = _encode_tuple(args)
279
self._request.accept_bytes(bytes)
321
self._write_args(args)
280
322
readv_bytes = self._serialise_offsets(body)
281
323
bytes = self._encode_bulk_data(readv_bytes)
282
324
self._request.accept_bytes(bytes)
323
365
def _recv_tuple(self):
324
366
"""Receive a tuple from the medium request."""
367
return _decode_tuple(self._recv_line())
369
def _recv_line(self):
370
"""Read an entire line from the medium request."""
326
372
while not line or line[-1] != '\n':
327
373
# TODO: this is inefficient - but tuples are short.
328
374
new_char = self._request.read_bytes(1)
330
376
assert new_char != '', "end of file reading from server."
331
return _decode_tuple(line)
333
379
def query_version(self):
334
380
"""Return protocol version number of the server."""
336
382
resp = self.read_response_tuple()
337
383
if resp == ('ok', '1'):
385
elif resp == ('ok', '2'):
340
388
raise errors.SmartProtocolError("bad response %r" % (resp,))
390
def _write_args(self, args):
391
self._write_protocol_version()
392
bytes = _encode_tuple(args)
393
self._request.accept_bytes(bytes)
395
def _write_protocol_version(self):
396
"""Write any prefixes this protocol requires.
398
Version one doesn't send protocol versions.
402
class SmartClientRequestProtocolTwo(SmartClientRequestProtocolOne):
403
"""Version two of the client side of the smart protocol.
405
This prefixes the request with the value of REQUEST_VERSION_TWO.
408
def read_response_tuple(self, expect_body=False):
409
"""Read a response tuple from the wire.
411
This should only be called once.
413
version = self._request.read_line()
414
if version != RESPONSE_VERSION_TWO:
415
raise errors.SmartProtocolError('bad protocol marker %r' % version)
416
response_status = self._recv_line()
417
if response_status not in ('success\n', 'failed\n'):
418
raise errors.SmartProtocolError(
419
'bad protocol status %r' % response_status)
420
self.response_status = response_status == 'success\n'
421
return SmartClientRequestProtocolOne.read_response_tuple(self, expect_body)
423
def _write_protocol_version(self):
424
r"""Write any prefixes this protocol requires.
426
Version two sends the value of REQUEST_VERSION_TWO.
428
self._request.accept_bytes(REQUEST_VERSION_TWO)