/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/smart/protocol.py

  • Committer: Jelmer Vernooij
  • Author(s): Richard Wilbur
  • Date: 2017-05-30 23:37:11 UTC
  • mto: This revision was merged to the branch mainline in revision 6645.
  • Revision ID: jelmer@jelmer.uk-20170530233711-r0m0qp8hpkqzpopw
Fix order in which files are processed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
client and server.
19
19
"""
20
20
 
 
21
from __future__ import absolute_import
 
22
 
21
23
import collections
22
 
from cStringIO import StringIO
23
24
import struct
24
25
import sys
25
 
import thread
26
 
import threading
 
26
try:
 
27
    import _thread
 
28
except ImportError:
 
29
    import thread as _thread
27
30
import time
28
31
 
29
 
import bzrlib
30
 
from bzrlib import (
 
32
import breezy
 
33
from .. import (
31
34
    debug,
32
35
    errors,
33
36
    osutils,
34
37
    )
35
 
from bzrlib.smart import message, request
36
 
from bzrlib.trace import log_exception_quietly, mutter
37
 
from bzrlib.bencode import bdecode_as_tuple, bencode
 
38
from ..sixish import (
 
39
    BytesIO,
 
40
    reraise,
 
41
)
 
42
from . import message, request
 
43
from ..trace import log_exception_quietly, mutter
 
44
from ..bencode import bdecode_as_tuple, bencode
38
45
 
39
46
 
40
47
# Protocol version strings.  These are sent as prefixes of bzr requests and
63
70
def _encode_tuple(args):
64
71
    """Encode the tuple args to a bytestream."""
65
72
    joined = '\x01'.join(args) + '\n'
66
 
    if type(joined) is unicode:
 
73
    if isinstance(joined, unicode):
67
74
        # XXX: We should fix things so this never happens!  -AJB, 20100304
68
75
        mutter('response args contain unicode, should be only bytes: %r',
69
76
               joined)
167
174
                    self._send_response(self.request.response)
168
175
            except KeyboardInterrupt:
169
176
                raise
170
 
            except errors.UnknownSmartMethod, err:
 
177
            except errors.UnknownSmartMethod as err:
171
178
                protocol_error = errors.SmartProtocolError(
172
179
                    "bad request %r" % (err.verb,))
173
180
                failure = request.FailedSmartServerResponse(
174
181
                    ('error', str(protocol_error)))
175
182
                self._send_response(failure)
176
183
                return
177
 
            except Exception, exception:
 
184
            except Exception as exception:
178
185
                # everything else: pass to client, flush, and quit
179
186
                log_exception_quietly()
180
187
                self._send_response(request.FailedSmartServerResponse(
408
415
                #     _NeedMoreBytes).
409
416
                current_state = self.state_accept
410
417
                self.state_accept()
411
 
        except _NeedMoreBytes, e:
 
418
        except _NeedMoreBytes as e:
412
419
            self._number_needed_bytes = e.count
413
420
 
414
421
 
654
661
        """Make a remote call with a readv array.
655
662
 
656
663
        The body is encoded with one line per readv offset pair. The numbers in
657
 
        each pair are separated by a comma, and no trailing \n is emitted.
 
664
        each pair are separated by a comma, and no trailing \\n is emitted.
658
665
        """
659
666
        if 'hpss' in debug.debug_flags:
660
667
            mutter('hpss call w/readv: %s', repr(args)[1:-1])
775
782
                    "Connection lost while reading response body.")
776
783
            _body_decoder.accept_bytes(bytes)
777
784
        self._request.finished_reading()
778
 
        self._body_buffer = StringIO(_body_decoder.read_pending_data())
 
785
        self._body_buffer = BytesIO(_body_decoder.read_pending_data())
779
786
        # XXX: TODO check the trailer result.
780
787
        if 'hpss' in debug.debug_flags:
781
788
            mutter('              %d body bytes read',
864
871
                    "Connection lost while reading streamed body.")
865
872
            _body_decoder.accept_bytes(bytes)
866
873
            for body_bytes in iter(_body_decoder.read_next_chunk, None):
867
 
                if 'hpss' in debug.debug_flags and type(body_bytes) is str:
 
874
                if 'hpss' in debug.debug_flags and isinstance(body_bytes, str):
868
875
                    mutter('              %d byte chunk read',
869
876
                           len(body_bytes))
870
877
                yield body_bytes
907
914
            _StatefulDecoder.accept_bytes(self, bytes)
908
915
        except KeyboardInterrupt:
909
916
            raise
910
 
        except errors.SmartMessageHandlerError, exception:
 
917
        except errors.SmartMessageHandlerError as exception:
911
918
            # We do *not* set self.decoding_failed here.  The message handler
912
919
            # has raised an error, but the decoder is still able to parse bytes
913
920
            # and determine when this message ends.
918
925
            # exception has interrupted the loop that runs the state machine.
919
926
            # So we call accept_bytes again to restart it.
920
927
            self.accept_bytes('')
921
 
        except Exception, exception:
 
928
        except Exception as exception:
922
929
            # The decoder itself has raised an exception.  We cannot continue
923
930
            # decoding.
924
931
            self.decoding_failed = True
992
999
 
993
1000
    def _state_accept_expecting_headers(self):
994
1001
        decoded = self._extract_prefixed_bencoded_data()
995
 
        if type(decoded) is not dict:
 
1002
        if not isinstance(decoded, dict):
996
1003
            raise errors.SmartProtocolError(
997
1004
                'Header object %r is not a dict' % (decoded,))
998
1005
        self.state_accept = self._state_accept_expecting_message_part
1081
1088
        self._real_write_func = write_func
1082
1089
 
1083
1090
    def _write_func(self, bytes):
1084
 
        # TODO: It is probably more appropriate to use sum(map(len, _buf))
1085
 
        #       for total number of bytes to write, rather than buffer based on
1086
 
        #       the number of write() calls
1087
1091
        # TODO: Another possibility would be to turn this into an async model.
1088
1092
        #       Where we let another thread know that we have some bytes if
1089
1093
        #       they want it, but we don't actually block for it
1122
1126
        self._write_func('s')
1123
1127
        utf8_args = []
1124
1128
        for arg in args:
1125
 
            if type(arg) is unicode:
 
1129
            if isinstance(arg, unicode):
1126
1130
                utf8_args.append(arg.encode('utf8'))
1127
1131
            else:
1128
1132
                utf8_args.append(arg)
1152
1156
    def __init__(self, write_func):
1153
1157
        _ProtocolThreeEncoder.__init__(self, write_func)
1154
1158
        self.response_sent = False
1155
 
        self._headers = {'Software version': bzrlib.__version__}
 
1159
        self._headers = {'Software version': breezy.__version__}
1156
1160
        if 'hpss' in debug.debug_flags:
1157
 
            self._thread_id = thread.get_ident()
 
1161
            self._thread_id = _thread.get_ident()
1158
1162
            self._response_start_time = None
1159
1163
 
1160
1164
    def _trace(self, action, message, extra_bytes=None, include_time=False):
1231
1235
                    if first_chunk is None:
1232
1236
                        first_chunk = chunk
1233
1237
                    self._write_prefixed_body(chunk)
 
1238
                    self.flush()
1234
1239
                    if 'hpssdetail' in debug.debug_flags:
1235
1240
                        # Not worth timing separately, as _write_func is
1236
1241
                        # actually buffered
1273
1278
    iterator = iter(iterable)
1274
1279
    while True:
1275
1280
        try:
1276
 
            yield None, iterator.next()
 
1281
            yield None, next(iterator)
1277
1282
        except StopIteration:
1278
1283
            return
1279
1284
        except (KeyboardInterrupt, SystemExit):
1291
1296
        _ProtocolThreeEncoder.__init__(self, medium_request.accept_bytes)
1292
1297
        self._medium_request = medium_request
1293
1298
        self._headers = {}
 
1299
        self.body_stream_started = None
1294
1300
 
1295
1301
    def set_headers(self, headers):
1296
1302
        self._headers = headers.copy()
1331
1337
        """Make a remote call with a readv array.
1332
1338
 
1333
1339
        The body is encoded with one line per readv offset pair. The numbers in
1334
 
        each pair are separated by a comma, and no trailing \n is emitted.
 
1340
        each pair are separated by a comma, and no trailing \\n is emitted.
1335
1341
        """
1336
1342
        if 'hpss' in debug.debug_flags:
1337
1343
            mutter('hpss call w/readv: %s', repr(args)[1:-1])
1356
1362
            if path is not None:
1357
1363
                mutter('                  (to %s)', path)
1358
1364
            self._request_start_time = osutils.timer_func()
 
1365
        self.body_stream_started = False
1359
1366
        self._write_protocol_version()
1360
1367
        self._write_headers(self._headers)
1361
1368
        self._write_structure(args)
1363
1370
        #       have finished sending the stream.  We would notice at the end
1364
1371
        #       anyway, but if the medium can deliver it early then it's good
1365
1372
        #       to short-circuit the whole request...
 
1373
        # Provoke any ConnectionReset failures before we start the body stream.
 
1374
        self.flush()
 
1375
        self.body_stream_started = True
1366
1376
        for exc_info, part in _iter_with_errors(stream):
1367
1377
            if exc_info is not None:
1368
1378
                # Iterating the stream failed.  Cleanly abort the request.
1372
1382
                self._write_structure(('error',))
1373
1383
                self._write_end()
1374
1384
                self._medium_request.finished_writing()
1375
 
                raise exc_info[0], exc_info[1], exc_info[2]
 
1385
                try:
 
1386
                    reraise(*exc_info)
 
1387
                finally:
 
1388
                    del exc_info
1376
1389
            else:
1377
1390
                self._write_prefixed_body(part)
1378
1391
                self.flush()