/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 brzlib/smart/client.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-21 12:41:27 UTC
  • mto: This revision was merged to the branch mainline in revision 6623.
  • Revision ID: jelmer@jelmer.uk-20170521124127-iv8etg0vwymyai6y
s/bzr/brz/ in apport config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from ... import lazy_import
 
17
from __future__ import absolute_import
 
18
 
 
19
from brzlib import lazy_import
18
20
lazy_import.lazy_import(globals(), """
19
 
from breezy.bzr.smart import request as _mod_request
 
21
from brzlib.smart import request as _mod_request
20
22
""")
21
23
 
22
 
import breezy
23
 
from . import message, protocol
24
 
from ... import (
 
24
import brzlib
 
25
from brzlib.smart import message, protocol
 
26
from brzlib import (
25
27
    debug,
26
28
    errors,
27
29
    hooks,
38
40
        """
39
41
        self._medium = medium
40
42
        if headers is None:
41
 
            self._headers = {
42
 
                b'Software version': breezy.__version__.encode('utf-8')}
 
43
            self._headers = {'Software version': brzlib.__version__}
43
44
        else:
44
45
            self._headers = dict(headers)
45
46
 
47
48
        return '%s(%r)' % (self.__class__.__name__, self._medium)
48
49
 
49
50
    def _call_and_read_response(self, method, args, body=None, readv_body=None,
50
 
                                body_stream=None, expect_response_body=True):
 
51
            body_stream=None, expect_response_body=True):
51
52
        request = _SmartClientRequest(self, method, args, body=body,
52
 
                                      readv_body=readv_body, body_stream=body_stream,
53
 
                                      expect_response_body=expect_response_body)
 
53
            readv_body=readv_body, body_stream=body_stream,
 
54
            expect_response_body=expect_response_body)
54
55
        return request.call_and_read_response()
55
56
 
56
57
    def call(self, method, *args):
72
73
 
73
74
    def call_with_body_bytes(self, method, args, body):
74
75
        """Call a method on the remote server with body bytes."""
75
 
        if not isinstance(method, bytes):
 
76
        if type(method) is not str:
76
77
            raise TypeError('method must be a byte string, not %r' % (method,))
77
78
        for arg in args:
78
 
            if not isinstance(arg, bytes):
 
79
            if type(arg) is not str:
79
80
                raise TypeError('args must be byte strings, not %r' % (args,))
80
 
        if not isinstance(body, bytes):
 
81
        if type(body) is not str:
81
82
            raise TypeError('body must be byte string, not %r' % (body,))
82
83
        response, response_handler = self._call_and_read_response(
83
84
            method, args, body=body, expect_response_body=False)
85
86
 
86
87
    def call_with_body_bytes_expecting_body(self, method, args, body):
87
88
        """Call a method on the remote server with body bytes."""
88
 
        if not isinstance(method, bytes):
 
89
        if type(method) is not str:
89
90
            raise TypeError('method must be a byte string, not %r' % (method,))
90
91
        for arg in args:
91
 
            if not isinstance(arg, bytes):
 
92
            if type(arg) is not str:
92
93
                raise TypeError('args must be byte strings, not %r' % (args,))
93
 
        if not isinstance(body, bytes):
 
94
        if type(body) is not str:
94
95
            raise TypeError('body must be byte string, not %r' % (body,))
95
96
        response, response_handler = self._call_and_read_response(
96
97
            method, args, body=body, expect_response_body=True)
98
99
 
99
100
    def call_with_body_readv_array(self, args, body):
100
101
        response, response_handler = self._call_and_read_response(
101
 
            args[0], args[1:], readv_body=body, expect_response_body=True)
 
102
                args[0], args[1:], readv_body=body, expect_response_body=True)
102
103
        return (response, response_handler)
103
104
 
104
105
    def call_with_body_stream(self, args, stream):
105
106
        response, response_handler = self._call_and_read_response(
106
 
            args[0], args[1:], body_stream=stream,
107
 
            expect_response_body=False)
 
107
                args[0], args[1:], body_stream=stream,
 
108
                expect_response_body=False)
108
109
        return (response, response_handler)
109
110
 
110
111
    def remote_path_from_transport(self, transport):
114
115
        anything but path, so it is only safe to use it in requests sent over
115
116
        the medium from the matching transport.
116
117
        """
117
 
        return self._medium.remote_path_from_transport(transport).encode('utf-8')
 
118
        return self._medium.remote_path_from_transport(transport)
118
119
 
119
120
 
120
121
class _SmartClientRequest(object):
189
190
        try:
190
191
            response_tuple = response_handler.read_response_tuple(
191
192
                expect_body=self.expect_response_body)
192
 
        except errors.ConnectionReset as e:
 
193
        except errors.ConnectionReset, e:
193
194
            self.client._medium.reset()
194
195
            if not self._is_safe_to_send_twice():
195
196
                raise
209
210
        We do this by placing a request in the most recent protocol, and
210
211
        handling the UnexpectedProtocolVersionMarker from the server.
211
212
        """
212
 
        last_err = None
213
213
        for protocol_version in [3, 2]:
214
214
            if protocol_version == 2:
215
215
                # If v3 doesn't work, the remote side is older than 1.6.
216
216
                self.client._medium._remember_remote_is_before((1, 6))
217
217
            try:
218
218
                response_tuple, response_handler = self._call(protocol_version)
219
 
            except errors.UnexpectedProtocolVersionMarker as err:
 
219
            except errors.UnexpectedProtocolVersionMarker, err:
220
220
                # TODO: We could recover from this without disconnecting if
221
221
                # we recognise the protocol version.
222
222
                trace.warning(
224
224
                    ' reconnecting.  (Upgrade the server to avoid this.)'
225
225
                    % (protocol_version,))
226
226
                self.client._medium.disconnect()
227
 
                last_err = err
228
227
                continue
229
228
            except errors.ErrorFromSmartServer:
230
229
                # If we received an error reply from the server, then it
235
234
                self.client._medium._protocol_version = protocol_version
236
235
                return response_tuple, response_handler
237
236
        raise errors.SmartProtocolError(
238
 
            'Server is not a Bazaar server: ' + str(last_err))
 
237
            'Server is not a Bazaar server: ' + str(err))
239
238
 
240
239
    def _construct_protocol(self, version):
241
240
        """Build the encoding stack for a given protocol version."""
266
265
        encoder, response_handler = self._construct_protocol(protocol_version)
267
266
        try:
268
267
            self._send_no_retry(encoder)
269
 
        except errors.ConnectionReset as e:
 
268
        except errors.ConnectionReset, e:
270
269
            # If we fail during the _send_no_retry phase, then we can
271
270
            # be confident that the server did not get our request, because we
272
271
            # haven't started waiting for the reply yet. So try the request
275
274
 
276
275
            # Connection is dead, so close our end of it.
277
276
            self.client._medium.reset()
278
 
            if (('noretry' in debug.debug_flags) or
279
 
                (self.body_stream is not None and
280
 
                    encoder.body_stream_started)):
 
277
            if (('noretry' in debug.debug_flags)
 
278
                or (self.body_stream is not None
 
279
                    and encoder.body_stream_started)):
281
280
                # We can't restart a body_stream that has been partially
282
281
                # consumed, so we don't retry.
283
282
                # Note: We don't have to worry about
302
301
            if self.body_stream is not None:
303
302
                raise AssertionError(
304
303
                    "body and body_stream are mutually exclusive.")
305
 
            encoder.call_with_body_bytes(
306
 
                (self.method, ) + self.args, self.body)
 
304
            encoder.call_with_body_bytes((self.method, ) + self.args, self.body)
307
305
        elif self.readv_body is not None:
308
306
            if self.body_stream is not None:
309
307
                raise AssertionError(
320
318
class SmartClientHooks(hooks.Hooks):
321
319
 
322
320
    def __init__(self):
323
 
        hooks.Hooks.__init__(
324
 
            self, "breezy.bzr.smart.client", "_SmartClient.hooks")
 
321
        hooks.Hooks.__init__(self, "brzlib.smart.client", "_SmartClient.hooks")
325
322
        self.add_hook('call',
326
 
                      "Called when the smart client is submitting a request to the "
327
 
                      "smart server. Called with a breezy.bzr.smart.client.CallHookParams "
328
 
                      "object. Streaming request bodies, and responses, are not "
329
 
                      "accessible.", None)
 
323
            "Called when the smart client is submitting a request to the "
 
324
            "smart server. Called with a brzlib.smart.client.CallHookParams "
 
325
            "object. Streaming request bodies, and responses, are not "
 
326
            "accessible.", None)
330
327
 
331
328
 
332
329
_SmartClient.hooks = SmartClientHooks()
342
339
        self.medium = medium
343
340
 
344
341
    def __repr__(self):
345
 
        attrs = dict((k, v) for k, v in self.__dict__.items()
 
342
        attrs = dict((k, v) for (k, v) in self.__dict__.iteritems()
346
343
                     if v is not None)
347
344
        return '<%s %r>' % (self.__class__.__name__, attrs)
348
345
 
349
346
    def __eq__(self, other):
350
 
        if not isinstance(other, type(self)):
 
347
        if type(other) is not type(self):
351
348
            return NotImplemented
352
349
        return self.__dict__ == other.__dict__
353
350