~jelmer/brz/tree-reference-fixes

« back to all changes in this revision

Viewing changes to breezy/bzr/smart/protocol.py

  • Committer: Jelmer Vernooij
  • Date: 2018-03-25 12:47:13 UTC
  • mfrom: (6926.1.2 work)
  • Revision ID: jelmer@jelmer.uk-20180325124713-dq64vm9bhch1gjow
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
120
120
    # support multiple chunks?
121
121
    def _encode_bulk_data(self, body):
122
122
        """Encode body as a bulk data chunk."""
123
 
        return ''.join(('%d\n' % len(body), body, 'done\n'))
 
123
        return b''.join((b'%d\n' % len(body), body, b'done\n'))
124
124
 
125
125
    def _serialise_offsets(self, offsets):
126
126
        """Serialise a readv offset list."""
127
127
        txt = []
128
128
        for start, length in offsets:
129
 
            txt.append('%d,%d' % (start, length))
130
 
        return '\n'.join(txt)
 
129
            txt.append(b'%d,%d' % (start, length))
 
130
        return b'\n'.join(txt)
131
131
 
132
132
 
133
133
class SmartServerRequestProtocolOne(SmartProtocolBase):
138
138
        self._backing_transport = backing_transport
139
139
        self._root_client_path = root_client_path
140
140
        self._jail_root = jail_root
141
 
        self.unused_data = ''
 
141
        self.unused_data = b''
142
142
        self._finished = False
143
 
        self.in_buffer = ''
 
143
        self.in_buffer = b''
144
144
        self._has_dispatched = False
145
145
        self.request = None
146
146
        self._body_decoder = None
171
171
                if self.request.finished_reading:
172
172
                    # trivial request
173
173
                    self.unused_data = self.in_buffer
174
 
                    self.in_buffer = ''
 
174
                    self.in_buffer = b''
175
175
                    self._send_response(self.request.response)
176
176
            except KeyboardInterrupt:
177
177
                raise
194
194
                # nothing to do.XXX: this routine should be a single state
195
195
                # machine too.
196
196
                self.unused_data += self.in_buffer
197
 
                self.in_buffer = ''
 
197
                self.in_buffer = b''
198
198
                return
199
199
            if self._body_decoder is None:
200
200
                self._body_decoder = LengthPrefixedBodyDecoder()
209
209
            if self.request.response is not None:
210
210
                self._send_response(self.request.response)
211
211
                self.unused_data = self.in_buffer
212
 
                self.in_buffer = ''
 
212
                self.in_buffer = b''
213
213
            else:
214
214
                if self.request.finished_reading:
215
215
                    raise AssertionError(
266
266
    def _write_success_or_failure_prefix(self, response):
267
267
        """Write the protocol specific success/failure prefix."""
268
268
        if response.is_successful():
269
 
            self._write_func('success\n')
 
269
            self._write_func(b'success\n')
270
270
        else:
271
 
            self._write_func('failed\n')
 
271
            self._write_func(b'failed\n')
272
272
 
273
273
    def _write_protocol_version(self):
274
274
        r"""Write any prefixes this protocol requires.
347
347
        self.finished_reading = False
348
348
        self._in_buffer_list = []
349
349
        self._in_buffer_len = 0
350
 
        self.unused_data = ''
 
350
        self.unused_data = b''
351
351
        self.bytes_left = None
352
352
        self._number_needed_bytes = None
353
353
 
354
354
    def _get_in_buffer(self):
355
355
        if len(self._in_buffer_list) == 1:
356
356
            return self._in_buffer_list[0]
357
 
        in_buffer = ''.join(self._in_buffer_list)
 
357
        in_buffer = b''.join(self._in_buffer_list)
358
358
        if len(in_buffer) != self._in_buffer_len:
359
359
            raise AssertionError(
360
360
                "Length of buffer did not match expected value: %s != %s"
466
466
 
467
467
    def _extract_line(self):
468
468
        in_buf = self._get_in_buffer()
469
 
        pos = in_buf.find('\n')
 
469
        pos = in_buf.find(b'\n')
470
470
        if pos == -1:
471
471
            # We haven't read a complete line yet, so request more bytes before
472
472
            # we continue.
489
489
 
490
490
    def _state_accept_expecting_header(self):
491
491
        prefix = self._extract_line()
492
 
        if prefix == 'chunked':
 
492
        if prefix == b'chunked':
493
493
            self.state_accept = self._state_accept_expecting_length
494
494
        else:
495
495
            raise errors.SmartProtocolError(
497
497
 
498
498
    def _state_accept_expecting_length(self):
499
499
        prefix = self._extract_line()
500
 
        if prefix == 'ERR':
 
500
        if prefix == b'ERR':
501
501
            self.error = True
502
502
            self.error_in_progress = []
503
503
            self._state_accept_expecting_length()
504
504
            return
505
 
        elif prefix == 'END':
 
505
        elif prefix == b'END':
506
506
            # We've read the end-of-body marker.
507
507
            # Any further bytes are unused data, including the bytes left in
508
508
            # the _in_buffer.
510
510
            return
511
511
        else:
512
512
            self.bytes_left = int(prefix, 16)
513
 
            self.chunk_in_progress = ''
 
513
            self.chunk_in_progress = b''
514
514
            self.state_accept = self._state_accept_reading_chunk
515
515
 
516
516
    def _state_accept_reading_chunk(self):
541
541
        _StatefulDecoder.__init__(self)
542
542
        self.state_accept = self._state_accept_expecting_length
543
543
        self.state_read = self._state_read_no_data
544
 
        self._body = ''
545
 
        self._trailer_buffer = ''
 
544
        self._body = b''
 
545
        self._trailer_buffer = b''
546
546
 
547
547
    def next_read_size(self):
548
548
        if self.bytes_left is not None:
566
566
 
567
567
    def _state_accept_expecting_length(self):
568
568
        in_buf = self._get_in_buffer()
569
 
        pos = in_buf.find('\n')
 
569
        pos = in_buf.find(b'\n')
570
570
        if pos == -1:
571
571
            return
572
572
        self.bytes_left = int(in_buf[:pos])
592
592
        self._set_in_buffer(None)
593
593
        # TODO: what if the trailer does not match "done\n"?  Should this raise
594
594
        # a ProtocolViolation exception?
595
 
        if self._trailer_buffer.startswith('done\n'):
596
 
            self.unused_data = self._trailer_buffer[len('done\n'):]
 
595
        if self._trailer_buffer.startswith(b'done\n'):
 
596
            self.unused_data = self._trailer_buffer[len(b'done\n'):]
597
597
            self.state_accept = self._state_accept_reading_unused
598
598
            self.finished_reading = True
599
599
 
602
602
        self._set_in_buffer(None)
603
603
 
604
604
    def _state_read_no_data(self):
605
 
        return ''
 
605
        return b''
606
606
 
607
607
    def _state_read_body_buffer(self):
608
608
        result = self._body
609
 
        self._body = ''
 
609
        self._body = b''
610
610
        return result
611
611
 
612
612
 
777
777
 
778
778
        while not _body_decoder.finished_reading:
779
779
            bytes = self._request.read_bytes(_body_decoder.next_read_size())
780
 
            if bytes == '':
 
780
            if bytes == b'':
781
781
                # end of file encountered reading from server
782
782
                raise errors.ConnectionReset(
783
783
                    "Connection lost while reading response body.")
866
866
        _body_decoder = ChunkedBodyDecoder()
867
867
        while not _body_decoder.finished_reading:
868
868
            bytes = self._request.read_bytes(_body_decoder.next_read_size())
869
 
            if bytes == '':
 
869
            if bytes == b'':
870
870
                # end of file encountered reading from server
871
871
                raise errors.ConnectionReset(
872
872
                    "Connection lost while reading streamed body.")
1101
1101
 
1102
1102
    def flush(self):
1103
1103
        if self._buf:
1104
 
            self._real_write_func(''.join(self._buf))
 
1104
            self._real_write_func(b''.join(self._buf))
1105
1105
            del self._buf[:]
1106
1106
            self._buf_len = 0
1107
1107
 
1109
1109
        """Serialise a readv offset list."""
1110
1110
        txt = []
1111
1111
        for start, length in offsets:
1112
 
            txt.append('%d,%d' % (start, length))
1113
 
        return '\n'.join(txt)
 
1112
            txt.append(b'%d,%d' % (start, length))
 
1113
        return b'\n'.join(txt)
1114
1114
 
1115
1115
    def _write_protocol_version(self):
1116
1116
        self._write_func(MESSAGE_VERSION_THREE)
1124
1124
        self._write_prefixed_bencode(headers)
1125
1125
 
1126
1126
    def _write_structure(self, args):
1127
 
        self._write_func('s')
 
1127
        self._write_func(b's')
1128
1128
        utf8_args = []
1129
1129
        for arg in args:
1130
1130
            if isinstance(arg, text_type):
1134
1134
        self._write_prefixed_bencode(utf8_args)
1135
1135
 
1136
1136
    def _write_end(self):
1137
 
        self._write_func('e')
 
1137
        self._write_func(b'e')
1138
1138
        self.flush()
1139
1139
 
1140
1140
    def _write_prefixed_body(self, bytes):
1141
 
        self._write_func('b')
 
1141
        self._write_func(b'b')
1142
1142
        self._write_func(struct.pack('!L', len(bytes)))
1143
1143
        self._write_func(bytes)
1144
1144
 
1145
1145
    def _write_chunked_body_start(self):
1146
 
        self._write_func('oC')
 
1146
        self._write_func(b'oC')
1147
1147
 
1148
1148
    def _write_error_status(self):
1149
 
        self._write_func('oE')
 
1149
        self._write_func(b'oE')
1150
1150
 
1151
1151
    def _write_success_status(self):
1152
 
        self._write_func('oS')
 
1152
        self._write_func(b'oS')
1153
1153
 
1154
1154
 
1155
1155
class ProtocolThreeResponder(_ProtocolThreeEncoder):