74
74
# RemoteTransport is an adapter from the Transport object model to the
75
75
# SmartClient model, not an encoder.
77
# FIXME: the medium parameter should be private, only the tests requires
78
# it. It may be even clearer to define a TestRemoteTransport that handles
79
# the specific cases of providing a _client and/or a _medium, and leave
80
# RemoteTransport as an abstract class.
77
81
def __init__(self, url, from_transport=None, medium=None, _client=None):
89
93
determined from the medium.
91
95
super(RemoteTransport, self).__init__(url, from_transport)
93
self._build_medium(from_transport)
98
medium = self._build_medium(from_transport)
100
self._set_connection(medium, None)
101
self._medium = medium
96
102
assert self._medium is not None
103
# ConnectedTransport provides the connection sharing by requiring
104
# daughter classes to always access the connection via _get_connection
105
# and guarantee that the connection wil be shared across all transports
106
# even if the server force a reconnection (i.e. the connection object
107
# should be built again).
109
# For RemoteTransport objects, the medium is the connection. But using
110
# _get_connection is not enough because:
111
# - self._client needs a medium to be built (and keep an internal
113
# - RemoteBzrDir RemoteRepository, RemoteRepositoryFormat RemoteBranch
114
# keep internal copies of _SmartClient objects.
116
# Therefore, the needed refactoring (enhancing _SmartClient and its
117
# users so that connection are still shared even in cases or
118
# reconnections) is too much for this round -- vila20070607
120
# On the other hand, except for the reconnection part, the sharing will
121
# already reduce the number of connections.
97
122
if _client is None:
98
123
self._client = client._SmartClient(self._medium)
102
127
def _build_medium(self, from_transport=None):
103
128
"""Create the medium if from_transport does not provide one.
104
MUST be defined by daughter classes. The medium is
105
analogous to the connection for ConnectedTransport: it
130
The medium is analogous to the connection for ConnectedTransport: it
106
131
allows connection sharing.
108
133
:param from_transport: provide the medium to reuse if not None
110
raise NotImplementedError(self._build_medium)
112
def clone(self, relative_url):
113
"""Make a new RemoteTransport related to me, sharing the same connection.
115
This essentially opens a handle on a different remote directory.
117
if relative_url is None:
118
return self.__class__(self.base, self, self._medium)
135
if from_transport is not None:
136
_medium = from_transport._medium
120
return self.__class__(self.abspath(relative_url), self,
138
import pdb; pdb.set_trace()
141
self._set_connection(_medium, None)
123
144
def is_readonly(self):
124
145
"""Smart server transport can do read/write file operations."""
140
161
assert False, 'weird response %r' % (resp,)
142
163
def get_smart_client(self):
164
return self._get_connection()
145
166
def get_smart_medium(self):
167
return self._get_connection()
148
169
def _remote_path(self, relpath):
149
170
"""Returns the Unicode version of the absolute path for relpath."""
432
453
_medium = from_transport._medium
434
455
_medium = medium.SmartTCPClientMedium(self._host, self._port)
435
self._medium = _medium
456
self._set_connection(_medium, None)
438
460
class RemoteSSHTransport(RemoteTransport):
448
470
_medium = from_transport._medium
450
472
_medium = medium.SmartSSHClientMedium(self._host, self._port,
451
self._user, self._password)
452
self._medium = _medium
473
self._user, self._password)
474
# ssh will prompt the user for a password if needed and if none is
475
# provided but it will not give it back, so no credentials can be
477
self._set_connection(_medium, None)
455
481
class RemoteHTTPTransport(RemoteTransport):
478
504
_medium = from_transport._medium
480
506
_medium = self._http_transport.get_smart_medium()
481
self._medium = _medium
507
# We let http_transport take care of the credentials
508
self._set_connection(_medium, None)
483
511
def _remote_path(self, relpath):
484
512
"""After connecting, HTTP Transport only deals in relative URLs."""