/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 bzrlib/transport/remote.py

  • Committer: Martin Pool
  • Date: 2008-05-27 03:00:53 UTC
  • mfrom: (3452 +trunk)
  • mto: (3724.1.1 lock-hooks)
  • mto: This revision was merged to the branch mainline in revision 3730.
  • Revision ID: mbp@sourcefrog.net-20080527030053-0mct6dypek0ysjc3
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
__all__ = ['RemoteTransport', 'RemoteTCPTransport', 'RemoteSSHTransport']
24
24
 
25
25
from cStringIO import StringIO
26
 
import urllib
27
 
import urlparse
28
26
 
29
27
from bzrlib import (
30
28
    config,
34
32
    transport,
35
33
    urlutils,
36
34
    )
37
 
from bzrlib.smart import client, medium, protocol
 
35
from bzrlib.smart import client, medium
38
36
from bzrlib.symbol_versioning import (deprecated_method, one_four)
39
37
 
40
38
 
79
77
            one is being cloned from.  Attributes such as the medium will
80
78
            be reused.
81
79
 
82
 
        :param medium: The medium to use for this RemoteTransport. This must be
83
 
            supplied if _from_transport is None.
 
80
        :param medium: The medium to use for this RemoteTransport.  If None,
 
81
            the medium from the _from_transport is shared.  If both this
 
82
            and _from_transport are None, a new medium will be built.
 
83
            _from_transport and medium cannot both be specified.
84
84
 
85
85
        :param _client: Override the _SmartClient used by this transport.  This
86
86
            should only be used for testing purposes; normally this is
105
105
            self._shared_connection = transport._SharedConnection(medium,
106
106
                                                                  credentials,
107
107
                                                                  self.base)
 
108
        elif medium is None:
 
109
            # No medium was specified, so share the medium from the
 
110
            # _from_transport.
 
111
            medium = self._shared_connection.connection
108
112
        else:
109
 
            if medium is None:
110
 
                # No medium was specified, so share the medium from the
111
 
                # _from_transport.
112
 
                medium = self._shared_connection.connection
 
113
            raise AssertionError(
 
114
                "Both _from_transport (%r) and medium (%r) passed to "
 
115
                "RemoteTransport.__init__, but these parameters are mutally "
 
116
                "exclusive." % (_from_transport, medium))
113
117
 
114
118
        if _client is None:
115
 
            self._client = client._SmartClient(medium, self.base)
 
119
            self._client = client._SmartClient(medium)
116
120
        else:
117
121
            self._client = _client
118
122
 
127
131
 
128
132
    def is_readonly(self):
129
133
        """Smart server transport can do read/write file operations."""
130
 
        resp = self._call2('Transport.is_readonly')
131
 
        if resp == ('yes', ):
132
 
            return True
133
 
        elif resp == ('no', ):
134
 
            return False
135
 
        elif (resp == ('error', "Generic bzr smart protocol error: "
136
 
                                "bad request 'Transport.is_readonly'") or
137
 
              resp == ('error', "Generic bzr smart protocol error: "
138
 
                                "bad request u'Transport.is_readonly'")):
 
134
        try:
 
135
            resp = self._call2('Transport.is_readonly')
 
136
        except errors.UnknownSmartMethod:
139
137
            # XXX: nasty hack: servers before 0.16 don't have a
140
138
            # 'Transport.is_readonly' verb, so we do what clients before 0.16
141
139
            # did: assume False.
142
140
            return False
 
141
        if resp == ('yes', ):
 
142
            return True
 
143
        elif resp == ('no', ):
 
144
            return False
143
145
        else:
144
146
            self._translate_error(resp)
145
147
        raise errors.UnexpectedSmartServerResponse(resp)
159
161
        return self._combine_paths(self._path, relpath)
160
162
 
161
163
    def _call(self, method, *args):
162
 
        resp = self._call2(method, *args)
 
164
        try:
 
165
            resp = self._call2(method, *args)
 
166
        except errors.ErrorFromSmartServer, err:
 
167
            self._translate_error(err.error_tuple)
163
168
        self._translate_error(resp)
164
169
 
165
170
    def _call2(self, method, *args):
166
171
        """Call a method on the remote server."""
167
 
        return self._client.call(method, *args)
 
172
        try:
 
173
            return self._client.call(method, *args)
 
174
        except errors.ErrorFromSmartServer, err:
 
175
            self._translate_error(err.error_tuple)
168
176
 
169
177
    def _call_with_body_bytes(self, method, args, body):
170
178
        """Call a method on the remote server with body bytes."""
171
 
        return self._client.call_with_body_bytes(method, args, body)
 
179
        try:
 
180
            return self._client.call_with_body_bytes(method, args, body)
 
181
        except errors.ErrorFromSmartServer, err:
 
182
            self._translate_error(err.error_tuple)
172
183
 
173
184
    def has(self, relpath):
174
185
        """Indicate whether a remote file of the given name exists or not.
192
203
 
193
204
    def get_bytes(self, relpath):
194
205
        remote = self._remote_path(relpath)
195
 
        request = self.get_smart_medium().get_request()
196
 
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
197
 
        smart_protocol.call('get', remote)
198
 
        resp = smart_protocol.read_response_tuple(True)
 
206
        try:
 
207
            resp, response_handler = self._client.call_expecting_body('get', remote)
 
208
        except errors.ErrorFromSmartServer, err:
 
209
            self._translate_error(err.error_tuple, relpath)
199
210
        if resp != ('ok', ):
200
 
            smart_protocol.cancel_read_body()
201
 
            self._translate_error(resp, relpath)
202
 
        return smart_protocol.read_body_bytes()
 
211
            response_handler.cancel_read_body()
 
212
            raise errors.UnexpectedSmartServerResponse(resp)
 
213
        return response_handler.read_body_bytes()
203
214
 
204
215
    def _serialise_optional_mode(self, mode):
205
216
        if mode is None:
308
319
                               limit=self._max_readv_combine,
309
320
                               fudge_factor=self._bytes_to_read_before_seek))
310
321
 
311
 
        request = self.get_smart_medium().get_request()
312
 
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
313
 
        smart_protocol.call_with_body_readv_array(
314
 
            ('readv', self._remote_path(relpath)),
315
 
            [(c.start, c.length) for c in coalesced])
316
 
        resp = smart_protocol.read_response_tuple(True)
 
322
        try:
 
323
            result = self._client.call_with_body_readv_array(
 
324
                ('readv', self._remote_path(relpath),),
 
325
                [(c.start, c.length) for c in coalesced])
 
326
            resp, response_handler = result
 
327
        except errors.ErrorFromSmartServer, err:
 
328
            self._translate_error(err.error_tuple)
317
329
 
318
330
        if resp[0] != 'readv':
319
331
            # This should raise an exception
320
 
            smart_protocol.cancel_read_body()
321
 
            self._translate_error(resp)
322
 
            return
 
332
            response_handler.cancel_read_body()
 
333
            raise errors.UnexpectedSmartServerResponse(resp)
323
334
 
324
335
        # FIXME: this should know how many bytes are needed, for clarity.
325
 
        data = smart_protocol.read_body_bytes()
 
336
        data = response_handler.read_body_bytes()
326
337
        # Cache the results, but only until they have been fulfilled
327
338
        data_map = {}
328
339
        for c_offset in coalesced:
459
470
    """
460
471
 
461
472
    def _build_medium(self):
462
 
        assert self.base.startswith('bzr://')
463
 
        return medium.SmartTCPClientMedium(self._host, self._port), None
 
473
        client_medium = medium.SmartTCPClientMedium(
 
474
            self._host, self._port, self.base)
 
475
        return client_medium, None
464
476
 
465
477
 
466
478
class RemoteSSHTransport(RemoteTransport):
471
483
    """
472
484
 
473
485
    def _build_medium(self):
474
 
        assert self.base.startswith('bzr+ssh://')
475
486
        # ssh will prompt the user for a password if needed and if none is
476
487
        # provided but it will not give it back, so no credentials can be
477
488
        # stored.
478
489
        location_config = config.LocationConfig(self.base)
479
490
        bzr_remote_path = location_config.get_bzr_remote_path()
480
 
        return medium.SmartSSHClientMedium(self._host, self._port,
481
 
            self._user, self._password, bzr_remote_path=bzr_remote_path), None
 
491
        client_medium = medium.SmartSSHClientMedium(self._host, self._port,
 
492
            self._user, self._password, self.base,
 
493
            bzr_remote_path=bzr_remote_path)
 
494
        return client_medium, None
482
495
 
483
496
 
484
497
class RemoteHTTPTransport(RemoteTransport):
493
506
    """
494
507
 
495
508
    def __init__(self, base, _from_transport=None, http_transport=None):
496
 
        assert ( base.startswith('bzr+http://') or base.startswith('bzr+https://') )
497
 
 
498
509
        if http_transport is None:
499
510
            # FIXME: the password may be lost here because it appears in the
500
511
            # url only for an intial construction (when the url came from the