~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/protocol.py

Add Smart{Client,Server}RequestProtocolTwo, that prefix args tuples with a version marker.

Show diffs side-by-side

added added

removed removed

Lines of Context:
135
135
        """Send a smart server response down the output stream."""
136
136
        assert not self._finished, 'response already sent'
137
137
        self._finished = True
 
138
        self._write_protocol_version()
138
139
        self._write_func(_encode_tuple(args))
139
140
        if body is not None:
140
141
            assert isinstance(body, str), 'body must be a str'
141
142
            bytes = self._encode_bulk_data(body)
142
143
            self._write_func(bytes)
143
144
 
 
145
    def _write_protocol_version(self):
 
146
        """Write any prefixes this protocol requires.
 
147
        
 
148
        Version one doesn't send protocol versions.
 
149
        """
 
150
 
144
151
    def next_read_size(self):
145
152
        if self._finished:
146
153
            return 0
150
157
            return self._body_decoder.next_read_size()
151
158
 
152
159
 
 
160
class SmartServerRequestProtocolTwo(SmartServerRequestProtocolOne):
 
161
    r"""Version two of the server side of the smart protocol.
 
162
   
 
163
    This prefixes responses with the protocol version: "2\x01".
 
164
    """
 
165
 
 
166
    def _write_protocol_version(self):
 
167
        r"""Write any prefixes this protocol requires.
 
168
        
 
169
        Version two sends "2\x01".
 
170
        """
 
171
        self._write_func('2\x01')
 
172
 
 
173
 
153
174
class LengthPrefixedBodyDecoder(object):
154
175
    """Decodes the length-prefixed bulk data."""
155
176
    
254
275
        self._body_buffer = None
255
276
 
256
277
    def call(self, *args):
257
 
        bytes = _encode_tuple(args)
258
 
        self._request.accept_bytes(bytes)
 
278
        self._write_args(args)
259
279
        self._request.finished_writing()
260
280
 
261
281
    def call_with_body_bytes(self, args, body):
263
283
 
264
284
        After calling this, call read_response_tuple to find the result out.
265
285
        """
266
 
        bytes = _encode_tuple(args)
267
 
        self._request.accept_bytes(bytes)
 
286
        self._write_args(args)
268
287
        bytes = self._encode_bulk_data(body)
269
288
        self._request.accept_bytes(bytes)
270
289
        self._request.finished_writing()
275
294
        The body is encoded with one line per readv offset pair. The numbers in
276
295
        each pair are separated by a comma, and no trailing \n is emitted.
277
296
        """
278
 
        bytes = _encode_tuple(args)
279
 
        self._request.accept_bytes(bytes)
 
297
        self._write_args(args)
280
298
        readv_bytes = self._serialise_offsets(body)
281
299
        bytes = self._encode_bulk_data(readv_bytes)
282
300
        self._request.accept_bytes(bytes)
336
354
        resp = self.read_response_tuple()
337
355
        if resp == ('ok', '1'):
338
356
            return 1
 
357
        elif resp == ('ok', '2'):
 
358
            return 2
339
359
        else:
340
360
            raise errors.SmartProtocolError("bad response %r" % (resp,))
341
361
 
342
 
 
 
362
    def _write_args(self, args):
 
363
        self._write_protocol_version()
 
364
        bytes = _encode_tuple(args)
 
365
        self._request.accept_bytes(bytes)
 
366
 
 
367
    def _write_protocol_version(self):
 
368
        """Write any prefixes this protocol requires.
 
369
        
 
370
        Version one doesn't send protocol versions.
 
371
        """
 
372
 
 
373
 
 
374
class SmartClientRequestProtocolTwo(SmartClientRequestProtocolOne):
 
375
    r"""Version two of the client side of the smart protocol.
 
376
    
 
377
    This prefixes the request with the protocol version: "2\x01".
 
378
    """
 
379
 
 
380
    _version_string = '2\x01'
 
381
 
 
382
    def read_response_tuple(self, expect_body=False):
 
383
        """Read a response tuple from the wire.
 
384
 
 
385
        This should only be called once.
 
386
        """
 
387
        version = self._request.read_bytes(2)
 
388
        if version != SmartClientRequestProtocolTwo._version_string:
 
389
            raise errors.SmartProtocolError('bad protocol marker %r' % version)
 
390
        return SmartClientRequestProtocolOne.read_response_tuple(self, expect_body)
 
391
 
 
392
    def _write_protocol_version(self):
 
393
        r"""Write any prefixes this protocol requires.
 
394
        
 
395
        Version two sends "2\x01".
 
396
        """
 
397
        self._request.accept_bytes(SmartClientRequestProtocolTwo._version_string)
343
398