84
85
def _get_transport_modules():
85
86
"""Return a list of the modules providing transports."""
87
for prefix, factory_list in transport_list_registry.iteritems():
88
for prefix, factory_list in transport_list_registry.items():
88
89
for factory in factory_list:
89
90
if hasattr(factory, "_module_name"):
90
91
modules.add(factory._module_name)
272
273
from/to a storage location.
274
275
Most functions have a _multi variant, which allows you to queue up
275
multiple requests. They generally have a dumb base implementation
276
multiple requests. They generally have a dumb base implementation
276
277
which just iterates over the arguments, but smart Transport
277
278
implementations can do pipelining.
278
279
In general implementations should support having a generator or a list
324
325
def clone(self, offset=None):
325
326
"""Return a new Transport object, cloned from the current location,
326
using a subdirectory or parent directory. This allows connections
327
using a subdirectory or parent directory. This allows connections
327
328
to be pooled, rather than a new one needed for each subdir.
329
330
raise NotImplementedError(self.clone)
367
368
raise NotImplementedError(self.external_url)
369
370
def _pump(self, from_file, to_file):
370
"""Most children will need to copy from one file-like
371
"""Most children will need to copy from one file-like
371
372
object or string to another one.
372
373
This just gives them something easy to call.
382
383
except TypeError: # We can't tell how many, because relpaths is a generator
386
def _report_activity(self, bytes, direction):
387
"""Notify that this transport has activity.
389
Implementations should call this from all methods that actually do IO.
390
Be careful that it's not called twice, if one method is implemented on
393
:param bytes: Number of bytes read or written.
394
:param direction: 'read' or 'write' or None.
396
ui.ui_factory.report_transport_activity(self, bytes, direction)
385
398
def _update_pb(self, pb, msg, count, total):
386
399
"""Update the progress bar based on the current count
387
400
and total available, total may be None if it was
439
452
t._combine_paths('/home/sarah', '/etc')
442
:param base_path: urlencoded path for the transport root; typically a
455
:param base_path: urlencoded path for the transport root; typically a
443
456
URL but need not contain scheme/host/etc.
444
457
:param relpath: relative url string for relative part of remote path.
445
458
:return: urlencoded string for final path.
472
485
"""Return the recommended page size for this transport.
474
487
This is potentially different for every path in a given namespace.
475
For example, local transports might use an operating system call to
488
For example, local transports might use an operating system call to
476
489
get the block size for a given path, which can vary due to mount
484
497
"""Return the local path portion from a given absolute path.
486
499
This default implementation is not suitable for filesystems with
487
aliasing, such as that given by symlinks, where a path may not
488
start with our base, but still be a relpath once aliasing is
500
aliasing, such as that given by symlinks, where a path may not
501
start with our base, but still be a relpath once aliasing is
491
504
# TODO: This might want to use bzrlib.osutils.relpath
507
520
def has(self, relpath):
508
521
"""Does the file relpath exist?
510
523
Note that some transports MAY allow querying on directories, but this
511
is not part of the protocol. In other words, the results of
524
is not part of the protocol. In other words, the results of
512
525
t.has("a_directory_name") are undefined.
535
548
"""Iter the relative paths of files in the transports sub-tree.
537
550
*NOTE*: This only lists *files*, not subdirectories!
539
552
As with other listing functions, only some transports implement this,.
540
553
you may check via listable() to determine if it will.
673
690
# Cache the results, but only until they have been fulfilled
675
692
for c_offset in coalesced:
676
# TODO: jam 20060724 it might be faster to not issue seek if
693
# TODO: jam 20060724 it might be faster to not issue seek if
677
694
# we are already at the right location. This should be
679
696
fp.seek(c_offset.start)
861
878
"""Copy the string into the target location.
863
This function is not strictly safe to use. See
880
This function is not strictly safe to use. See
864
881
Transport.put_bytes_non_atomic for more information.
866
883
:param relpath: The remote location to put the contents.
948
965
be synchronised with any internal buffering that may be present.
950
967
:param relpath: The relative path to the file.
951
:param mode: The mode for the newly created file,
968
:param mode: The mode for the newly created file,
952
969
None means just use the default
953
970
:return: A FileStream. FileStream objects have two methods, write() and
954
971
close(). There is no guarantee that data is committed to the file
1004
1021
def copy(self, rel_from, rel_to):
1005
1022
"""Copy the item at rel_from to the location at rel_to.
1007
Override this for efficiency if a specific transport can do it
1024
Override this for efficiency if a specific transport can do it
1008
1025
faster than this default implementation.
1010
1027
self.put_file(rel_to, self.get(rel_from))
1012
1029
def copy_multi(self, relpaths, pb=None):
1013
1030
"""Copy a bunch of entries.
1015
1032
:param relpaths: A list of tuples of the form [(from, to), (from, to),...]
1017
1034
# This is the non-pipelined implementation, so that
1035
1052
def copy_tree(self, from_relpath, to_relpath):
1036
1053
"""Copy a subtree from one relpath to another.
1038
If a faster implementation is available, specific transports should
1055
If a faster implementation is available, specific transports should
1041
1058
source = self.clone(from_relpath)
1103
1120
def move_multi(self, relpaths, pb=None):
1104
1121
"""Move a bunch of entries.
1106
1123
:param relpaths: A list of tuples of the form [(from1, to1), (from2, to2),...]
1108
1125
return self._iterate_over(relpaths, self.move, pb, 'move', expand=True)
1161
1178
NOTE: This returns an object with fields such as 'st_size'. It MAY
1162
1179
or MAY NOT return the literal result of an os.stat() call, so all
1163
1180
access should be via named fields.
1164
ALSO NOTE: Stats of directories may not be supported on some
1181
ALSO NOTE: Stats of directories may not be supported on some
1167
1184
raise NotImplementedError(self.stat)
1204
1221
These methods may be removed in the future.
1206
1223
Transports may raise TransportNotPossible if OS-level locks cannot be
1207
taken over this transport.
1224
taken over this transport.
1209
1226
:return: A lock object, which should contain an unlock() function.
1231
1248
"""Return true if this transport can store and retrieve unix modebits.
1233
1250
(For example, 0700 to make a directory owner-private.)
1235
Note: most callers will not want to switch on this, but should rather
1252
Note: most callers will not want to switch on this, but should rather
1236
1253
just try and set permissions and let them be either stored or not.
1237
1254
This is intended mainly for the use of the test suite.
1239
Warning: this is not guaranteed to be accurate as sometimes we can't
1256
Warning: this is not guaranteed to be accurate as sometimes we can't
1240
1257
be sure: for example with vfat mounted on unix, or a windows sftp
1242
1259
# TODO: Perhaps return a e.g. TransportCharacteristics that can answer
1249
1266
# should be asked to ConnectedTransport only.
1269
def _redirected_to(self, source, target):
1270
"""Returns a transport suitable to re-issue a redirected request.
1272
:param source: The source url as returned by the server.
1273
:param target: The target url as returned by the server.
1275
The redirection can be handled only if the relpath involved is not
1276
renamed by the redirection.
1278
:returns: A transport or None.
1280
# This returns None by default, meaning the transport can't handle the
1253
1286
class _SharedConnection(object):
1254
1287
"""A connection shared between several transports."""
1421
1454
def abspath(self, relpath):
1422
1455
"""Return the full url to the given relative path.
1424
1457
:param relpath: the relative path urlencoded
1426
1459
:returns: the Unicode version of the absolute path for relpath.
1487
1520
Some protocols can renegociate the credentials within a connection,
1488
1521
this method allows daughter classes to share updated credentials.
1490
1523
:param credentials: the updated credentials.
1492
1525
# We don't want to call _set_connection here as we are only updating
1560
1593
def convert_path_to_url(base, error_str):
1561
1594
m = _urlRE.match(base)
1563
# This looks like a URL, but we weren't able to
1596
# This looks like a URL, but we weren't able to
1564
1597
# instantiate it as such raise an appropriate error
1565
1598
# FIXME: we have a 'error_str' unused and we use last_err below
1566
1599
raise errors.UnsupportedProtocol(base, last_err)
1587
1620
possible_transports.append(t_same_connection)
1588
1621
return t_same_connection
1590
for proto, factory_list in transport_list_registry.iteritems():
1623
for proto, factory_list in transport_list_registry.items():
1591
1624
if proto is not None and base.startswith(proto):
1592
1625
transport, last_err = _try_transport_factories(base, factory_list)
1632
1665
:param action: A callable, what the caller want to do while catching
1634
1667
:param transport: The initial transport used.
1635
:param redirected: A callable receiving the redirected transport and the
1668
:param redirected: A callable receiving the redirected transport and the
1636
1669
RedirectRequested exception.
1638
1671
:return: Whatever 'action' returns
1666
1699
class Server(object):
1667
1700
"""A Transport Server.
1669
1702
The Server interface provides a server for a given transport. We use
1670
1703
these servers as loopback testing tools. For any given transport the
1671
1704
Servers it provides must either allow writing, or serve the contents
1672
1705
of os.getcwdu() at the time setUp is called.
1674
1707
Note that these are real servers - they must implement all the things
1675
1708
that we want bzr transports to take advantage of.
1684
1717
def get_url(self):
1685
1718
"""Return a url for this server.
1687
If the transport does not represent a disk directory (i.e. it is
1720
If the transport does not represent a disk directory (i.e. it is
1688
1721
a database like svn, or a memory only transport, it should return
1689
1722
a connection to a newly established resource for this Server.
1690
1723
Otherwise it should return a url that will provide access to the path
1691
1724
that was os.getcwdu() when setUp() was called.
1693
1726
Subsequent calls will return the same resource.
1695
1728
raise NotImplementedError
1697
1730
def get_bogus_url(self):
1698
1731
"""Return a url for this protocol, that will fail to connect.
1700
1733
This may raise NotImplementedError to indicate that this server cannot
1701
1734
provide bogus urls.
1739
1772
help="Read-only access of branches exported on the web.")
1740
1773
register_transport_proto('https://',
1741
1774
help="Read-only access of branches exported on the web using SSL.")
1775
# The default http implementation is urllib, but https is pycurl if available
1776
register_lazy_transport('http://', 'bzrlib.transport.http._pycurl',
1742
1778
register_lazy_transport('http://', 'bzrlib.transport.http._urllib',
1743
1779
'HttpTransport_urllib')
1744
1780
register_lazy_transport('https://', 'bzrlib.transport.http._urllib',
1745
1781
'HttpTransport_urllib')
1746
register_lazy_transport('http://', 'bzrlib.transport.http._pycurl',
1748
1782
register_lazy_transport('https://', 'bzrlib.transport.http._pycurl',
1749
1783
'PyCurlTransport')
1756
1790
# Default to trying GSSAPI authentication (if the kerberos module is available)
1757
1791
register_transport_proto('ftp+gssapi://', register_netloc=True)
1758
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1792
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1759
1793
'GSSAPIFtpTransport')
1760
1794
register_transport_proto('aftp+gssapi://', register_netloc=True)
1761
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1795
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1762
1796
'GSSAPIFtpTransport')
1763
1797
register_transport_proto('ftp+nogssapi://', register_netloc=True)
1764
1798
register_transport_proto('aftp+nogssapi://', register_netloc=True)
1766
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi',
1767
'GSSAPIFtpTransport')
1768
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi',
1769
'GSSAPIFtpTransport')
1770
register_lazy_transport('ftp+nogssapi://', 'bzrlib.transport.ftp',
1800
register_lazy_transport('ftp://', 'bzrlib.transport.ftp._gssapi',
1801
'GSSAPIFtpTransport')
1802
register_lazy_transport('aftp://', 'bzrlib.transport.ftp._gssapi',
1803
'GSSAPIFtpTransport')
1804
register_lazy_transport('ftp+nogssapi://', 'bzrlib.transport.ftp',
1771
1805
'FtpTransport')
1772
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1806
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1773
1807
'FtpTransport')
1775
1809
register_transport_proto('memory://')
1845
1879
register_netloc=True)
1846
1880
register_lazy_transport('bzr+ssh://', 'bzrlib.transport.remote',
1847
1881
'RemoteSSHTransport')
1883
register_transport_proto('ssh:')
1884
register_lazy_transport('ssh:', 'bzrlib.transport.remote',
1885
'HintingSSHTransport')