/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: John Arbash Meinel
  • Date: 2008-06-05 16:27:16 UTC
  • mfrom: (3475 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3476.
  • Revision ID: john@arbash-meinel.com-20080605162716-a3hn238tnctbfd8j
merge bzr.dev, resolve NEWS

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
 
36
from bzrlib.symbol_versioning import (deprecated_method, one_four)
38
37
 
39
38
 
40
39
class _SmartStat(object):
78
77
            one is being cloned from.  Attributes such as the medium will
79
78
            be reused.
80
79
 
81
 
        :param medium: The medium to use for this RemoteTransport. This must be
82
 
            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.
83
84
 
84
85
        :param _client: Override the _SmartClient used by this transport.  This
85
86
            should only be used for testing purposes; normally this is
104
105
            self._shared_connection = transport._SharedConnection(medium,
105
106
                                                                  credentials,
106
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
 
112
        else:
 
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))
107
117
 
108
118
        if _client is None:
109
 
            self._client = client._SmartClient(self.get_shared_medium())
 
119
            self._client = client._SmartClient(medium)
110
120
        else:
111
121
            self._client = _client
112
122
 
121
131
 
122
132
    def is_readonly(self):
123
133
        """Smart server transport can do read/write file operations."""
124
 
        resp = self._call2('Transport.is_readonly')
125
 
        if resp == ('yes', ):
126
 
            return True
127
 
        elif resp == ('no', ):
128
 
            return False
129
 
        elif (resp == ('error', "Generic bzr smart protocol error: "
130
 
                                "bad request 'Transport.is_readonly'") or
131
 
              resp == ('error', "Generic bzr smart protocol error: "
132
 
                                "bad request u'Transport.is_readonly'")):
 
134
        try:
 
135
            resp = self._call2('Transport.is_readonly')
 
136
        except errors.UnknownSmartMethod:
133
137
            # XXX: nasty hack: servers before 0.16 don't have a
134
138
            # 'Transport.is_readonly' verb, so we do what clients before 0.16
135
139
            # did: assume False.
136
140
            return False
 
141
        if resp == ('yes', ):
 
142
            return True
 
143
        elif resp == ('no', ):
 
144
            return False
137
145
        else:
138
146
            self._translate_error(resp)
139
147
        raise errors.UnexpectedSmartServerResponse(resp)
144
152
    def get_smart_medium(self):
145
153
        return self._get_connection()
146
154
 
 
155
    @deprecated_method(one_four)
147
156
    def get_shared_medium(self):
148
157
        return self._get_shared_connection()
149
158
 
152
161
        return self._combine_paths(self._path, relpath)
153
162
 
154
163
    def _call(self, method, *args):
155
 
        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)
156
168
        self._translate_error(resp)
157
169
 
158
170
    def _call2(self, method, *args):
159
171
        """Call a method on the remote server."""
160
 
        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)
161
176
 
162
177
    def _call_with_body_bytes(self, method, args, body):
163
178
        """Call a method on the remote server with body bytes."""
164
 
        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)
165
183
 
166
184
    def has(self, relpath):
167
185
        """Indicate whether a remote file of the given name exists or not.
185
203
 
186
204
    def get_bytes(self, relpath):
187
205
        remote = self._remote_path(relpath)
188
 
        request = self.get_smart_medium().get_request()
189
 
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
190
 
        smart_protocol.call('get', remote)
191
 
        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)
192
210
        if resp != ('ok', ):
193
 
            smart_protocol.cancel_read_body()
194
 
            self._translate_error(resp, relpath)
195
 
        return smart_protocol.read_body_bytes()
 
211
            response_handler.cancel_read_body()
 
212
            raise errors.UnexpectedSmartServerResponse(resp)
 
213
        return response_handler.read_body_bytes()
196
214
 
197
215
    def _serialise_optional_mode(self, mode):
198
216
        if mode is None:
301
319
                               limit=self._max_readv_combine,
302
320
                               fudge_factor=self._bytes_to_read_before_seek))
303
321
 
304
 
        request = self.get_smart_medium().get_request()
305
 
        smart_protocol = protocol.SmartClientRequestProtocolOne(request)
306
 
        smart_protocol.call_with_body_readv_array(
307
 
            ('readv', self._remote_path(relpath)),
308
 
            [(c.start, c.length) for c in coalesced])
309
 
        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)
310
329
 
311
330
        if resp[0] != 'readv':
312
331
            # This should raise an exception
313
 
            smart_protocol.cancel_read_body()
314
 
            self._translate_error(resp)
315
 
            return
 
332
            response_handler.cancel_read_body()
 
333
            raise errors.UnexpectedSmartServerResponse(resp)
316
334
 
317
335
        # FIXME: this should know how many bytes are needed, for clarity.
318
 
        data = smart_protocol.read_body_bytes()
 
336
        data = response_handler.read_body_bytes()
319
337
        # Cache the results, but only until they have been fulfilled
320
338
        data_map = {}
321
339
        for c_offset in coalesced:
452
470
    """
453
471
 
454
472
    def _build_medium(self):
455
 
        assert self.base.startswith('bzr://')
456
 
        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
457
476
 
458
477
 
459
478
class RemoteSSHTransport(RemoteTransport):
464
483
    """
465
484
 
466
485
    def _build_medium(self):
467
 
        assert self.base.startswith('bzr+ssh://')
468
486
        # ssh will prompt the user for a password if needed and if none is
469
487
        # provided but it will not give it back, so no credentials can be
470
488
        # stored.
471
489
        location_config = config.LocationConfig(self.base)
472
490
        bzr_remote_path = location_config.get_bzr_remote_path()
473
 
        return medium.SmartSSHClientMedium(self._host, self._port,
474
 
            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
475
495
 
476
496
 
477
497
class RemoteHTTPTransport(RemoteTransport):
486
506
    """
487
507
 
488
508
    def __init__(self, base, _from_transport=None, http_transport=None):
489
 
        assert ( base.startswith('bzr+http://') or base.startswith('bzr+https://') )
490
 
 
491
509
        if http_transport is None:
492
510
            # FIXME: the password may be lost here because it appears in the
493
511
            # url only for an intial construction (when the url came from the