~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2005-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.11.19 by John Arbash Meinel
Testing put and append, also testing agaist file-like objects as well as strings.
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.11.19 by John Arbash Meinel
Testing put and append, also testing agaist file-like objects as well as strings.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.11.19 by John Arbash Meinel
Testing put and append, also testing agaist file-like objects as well as strings.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
16
1185.11.19 by John Arbash Meinel
Testing put and append, also testing agaist file-like objects as well as strings.
17
"""Transport is an abstraction layer to handle file access.
18
19
The abstraction is to allow access from the local filesystem, as well
20
as remote (such as http or sftp).
1540.3.12 by Martin Pool
Multiple transports can be registered for any protocol, and they are
21
22
Transports are constructed from a string, being a URL or (as a degenerate
23
case) a local filesystem path.  This is typically the top directory of
24
a bzrdir, repository, or similar object we are interested in working with.
25
The Transport returned has methods to read, write and manipulate files within
26
it.
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
27
"""
28
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
29
from cStringIO import StringIO
30
import re
31
import sys
32
33
from bzrlib.lazy_import import lazy_import
34
lazy_import(globals(), """
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
35
import errno
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
36
from stat import S_ISDIR
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
37
import urllib
1636.1.1 by Robert Collins
Fix calling relpath() and abspath() on transports at their root.
38
import urlparse
1530.1.1 by Robert Collins
Minimal infrastructure to test TransportTestProviderAdapter.
39
1955.3.6 by John Arbash Meinel
Lots of deprecation warnings, but no errors
40
from bzrlib import (
41
    errors,
42
    osutils,
43
    symbol_versioning,
3882.7.5 by Martin Pool
Further mockup of transport-based activity indicator.
44
    ui,
1955.3.6 by John Arbash Meinel
Lots of deprecation warnings, but no errors
45
    urlutils,
46
    )
1996.3.6 by John Arbash Meinel
Find a few places that weren't importing their dependencies.
47
""")
48
1955.3.6 by John Arbash Meinel
Lots of deprecation warnings, but no errors
49
from bzrlib.symbol_versioning import (
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
50
        DEPRECATED_PARAMETER,
1955.3.6 by John Arbash Meinel
Lots of deprecation warnings, but no errors
51
        )
2164.2.21 by Vincent Ladeuil
Take bundles into account.
52
from bzrlib.trace import (
53
    mutter,
54
    )
2241.2.1 by ghigo
Add the TransportRegistry class
55
from bzrlib import registry
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
56
57
2671.3.2 by Robert Collins
Start open_file_stream logic.
58
# a dictionary of open file streams. Keys are absolute paths, values are
59
# transport defined.
60
_file_streams = {}
61
62
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
63
def _get_protocol_handlers():
1540.3.12 by Martin Pool
Multiple transports can be registered for any protocol, and they are
64
    """Return a dictionary of {urlprefix: [factory]}"""
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
65
    return transport_list_registry
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
66
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
67
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
68
def _set_protocol_handlers(new_handlers):
69
    """Replace the current protocol handlers dictionary.
70
71
    WARNING this will remove all build in protocols. Use with care.
72
    """
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
73
    global transport_list_registry
74
    transport_list_registry = new_handlers
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
75
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
76
1540.3.12 by Martin Pool
Multiple transports can be registered for any protocol, and they are
77
def _clear_protocol_handlers():
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
78
    global transport_list_registry
79
    transport_list_registry = TransportListRegistry()
1540.3.12 by Martin Pool
Multiple transports can be registered for any protocol, and they are
80
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
81
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
82
def _get_transport_modules():
83
    """Return a list of the modules providing transports."""
84
    modules = set()
3882.1.1 by Martin Pool
Don't call iteritems on transport_list_registry, because it may change during iteration
85
    for prefix, factory_list in transport_list_registry.items():
1540.3.12 by Martin Pool
Multiple transports can be registered for any protocol, and they are
86
        for factory in factory_list:
2241.2.2 by ghigo
Create the TransportList class
87
            if hasattr(factory, "_module_name"):
88
                modules.add(factory._module_name)
1540.3.12 by Martin Pool
Multiple transports can be registered for any protocol, and they are
89
            else:
2241.2.2 by ghigo
Create the TransportList class
90
                modules.add(factory._obj.__module__)
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
91
    # Add chroot and pathfilter directly, because there is no handler
92
    # registered for it.
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
93
    modules.add('bzrlib.transport.chroot')
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
94
    modules.add('bzrlib.transport.pathfilter')
1530.1.19 by Robert Collins
Make transport test adapter tests reliable.
95
    result = list(modules)
96
    result.sort()
97
    return result
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
98
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
99
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
100
class TransportListRegistry(registry.Registry):
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
101
    """A registry which simplifies tracking available Transports.
102
3764.1.1 by Vincent Ladeuil
Fix typo
103
    A registration of a new protocol requires two steps:
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
104
    1) register the prefix with the function register_transport( )
105
    2) register the protocol provider with the function
106
    register_transport_provider( ) ( and the "lazy" variant )
107
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
108
    This is needed because:
4764.1.1 by Vincent Ladeuil
Fix typos.
109
    a) a single provider can support multiple protocols ( like the ftp
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
110
    provider which supports both the ftp:// and the aftp:// protocols )
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
111
    b) a single protocol can have multiple providers ( like the http://
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
112
    protocol which is supported by both the urllib and pycurl provider )
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
113
    """
114
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
115
    def register_transport_provider(self, key, obj):
116
        self.get(key).insert(0, registry._ObjectGetter(obj))
117
118
    def register_lazy_transport_provider(self, key, module_name, member_name):
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
119
        self.get(key).insert(0,
2241.2.1 by ghigo
Add the TransportRegistry class
120
                registry._LazyObjectGetter(module_name, member_name))
121
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
122
    def register_transport(self, key, help=None):
123
        self.register(key, [], help)
2241.2.1 by ghigo
Add the TransportRegistry class
124
125
    def set_default_transport(self, key=None):
126
        """Return either 'key' or the default key if key is None"""
127
        self._default_key = key
128
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
129
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
130
transport_list_registry = TransportListRegistry()
2241.2.1 by ghigo
Add the TransportRegistry class
131
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
132
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
133
def register_transport_proto(prefix, help=None, info=None,
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
134
                             register_netloc=False):
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
135
    transport_list_registry.register_transport(prefix, help)
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
136
    if register_netloc:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
137
        if not prefix.endswith('://'):
138
            raise ValueError(prefix)
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
139
        register_urlparse_netloc_protocol(prefix[:-3])
2241.2.1 by ghigo
Add the TransportRegistry class
140
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
141
2241.2.1 by ghigo
Add the TransportRegistry class
142
def register_lazy_transport(prefix, module, classname):
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
143
    if not prefix in transport_list_registry:
2241.2.2 by ghigo
Create the TransportList class
144
        register_transport_proto(prefix)
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
145
    transport_list_registry.register_lazy_transport_provider(prefix, module, classname)
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
146
147
2241.2.1 by ghigo
Add the TransportRegistry class
148
def register_transport(prefix, klass, override=DEPRECATED_PARAMETER):
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
149
    if not prefix in transport_list_registry:
2241.2.2 by ghigo
Create the TransportList class
150
        register_transport_proto(prefix)
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
151
    transport_list_registry.register_transport_provider(prefix, klass)
2241.2.1 by ghigo
Add the TransportRegistry class
152
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
153
1636.1.2 by Robert Collins
More review fixen to the relpath at '/' fixes.
154
def register_urlparse_netloc_protocol(protocol):
1636.1.1 by Robert Collins
Fix calling relpath() and abspath() on transports at their root.
155
    """Ensure that protocol is setup to be used with urlparse netloc parsing."""
156
    if protocol not in urlparse.uses_netloc:
157
        urlparse.uses_netloc.append(protocol)
158
2241.3.4 by ghigo
Updates on the basis of John Arbash Meinel comments
159
2485.8.61 by Vincent Ladeuil
From review comments, use a private scheme for testing.
160
def _unregister_urlparse_netloc_protocol(protocol):
161
    """Remove protocol from urlparse netloc parsing.
162
163
    Except for tests, you should never use that function. Using it with 'http',
164
    for example, will break all http transports.
165
    """
166
    if protocol in urlparse.uses_netloc:
167
        urlparse.uses_netloc.remove(protocol)
168
169
2241.3.5 by ghigo
update to the latest bzr.dev
170
def unregister_transport(scheme, factory):
171
    """Unregister a transport."""
172
    l = transport_list_registry.get(scheme)
173
    for i in l:
174
        o = i.get_obj( )
175
        if o == factory:
176
            transport_list_registry.get(scheme).remove(i)
177
            break
178
    if len(l) == 0:
179
        transport_list_registry.remove(scheme)
180
181
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
182
class _CoalescedOffset(object):
183
    """A data container for keeping track of coalesced offsets."""
184
185
    __slots__ = ['start', 'length', 'ranges']
186
187
    def __init__(self, start, length, ranges):
188
        self.start = start
189
        self.length = length
190
        self.ranges = ranges
191
192
    def __cmp__(self, other):
193
        return cmp((self.start, self.length, self.ranges),
194
                   (other.start, other.length, other.ranges))
195
3059.2.2 by Vincent Ladeuil
Read http responses on demand without buffering the whole body
196
    def __repr__(self):
197
        return '%s(%r, %r, %r)' % (self.__class__.__name__,
198
            self.start, self.length, self.ranges)
199
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
200
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
201
class LateReadError(object):
202
    """A helper for transports which pretends to be a readable file.
203
204
    When read() is called, errors.ReadError is raised.
205
    """
206
207
    def __init__(self, path):
208
        self._path = path
209
210
    def close(self):
211
        """a no-op - do nothing."""
212
2052.6.2 by Robert Collins
Merge bzr.dev.
213
    def _fail(self):
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
214
        """Raise ReadError."""
215
        raise errors.ReadError(self._path)
216
2052.6.2 by Robert Collins
Merge bzr.dev.
217
    def __iter__(self):
218
        self._fail()
219
220
    def read(self, count=-1):
221
        self._fail()
222
223
    def readlines(self):
224
        self._fail()
225
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
226
2671.3.6 by Robert Collins
Review feedback.
227
class FileStream(object):
228
    """Base class for FileStreams."""
229
230
    def __init__(self, transport, relpath):
231
        """Create a FileStream for relpath on transport."""
232
        self.transport = transport
233
        self.relpath = relpath
234
235
    def _close(self):
236
        """A hook point for subclasses that need to take action on close."""
237
238
    def close(self):
239
        self._close()
240
        del _file_streams[self.transport.abspath(self.relpath)]
241
242
243
class FileFileStream(FileStream):
2671.3.9 by Robert Collins
Review feedback and fix VFat emulated transports to not claim to have unix permissions.
244
    """A file stream object returned by open_write_stream.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
245
2671.3.6 by Robert Collins
Review feedback.
246
    This version uses a file like object to perform writes.
247
    """
248
249
    def __init__(self, transport, relpath, file_handle):
250
        FileStream.__init__(self, transport, relpath)
251
        self.file_handle = file_handle
252
253
    def _close(self):
254
        self.file_handle.close()
255
256
    def write(self, bytes):
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
257
        osutils.pump_string_file(bytes, self.file_handle)
2671.3.6 by Robert Collins
Review feedback.
258
259
260
class AppendBasedFileStream(FileStream):
2671.3.9 by Robert Collins
Review feedback and fix VFat emulated transports to not claim to have unix permissions.
261
    """A file stream object returned by open_write_stream.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
262
2671.3.6 by Robert Collins
Review feedback.
263
    This version uses append on a transport to perform writes.
264
    """
265
266
    def write(self, bytes):
267
        self.transport.append_bytes(self.relpath, bytes)
268
269
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
270
class Transport(object):
271
    """This class encapsulates methods for retrieving or putting a file
272
    from/to a storage location.
273
274
    Most functions have a _multi variant, which allows you to queue up
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
275
    multiple requests. They generally have a dumb base implementation
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
276
    which just iterates over the arguments, but smart Transport
277
    implementations can do pipelining.
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
278
    In general implementations should support having a generator or a list
279
    as an argument (ie always iterate, never index)
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
280
281
    :ivar base: Base URL for the transport; should always end in a slash.
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
282
    """
283
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
284
    # implementations can override this if it is more efficient
285
    # for them to combine larger read chunks together
1864.5.4 by John Arbash Meinel
play around with tuning the partial reads.
286
    _max_readv_combine = 50
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
287
    # It is better to read this much more data in order, rather
288
    # than doing another seek. Even for the local filesystem,
289
    # there is a benefit in just reading.
290
    # TODO: jam 20060714 Do some real benchmarking to figure out
291
    #       where the biggest benefit between combining reads and
1864.5.8 by John Arbash Meinel
Cleanup and NEWS
292
    #       and seeking is. Consider a runtime auto-tune.
1864.5.4 by John Arbash Meinel
play around with tuning the partial reads.
293
    _bytes_to_read_before_seek = 0
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
294
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
295
    def __init__(self, base):
3734.2.3 by Vincent Ladeuil
Don't use multiple inheritance for http smart medium since we
296
        super(Transport, self).__init__()
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
297
        self.base = base
298
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
299
    def _translate_error(self, e, path, raise_generic=True):
300
        """Translate an IOError or OSError into an appropriate bzr error.
301
302
        This handles things like ENOENT, ENOTDIR, EEXIST, and EACCESS
303
        """
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
304
        if getattr(e, 'errno', None) is not None:
3146.4.1 by Aaron Bentley
Python 2.5 on win32 can emit errno.EINVAL when listing a non-directory
305
            if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
306
                raise errors.NoSuchFile(path, extra=e)
1185.31.58 by John Arbash Meinel
Updating for new transport tests so that they pass on win32
307
            # I would rather use errno.EFOO, but there doesn't seem to be
308
            # any matching for 267
309
            # This is the error when doing a listdir on a file:
310
            # WindowsError: [Errno 267] The directory name is invalid
311
            if sys.platform == 'win32' and e.errno in (errno.ESRCH, 267):
312
                raise errors.NoSuchFile(path, extra=e)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
313
            if e.errno == errno.EEXIST:
314
                raise errors.FileExists(path, extra=e)
315
            if e.errno == errno.EACCES:
316
                raise errors.PermissionDenied(path, extra=e)
1553.5.10 by Martin Pool
New DirectoryNotEmpty exception, and raise this from local and memory
317
            if e.errno == errno.ENOTEMPTY:
318
                raise errors.DirectoryNotEmpty(path, extra=e)
1558.10.1 by Aaron Bentley
Handle lockdirs over NFS properly
319
            if e.errno == errno.EBUSY:
320
                raise errors.ResourceBusy(path, extra=e)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
321
        if raise_generic:
322
            raise errors.TransportError(orig_error=e)
323
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
324
    def clone(self, offset=None):
325
        """Return a new Transport object, cloned from the current location,
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
326
        using a subdirectory or parent directory. This allows connections
1185.11.6 by John Arbash Meinel
Made HttpTransport handle a request for a parent directory differently.
327
        to be pooled, rather than a new one needed for each subdir.
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
328
        """
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
329
        raise NotImplementedError(self.clone)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
330
4294.2.1 by Robert Collins
Move directory checking for bzr push options into Branch.create_clone_on_transport.
331
    def create_prefix(self):
4294.2.10 by Robert Collins
Review feedback.
332
        """Create all the directories leading down to self.base."""
4294.2.1 by Robert Collins
Move directory checking for bzr push options into Branch.create_clone_on_transport.
333
        cur_transport = self
334
        needed = [cur_transport]
335
        # Recurse upwards until we can create a directory successfully
336
        while True:
337
            new_transport = cur_transport.clone('..')
338
            if new_transport.base == cur_transport.base:
339
                raise errors.BzrCommandError(
340
                    "Failed to create path prefix for %s."
341
                    % cur_transport.base)
342
            try:
343
                new_transport.mkdir('.')
344
            except errors.NoSuchFile:
345
                needed.append(new_transport)
346
                cur_transport = new_transport
347
            except errors.FileExists:
348
                break
349
            else:
350
                break
351
        # Now we only need to create child directories
352
        while needed:
353
            cur_transport = needed.pop()
354
            cur_transport.ensure_base()
355
2475.3.2 by John Arbash Meinel
Add Transport.ensure_base()
356
    def ensure_base(self):
357
        """Ensure that the directory this transport references exists.
358
359
        This will create a directory if it doesn't exist.
360
        :return: True if the directory was created, False otherwise.
361
        """
362
        # The default implementation just uses "Easier to ask for forgiveness
363
        # than permission". We attempt to create the directory, and just
2805.3.1 by Martin Pool
Transport.ensure_base should ignore PermissionDenied when trying to create the directory (Axel Kollmorgen)
364
        # suppress FileExists and PermissionDenied (for Windows) exceptions.
2475.3.2 by John Arbash Meinel
Add Transport.ensure_base()
365
        try:
366
            self.mkdir('.')
2805.3.1 by Martin Pool
Transport.ensure_base should ignore PermissionDenied when trying to create the directory (Axel Kollmorgen)
367
        except (errors.FileExists, errors.PermissionDenied):
2475.3.2 by John Arbash Meinel
Add Transport.ensure_base()
368
            return False
369
        else:
370
            return True
371
2634.1.1 by Robert Collins
(robertc) Reinstate the accidentally backed out external_url patch.
372
    def external_url(self):
373
        """Return a URL for self that can be given to an external process.
374
375
        There is no guarantee that the URL can be accessed from a different
376
        machine - e.g. file:/// urls are only usable on the local machine,
377
        sftp:/// urls when the server is only bound to localhost are only
378
        usable from localhost etc.
379
380
        NOTE: This method may remove security wrappers (e.g. on chroot
381
        transports) and thus should *only* be used when the result will not
382
        be used to obtain a new transport within bzrlib. Ideally chroot
383
        transports would know enough to cause the external url to be the exact
384
        one used that caused the chrooting in the first place, but that is not
385
        currently the case.
386
387
        :return: A URL that can be given to another process.
388
        :raises InProcessTransport: If the transport is one that cannot be
389
            accessed out of the current process (e.g. a MemoryTransport)
390
            then InProcessTransport is raised.
391
        """
392
        raise NotImplementedError(self.external_url)
393
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
394
    def _pump(self, from_file, to_file):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
395
        """Most children will need to copy from one file-like
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
396
        object or string to another one.
397
        This just gives them something easy to call.
398
        """
2745.5.2 by Robert Collins
* ``bzrlib.transport.Transport.put_file`` now returns the number of bytes
399
        return osutils.pumpfile(from_file, to_file)
1948.3.8 by Vincent LADEUIL
_pump accepts strings finally :)
400
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
401
    def _get_total(self, multi):
402
        """Try to figure out how many entries are in multi,
403
        but if not possible, return None.
404
        """
405
        try:
406
            return len(multi)
407
        except TypeError: # We can't tell how many, because relpaths is a generator
408
            return None
409
3882.7.1 by Martin Pool
Add stub _report_activity method as a transport callback
410
    def _report_activity(self, bytes, direction):
411
        """Notify that this transport has activity.
412
413
        Implementations should call this from all methods that actually do IO.
414
        Be careful that it's not called twice, if one method is implemented on
415
        top of another.
416
417
        :param bytes: Number of bytes read or written.
418
        :param direction: 'read' or 'write' or None.
419
        """
3882.7.5 by Martin Pool
Further mockup of transport-based activity indicator.
420
        ui.ui_factory.report_transport_activity(self, bytes, direction)
3882.7.1 by Martin Pool
Add stub _report_activity method as a transport callback
421
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
422
    def _update_pb(self, pb, msg, count, total):
423
        """Update the progress bar based on the current count
424
        and total available, total may be None if it was
425
        not possible to determine.
426
        """
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
427
        if pb is None:
428
            return
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
429
        if total is None:
430
            pb.update(msg, count, count+1)
431
        else:
432
            pb.update(msg, count, total)
433
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
434
    def _iterate_over(self, multi, func, pb, msg, expand=True):
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
435
        """Iterate over all entries in multi, passing them to func,
436
        and update the progress bar as you go along.
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
437
438
        :param expand:  If True, the entries will be passed to the function
439
                        by expanding the tuple. If False, it will be passed
440
                        as a single parameter.
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
441
        """
442
        total = self._get_total(multi)
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
443
        result = []
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
444
        count = 0
445
        for entry in multi:
446
            self._update_pb(pb, msg, count, total)
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
447
            if expand:
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
448
                result.append(func(*entry))
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
449
            else:
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
450
                result.append(func(entry))
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
451
            count += 1
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
452
        return tuple(result)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
453
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
454
    def abspath(self, relpath):
455
        """Return the full url to the given relative path.
1910.16.6 by Andrew Bennetts
Update Transport.abspath docstring.
456
457
        :param relpath: a string of a relative path
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
458
        """
1442.1.44 by Robert Collins
Many transport related tweaks:
459
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
460
        # XXX: Robert Collins 20051016 - is this really needed in the public
461
        # interface ?
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
462
        raise NotImplementedError(self.abspath)
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
463
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
464
    def _combine_paths(self, base_path, relpath):
465
        """Transform a Transport-relative path to a remote absolute path.
466
467
        This does not handle substitution of ~ but does handle '..' and '.'
468
        components.
469
470
        Examples::
471
1996.3.20 by John Arbash Meinel
[merge] bzr.dev 2063
472
            t._combine_paths('/home/sarah', 'project/foo')
473
                => '/home/sarah/project/foo'
474
            t._combine_paths('/home/sarah', '../../etc')
475
                => '/etc'
2070.3.2 by Andrew Bennetts
Merge from bzr.dev
476
            t._combine_paths('/home/sarah', '/etc')
477
                => '/etc'
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
478
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
479
        :param base_path: urlencoded path for the transport root; typically a
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
480
             URL but need not contain scheme/host/etc.
481
        :param relpath: relative url string for relative part of remote path.
482
        :return: urlencoded string for final path.
483
        """
484
        if not isinstance(relpath, str):
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
485
            raise errors.InvalidURL(relpath)
1910.19.1 by Andrew Bennetts
Support bzr:// urls to work with the new RPC-based transport which will be used
486
        if relpath.startswith('/'):
487
            base_parts = []
488
        else:
489
            base_parts = base_path.split('/')
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
490
        if len(base_parts) > 0 and base_parts[-1] == '':
491
            base_parts = base_parts[:-1]
492
        for p in relpath.split('/'):
493
            if p == '..':
494
                if len(base_parts) == 0:
495
                    # In most filesystems, a request for the parent
496
                    # of root, just returns root.
497
                    continue
498
                base_parts.pop()
499
            elif p == '.':
500
                continue # No-op
501
            elif p != '':
502
                base_parts.append(p)
503
        path = '/'.join(base_parts)
2070.3.1 by Andrew Bennetts
Fix memory_transport.abspath('/foo')
504
        if not path.startswith('/'):
505
            path = '/' + path
1910.16.2 by Andrew Bennetts
Reduce transport code duplication by creating a '_combine_paths' method to Transport.
506
        return path
507
2671.3.1 by Robert Collins
* New method ``bzrlib.transport.Transport.get_recommended_page_size``.
508
    def recommended_page_size(self):
509
        """Return the recommended page size for this transport.
510
511
        This is potentially different for every path in a given namespace.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
512
        For example, local transports might use an operating system call to
2671.3.1 by Robert Collins
* New method ``bzrlib.transport.Transport.get_recommended_page_size``.
513
        get the block size for a given path, which can vary due to mount
514
        points.
515
516
        :return: The page size in bytes.
517
        """
518
        return 4 * 1024
519
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
520
    def relpath(self, abspath):
521
        """Return the local path portion from a given absolute path.
1442.1.44 by Robert Collins
Many transport related tweaks:
522
523
        This default implementation is not suitable for filesystems with
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
524
        aliasing, such as that given by symlinks, where a path may not
525
        start with our base, but still be a relpath once aliasing is
1442.1.44 by Robert Collins
Many transport related tweaks:
526
        resolved.
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
527
        """
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
528
        # TODO: This might want to use bzrlib.osutils.relpath
529
        #       but we have to watch out because of the prefix issues
1530.1.3 by Robert Collins
transport implementations now tested consistently.
530
        if not (abspath == self.base[:-1] or abspath.startswith(self.base)):
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
531
            raise errors.PathNotChild(abspath, self.base)
1442.1.44 by Robert Collins
Many transport related tweaks:
532
        pl = len(self.base)
1530.1.3 by Robert Collins
transport implementations now tested consistently.
533
        return abspath[pl:].strip('/')
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
534
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
535
    def local_abspath(self, relpath):
536
        """Return the absolute path on the local filesystem.
537
538
        This function will only be defined for Transports which have a
539
        physical local filesystem representation.
5200.2.1 by Robert Collins
Minor local_abspath docstring improvement.
540
541
        :raises errors.NotLocalUrl: When no local path representation is
542
            available.
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
543
        """
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
544
        raise errors.NotLocalUrl(self.abspath(relpath))
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
545
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
546
    def has(self, relpath):
1442.1.44 by Robert Collins
Many transport related tweaks:
547
        """Does the file relpath exist?
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
548
1442.1.44 by Robert Collins
Many transport related tweaks:
549
        Note that some transports MAY allow querying on directories, but this
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
550
        is not part of the protocol.  In other words, the results of
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
551
        t.has("a_directory_name") are undefined.
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
552
553
        :rtype: bool
1442.1.44 by Robert Collins
Many transport related tweaks:
554
        """
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
555
        raise NotImplementedError(self.has)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
556
907.1.36 by John Arbash Meinel
Moving the multi-get functionality higher up into the Branch class.
557
    def has_multi(self, relpaths, pb=None):
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
558
        """Return True/False for each entry in relpaths"""
559
        total = self._get_total(relpaths)
560
        count = 0
561
        for relpath in relpaths:
907.1.36 by John Arbash Meinel
Moving the multi-get functionality higher up into the Branch class.
562
            self._update_pb(pb, 'has', count, total)
907.1.34 by John Arbash Meinel
Fixing append(), cleaning up function locations.
563
            yield self.has(relpath)
564
            count += 1
565
1185.16.155 by John Arbash Meinel
Added a has_any function to the Transport API
566
    def has_any(self, relpaths):
567
        """Return True if any of the paths exist."""
568
        for relpath in relpaths:
569
            if self.has(relpath):
570
                return True
571
        return False
572
1442.1.44 by Robert Collins
Many transport related tweaks:
573
    def iter_files_recursive(self):
574
        """Iter the relative paths of files in the transports sub-tree.
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
575
576
        *NOTE*: This only lists *files*, not subdirectories!
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
577
1442.1.44 by Robert Collins
Many transport related tweaks:
578
        As with other listing functions, only some transports implement this,.
3484.1.1 by Vincent Ladeuil
Trivial drive-by cleanups.
579
        you may check via listable() to determine if it will.
1442.1.44 by Robert Collins
Many transport related tweaks:
580
        """
1530.1.4 by Robert Collins
integrate Memory tests into transport interface tests.
581
        raise errors.TransportNotPossible("This transport has not "
1530.1.21 by Robert Collins
Review feedback fixes.
582
                                          "implemented iter_files_recursive "
1530.1.4 by Robert Collins
integrate Memory tests into transport interface tests.
583
                                          "(but must claim to be listable "
584
                                          "to trigger this error).")
1442.1.44 by Robert Collins
Many transport related tweaks:
585
2164.2.15 by Vincent Ladeuil
Http redirections are not followed by default. Do not use hints
586
    def get(self, relpath):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
587
        """Get the file at the given relative path.
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
588
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
589
        This may fail in a number of ways:
590
         - HTTP servers may return content for a directory. (unexpected
591
           content failure)
592
         - FTP servers may indicate NoSuchFile for a directory.
593
         - SFTP servers may give a file handle for a directory that will
594
           fail on read().
595
596
        For correct use of the interface, be sure to catch errors.PathError
597
        when calling it and catch errors.ReadError when reading from the
598
        returned object.
599
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
600
        :param relpath: The relative path to the file
1910.19.2 by Andrew Bennetts
Add a new method ``Transport.get_smart_client()``. This is provided to allow
601
        :rtype: File-like object.
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
602
        """
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
603
        raise NotImplementedError(self.get)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
604
1955.3.3 by John Arbash Meinel
Implement and test 'get_bytes'
605
    def get_bytes(self, relpath):
606
        """Get a raw string of the bytes for a file at the given location.
607
608
        :param relpath: The relative path to the file
609
        """
3882.7.3 by Martin Pool
transport.get should specifically close the file handle
610
        f = self.get(relpath)
611
        try:
612
            return f.read()
613
        finally:
614
            f.close()
1910.19.2 by Andrew Bennetts
Add a new method ``Transport.get_smart_client()``. This is provided to allow
615
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
616
    def get_smart_medium(self):
617
        """Return a smart client medium for this transport if possible.
618
619
        A smart medium doesn't imply the presence of a smart server: it implies
620
        that the smart protocol can be tunnelled via this transport.
621
622
        :raises NoSmartMedium: if no smart server medium is available.
623
        """
624
        raise errors.NoSmartMedium(self)
625
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
626
    def readv(self, relpath, offsets, adjust_for_latency=False,
627
        upper_limit=None):
2745.5.1 by Robert Collins
* New parameter on ``bzrlib.transport.Transport.readv``
628
        """Get parts of the file at the given relative path.
629
630
        :param relpath: The path to read data from.
631
        :param offsets: A list of (offset, size) tuples.
3024.2.1 by Vincent Ladeuil
Fix 165061 by using the correct _max_readv_combine attribute.
632
        :param adjust_for_latency: Adjust the requested offsets to accomodate
2745.5.1 by Robert Collins
* New parameter on ``bzrlib.transport.Transport.readv``
633
            transport latency. This may re-order the offsets, expand them to
634
            grab adjacent data when there is likely a high cost to requesting
635
            data relative to delivering it.
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
636
        :param upper_limit: When adjust_for_latency is True setting upper_limit
637
            allows the caller to tell the transport about the length of the
638
            file, so that requests are not issued for ranges beyond the end of
639
            the file. This matters because some servers and/or transports error
640
            in such a case rather than just satisfying the available ranges.
641
            upper_limit should always be provided when adjust_for_latency is
642
            True, and should be the size of the file in bytes.
2745.5.1 by Robert Collins
* New parameter on ``bzrlib.transport.Transport.readv``
643
        :return: A list or generator of (offset, data) tuples
644
        """
645
        if adjust_for_latency:
2890.1.3 by Robert Collins
Review feedback and discussion with Martin - split out the readv offset adjustment into a new helper and document where the design might/should go next.
646
            # Design note: We may wish to have different algorithms for the
647
            # expansion of the offsets per-transport. E.g. for local disk to
3024.2.1 by Vincent Ladeuil
Fix 165061 by using the correct _max_readv_combine attribute.
648
            # use page-aligned expansion. If that is the case consider the
649
            # following structure:
650
            #  - a test that transport.readv uses self._offset_expander or some
651
            #    similar attribute, to do the expansion
652
            #  - a test for each transport that it has some known-good offset
653
            #    expander
2890.1.3 by Robert Collins
Review feedback and discussion with Martin - split out the readv offset adjustment into a new helper and document where the design might/should go next.
654
            #  - unit tests for each offset expander
655
            #  - a set of tests for the offset expander interface, giving
656
            #    baseline behaviour (which the current transport
657
            #    adjust_for_latency tests could be repurposed to).
658
            offsets = self._sort_expand_and_combine(offsets, upper_limit)
2745.5.1 by Robert Collins
* New parameter on ``bzrlib.transport.Transport.readv``
659
        return self._readv(relpath, offsets)
660
661
    def _readv(self, relpath, offsets):
1594.2.5 by Robert Collins
Readv patch from Johan Rydberg giving knits partial download support.
662
        """Get parts of the file at the given relative path.
663
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
664
        :param relpath: The path to read.
665
        :param offsets: A list of (offset, size) tuples.
1594.2.5 by Robert Collins
Readv patch from Johan Rydberg giving knits partial download support.
666
        :return: A list or generator of (offset, data) tuples
667
        """
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
668
        if not offsets:
1594.2.16 by Robert Collins
Coalesce readv requests on file based transports.
669
            return
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
670
1864.5.7 by John Arbash Meinel
remove disable prefetch support
671
        fp = self.get(relpath)
2001.3.2 by John Arbash Meinel
Force all transports to raise ShortReadvError if they can
672
        return self._seek_and_read(fp, offsets, relpath)
1864.5.11 by John Arbash Meinel
Factor out the workhorse of Transport.readv() into a helper function, and re-use that function in sftp but with a non-prefetch file.
673
2001.3.2 by John Arbash Meinel
Force all transports to raise ShortReadvError if they can
674
    def _seek_and_read(self, fp, offsets, relpath='<unknown>'):
1864.5.11 by John Arbash Meinel
Factor out the workhorse of Transport.readv() into a helper function, and re-use that function in sftp but with a non-prefetch file.
675
        """An implementation of readv that uses fp.seek and fp.read.
676
677
        This uses _coalesce_offsets to issue larger reads and fewer seeks.
678
679
        :param fp: A file-like object that supports seek() and read(size)
680
        :param offsets: A list of offsets to be read from the given file.
681
        :return: yield (pos, data) tuples for each request
682
        """
1864.5.2 by John Arbash Meinel
always read in sorted order, and return in requested order, but only cache what is currently out of order
683
        # We are going to iterate multiple times, we need a list
684
        offsets = list(offsets)
685
        sorted_offsets = sorted(offsets)
686
687
        # turn the list of offsets into a stack
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
688
        offset_stack = iter(offsets)
689
        cur_offset_and_size = offset_stack.next()
1864.5.2 by John Arbash Meinel
always read in sorted order, and return in requested order, but only cache what is currently out of order
690
        coalesced = self._coalesce_offsets(sorted_offsets,
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
691
                               limit=self._max_readv_combine,
692
                               fudge_factor=self._bytes_to_read_before_seek)
1864.5.2 by John Arbash Meinel
always read in sorted order, and return in requested order, but only cache what is currently out of order
693
694
        # Cache the results, but only until they have been fulfilled
695
        data_map = {}
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
696
        for c_offset in coalesced:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
697
            # TODO: jam 20060724 it might be faster to not issue seek if
1864.5.11 by John Arbash Meinel
Factor out the workhorse of Transport.readv() into a helper function, and re-use that function in sftp but with a non-prefetch file.
698
            #       we are already at the right location. This should be
699
            #       benchmarked.
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
700
            fp.seek(c_offset.start)
701
            data = fp.read(c_offset.length)
2001.3.2 by John Arbash Meinel
Force all transports to raise ShortReadvError if they can
702
            if len(data) < c_offset.length:
703
                raise errors.ShortReadvError(relpath, c_offset.start,
2001.3.3 by John Arbash Meinel
review feedback: add the actual count written to ShortReadvError
704
                            c_offset.length, actual=len(data))
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
705
            for suboffset, subsize in c_offset.ranges:
706
                key = (c_offset.start+suboffset, subsize)
707
                data_map[key] = data[suboffset:suboffset+subsize]
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
708
1864.5.8 by John Arbash Meinel
Cleanup and NEWS
709
            # Now that we've read some data, see if we can yield anything back
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
710
            while cur_offset_and_size in data_map:
711
                this_data = data_map.pop(cur_offset_and_size)
3794.2.2 by John Arbash Meinel
Instead of counting the remaining offsets, trap the offset exception
712
                this_offset = cur_offset_and_size[0]
713
                try:
714
                    cur_offset_and_size = offset_stack.next()
715
                except StopIteration:
716
                    # Close the file handle as there will be no more data
717
                    # The handle would normally be cleaned up as this code goes
718
                    # out of scope, but as we are a generator, not all code
719
                    # will re-enter once we have consumed all the expected
720
                    # data. For example:
721
                    #   zip(range(len(requests)), readv(foo, requests))
722
                    # Will stop because the range is done, and not run the
723
                    # cleanup code for the readv().
724
                    fp.close()
725
                    cur_offset_and_size = None
726
                yield this_offset, this_data
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
727
2890.1.3 by Robert Collins
Review feedback and discussion with Martin - split out the readv offset adjustment into a new helper and document where the design might/should go next.
728
    def _sort_expand_and_combine(self, offsets, upper_limit):
729
        """Helper for readv.
730
731
        :param offsets: A readv vector - (offset, length) tuples.
732
        :param upper_limit: The highest byte offset that may be requested.
733
        :return: A readv vector that will read all the regions requested by
734
            offsets, in start-to-end order, with no duplicated regions,
735
            expanded by the transports recommended page size.
736
        """
737
        offsets = sorted(offsets)
738
        # short circuit empty requests
739
        if len(offsets) == 0:
740
            def empty_yielder():
741
                # Quick thunk to stop this function becoming a generator
742
                # itself, rather we return a generator that has nothing to
743
                # yield.
744
                if False:
745
                    yield None
746
            return empty_yielder()
747
        # expand by page size at either end
748
        maximum_expansion = self.recommended_page_size()
749
        new_offsets = []
750
        for offset, length in offsets:
751
            expansion = maximum_expansion - length
752
            if expansion < 0:
753
                # we're asking for more than the minimum read anyway.
754
                expansion = 0
755
            reduction = expansion / 2
756
            new_offset = offset - reduction
757
            new_length = length + expansion
758
            if new_offset < 0:
759
                # don't ask for anything < 0
760
                new_offset = 0
761
            if (upper_limit is not None and
762
                new_offset + new_length > upper_limit):
763
                new_length = upper_limit - new_offset
764
            new_offsets.append((new_offset, new_length))
765
        # combine the expanded offsets
766
        offsets = []
767
        current_offset, current_length = new_offsets[0]
768
        current_finish = current_length + current_offset
769
        for offset, length in new_offsets[1:]:
770
            finish = offset + length
3805.4.2 by John Arbash Meinel
Revert the changes to _sort_expand_and_combine
771
            if offset > current_finish:
772
                # there is a gap, output the current accumulator and start
773
                # a new one for the region we're examining.
2890.1.3 by Robert Collins
Review feedback and discussion with Martin - split out the readv offset adjustment into a new helper and document where the design might/should go next.
774
                offsets.append((current_offset, current_length))
775
                current_offset = offset
776
                current_length = length
777
                current_finish = finish
778
                continue
779
            if finish > current_finish:
780
                # extend the current accumulator to the end of the region
781
                # we're examining.
782
                current_finish = finish
783
                current_length = finish - current_offset
784
        offsets.append((current_offset, current_length))
785
        return offsets
786
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
787
    @staticmethod
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
788
    def _coalesce_offsets(offsets, limit=0, fudge_factor=0, max_size=0):
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
789
        """Yield coalesced offsets.
790
791
        With a long list of neighboring requests, combine them
792
        into a single large request, while retaining the original
793
        offsets.
794
        Turns  [(15, 10), (25, 10)] => [(15, 20, [(0, 10), (10, 10)])]
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
795
        Note that overlapping requests are not permitted. (So [(15, 10), (20,
796
        10)] will raise a ValueError.) This is because the data we access never
797
        overlaps, and it allows callers to trust that we only need any byte of
798
        data for 1 request (so nothing needs to be buffered to fulfill a second
799
        request.)
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
800
801
        :param offsets: A list of (start, length) pairs
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
802
        :param limit: Only combine a maximum of this many pairs Some transports
803
                penalize multiple reads more than others, and sometimes it is
804
                better to return early.
805
                0 means no limit
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
806
        :param fudge_factor: All transports have some level of 'it is
3120.2.1 by John Arbash Meinel
Change the sftp_readv loop to buffer even less.
807
                better to read some more data and throw it away rather
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
808
                than seek', so collapse if we are 'close enough'
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
809
        :param max_size: Create coalesced offsets no bigger than this size.
810
                When a single offset is bigger than 'max_size', it will keep
811
                its size and be alone in the coalesced offset.
812
                0 means no maximum size.
3120.2.1 by John Arbash Meinel
Change the sftp_readv loop to buffer even less.
813
        :return: return a list of _CoalescedOffset objects, which have members
814
            for where to start, how much to read, and how to split those chunks
815
            back up
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
816
        """
817
        last_end = None
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
818
        cur = _CoalescedOffset(None, None, [])
3120.2.1 by John Arbash Meinel
Change the sftp_readv loop to buffer even less.
819
        coalesced_offsets = []
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
820
3876.1.1 by John Arbash Meinel
Fix bug #303538 by capping the max per-hunk read size at 100MB.
821
        if max_size <= 0:
822
            # 'unlimited', but we actually take this to mean 100MB buffer limit
823
            max_size = 100*1024*1024
824
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
825
        for start, size in offsets:
826
            end = start + size
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
827
            if (last_end is not None
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
828
                and start <= last_end + fudge_factor
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
829
                and start >= cur.start
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
830
                and (limit <= 0 or len(cur.ranges) < limit)
831
                and (max_size <= 0 or end - cur.start <= max_size)):
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
832
                if start < last_end:
3686.1.9 by John Arbash Meinel
Overlapping ranges are not allowed anymore.
833
                    raise ValueError('Overlapping range not allowed:'
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
834
                        ' last range ended at %s, new one starts at %s'
835
                        % (last_end, start))
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
836
                cur.length = end - cur.start
837
                cur.ranges.append((start-cur.start, size))
1594.2.16 by Robert Collins
Coalesce readv requests on file based transports.
838
            else:
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
839
                if cur.start is not None:
3120.2.1 by John Arbash Meinel
Change the sftp_readv loop to buffer even less.
840
                    coalesced_offsets.append(cur)
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
841
                cur = _CoalescedOffset(start, size, [(0, size)])
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
842
            last_end = end
843
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
844
        if cur.start is not None:
3120.2.1 by John Arbash Meinel
Change the sftp_readv loop to buffer even less.
845
            coalesced_offsets.append(cur)
846
        return coalesced_offsets
1594.2.5 by Robert Collins
Readv patch from Johan Rydberg giving knits partial download support.
847
907.1.50 by John Arbash Meinel
Removed encode/decode from Transport.put/get, added more exceptions that can be thrown.
848
    def get_multi(self, relpaths, pb=None):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
849
        """Get a list of file-like objects, one for each entry in relpaths.
850
851
        :param relpaths: A list of relative paths.
4463.1.1 by Martin Pool
Update docstrings for recent progress changes
852
        :param pb:  An optional ProgressTask for indicating percent done.
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
853
        :return: A list or generator of file-like objects
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
854
        """
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
855
        # TODO: Consider having this actually buffer the requests,
856
        # in the default mode, it probably won't give worse performance,
857
        # and all children wouldn't have to implement buffering
907.1.16 by John Arbash Meinel
Fixing a few cut&paste typos.
858
        total = self._get_total(relpaths)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
859
        count = 0
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
860
        for relpath in relpaths:
907.1.16 by John Arbash Meinel
Fixing a few cut&paste typos.
861
            self._update_pb(pb, 'get', count, total)
907.1.50 by John Arbash Meinel
Removed encode/decode from Transport.put/get, added more exceptions that can be thrown.
862
            yield self.get(relpath)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
863
            count += 1
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
864
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
865
    def put_bytes(self, relpath, bytes, mode=None):
866
        """Atomically put the supplied bytes into the given location.
867
868
        :param relpath: The location to put the contents, relative to the
869
            transport base.
870
        :param bytes: A bytestring of data.
871
        :param mode: Create the file with the given mode.
872
        :return: None
873
        """
2414.1.3 by Andrew Bennetts
Fix test failures under 'python2.4 -O' ('python2.5 -O' was already passing).
874
        if not isinstance(bytes, str):
875
            raise AssertionError(
876
                'bytes must be a plain string, not %s' % type(bytes))
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
877
        return self.put_file(relpath, StringIO(bytes), mode=mode)
878
879
    def put_bytes_non_atomic(self, relpath, bytes, mode=None,
1946.2.12 by John Arbash Meinel
Add ability to pass a directory mode to non_atomic_put
880
                             create_parent_dir=False,
881
                             dir_mode=None):
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
882
        """Copy the string into the target location.
883
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
884
        This function is not strictly safe to use. See
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
885
        Transport.put_bytes_non_atomic for more information.
886
887
        :param relpath: The remote location to put the contents.
888
        :param bytes:   A string object containing the raw bytes to write into
889
                        the target file.
890
        :param mode:    Possible access permissions for new file.
891
                        None means do not set remote permissions.
892
        :param create_parent_dir: If we cannot create the target file because
893
                        the parent directory does not exist, go ahead and
894
                        create it, and then try again.
1946.2.12 by John Arbash Meinel
Add ability to pass a directory mode to non_atomic_put
895
        :param dir_mode: Possible access permissions for new directories.
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
896
        """
2414.1.3 by Andrew Bennetts
Fix test failures under 'python2.4 -O' ('python2.5 -O' was already passing).
897
        if not isinstance(bytes, str):
898
            raise AssertionError(
899
                'bytes must be a plain string, not %s' % type(bytes))
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
900
        self.put_file_non_atomic(relpath, StringIO(bytes), mode=mode,
1946.2.12 by John Arbash Meinel
Add ability to pass a directory mode to non_atomic_put
901
                                 create_parent_dir=create_parent_dir,
902
                                 dir_mode=dir_mode)
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
903
1955.3.6 by John Arbash Meinel
Lots of deprecation warnings, but no errors
904
    def put_file(self, relpath, f, mode=None):
905
        """Copy the file-like object into the location.
906
907
        :param relpath: Location to put the contents, relative to base.
908
        :param f:       File-like object.
909
        :param mode: The mode for the newly created file,
910
                     None means just use the default.
2745.5.2 by Robert Collins
* ``bzrlib.transport.Transport.put_file`` now returns the number of bytes
911
        :return: The length of the file that was written.
1955.3.6 by John Arbash Meinel
Lots of deprecation warnings, but no errors
912
        """
913
        # We would like to mark this as NotImplemented, but most likely
914
        # transports have defined it in terms of the old api.
915
        symbol_versioning.warn('Transport %s should implement put_file,'
916
                               ' rather than implementing put() as of'
917
                               ' version 0.11.'
918
                               % (self.__class__.__name__,),
919
                               DeprecationWarning)
920
        return self.put(relpath, f, mode=mode)
921
        #raise NotImplementedError(self.put_file)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
922
1955.3.27 by John Arbash Meinel
rename non_atomic_put_* to put_*non_atomic, and re-order the functions
923
    def put_file_non_atomic(self, relpath, f, mode=None,
1946.2.12 by John Arbash Meinel
Add ability to pass a directory mode to non_atomic_put
924
                            create_parent_dir=False,
925
                            dir_mode=None):
1946.1.1 by John Arbash Meinel
Stub out the test and basic implementation for 'non_atomic_put'
926
        """Copy the file-like object into the target location.
927
928
        This function is not strictly safe to use. It is only meant to
929
        be used when you already know that the target does not exist.
930
        It is not safe, because it will open and truncate the remote
931
        file. So there may be a time when the file has invalid contents.
932
933
        :param relpath: The remote location to put the contents.
934
        :param f:       File-like object.
935
        :param mode:    Possible access permissions for new file.
936
                        None means do not set remote permissions.
1946.1.8 by John Arbash Meinel
Update non_atomic_put to have a create_parent_dir flag
937
        :param create_parent_dir: If we cannot create the target file because
938
                        the parent directory does not exist, go ahead and
939
                        create it, and then try again.
1946.2.12 by John Arbash Meinel
Add ability to pass a directory mode to non_atomic_put
940
        :param dir_mode: Possible access permissions for new directories.
1946.1.1 by John Arbash Meinel
Stub out the test and basic implementation for 'non_atomic_put'
941
        """
942
        # Default implementation just does an atomic put.
1946.1.8 by John Arbash Meinel
Update non_atomic_put to have a create_parent_dir flag
943
        try:
1955.3.19 by John Arbash Meinel
rename non_atomic_put => non_atomic_put_file
944
            return self.put_file(relpath, f, mode=mode)
1946.1.8 by John Arbash Meinel
Update non_atomic_put to have a create_parent_dir flag
945
        except errors.NoSuchFile:
946
            if not create_parent_dir:
947
                raise
948
            parent_dir = osutils.dirname(relpath)
949
            if parent_dir:
1946.2.12 by John Arbash Meinel
Add ability to pass a directory mode to non_atomic_put
950
                self.mkdir(parent_dir, mode=dir_mode)
1955.3.19 by John Arbash Meinel
rename non_atomic_put => non_atomic_put_file
951
                return self.put_file(relpath, f, mode=mode)
1946.1.1 by John Arbash Meinel
Stub out the test and basic implementation for 'non_atomic_put'
952
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
953
    def mkdir(self, relpath, mode=None):
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
954
        """Create a directory at the given path."""
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
955
        raise NotImplementedError(self.mkdir)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
956
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
957
    def mkdir_multi(self, relpaths, mode=None, pb=None):
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
958
        """Create a group of directories"""
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
959
        def mkdir(path):
960
            self.mkdir(path, mode=mode)
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
961
        return len(self._iterate_over(relpaths, mkdir, pb, 'mkdir', expand=False))
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
962
2671.3.9 by Robert Collins
Review feedback and fix VFat emulated transports to not claim to have unix permissions.
963
    def open_write_stream(self, relpath, mode=None):
964
        """Open a writable file stream at relpath.
2671.3.2 by Robert Collins
Start open_file_stream logic.
965
2671.3.9 by Robert Collins
Review feedback and fix VFat emulated transports to not claim to have unix permissions.
966
        A file stream is a file like object with a write() method that accepts
967
        bytes to write.. Buffering may occur internally until the stream is
968
        closed with stream.close().  Calls to readv or the get_* methods will
969
        be synchronised with any internal buffering that may be present.
2671.3.2 by Robert Collins
Start open_file_stream logic.
970
971
        :param relpath: The relative path to the file.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
972
        :param mode: The mode for the newly created file,
2671.3.3 by Robert Collins
Add mode parameter to Transport.open_file_stream.
973
                     None means just use the default
2671.3.6 by Robert Collins
Review feedback.
974
        :return: A FileStream. FileStream objects have two methods, write() and
975
            close(). There is no guarantee that data is committed to the file
976
            if close() has not been called (even if get() is called on the same
977
            path).
2671.3.2 by Robert Collins
Start open_file_stream logic.
978
        """
2671.3.9 by Robert Collins
Review feedback and fix VFat emulated transports to not claim to have unix permissions.
979
        raise NotImplementedError(self.open_write_stream)
2671.3.2 by Robert Collins
Start open_file_stream logic.
980
1955.3.15 by John Arbash Meinel
Deprecate 'Transport.append' in favor of Transport.append_file or Transport.append_bytes
981
    def append_file(self, relpath, f, mode=None):
1910.7.18 by Andrew Bennetts
Merge from bzr.dev
982
        """Append bytes from a file-like object to a file at relpath.
983
984
        The file is created if it does not already exist.
985
986
        :param f: a file-like object of the bytes to append.
987
        :param mode: Unix mode for newly created files.  This is not used for
988
            existing files.
989
990
        :returns: the length of relpath before the content was written to it.
1955.3.15 by John Arbash Meinel
Deprecate 'Transport.append' in favor of Transport.append_file or Transport.append_bytes
991
        """
992
        symbol_versioning.warn('Transport %s should implement append_file,'
993
                               ' rather than implementing append() as of'
994
                               ' version 0.11.'
995
                               % (self.__class__.__name__,),
996
                               DeprecationWarning)
997
        return self.append(relpath, f, mode=mode)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
998
1955.3.2 by John Arbash Meinel
Implement and test 'Transport.append_bytes', cleanup the tests of plain append
999
    def append_bytes(self, relpath, bytes, mode=None):
1910.7.18 by Andrew Bennetts
Merge from bzr.dev
1000
        """Append bytes to a file at relpath.
1001
1002
        The file is created if it does not already exist.
1003
1004
        :type f: str
1005
        :param f: a string of the bytes to append.
1006
        :param mode: Unix mode for newly created files.  This is not used for
1007
            existing files.
1008
1009
        :returns: the length of relpath before the content was written to it.
1955.3.2 by John Arbash Meinel
Implement and test 'Transport.append_bytes', cleanup the tests of plain append
1010
        """
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1011
        if not isinstance(bytes, str):
1012
            raise TypeError(
1013
                'bytes must be a plain string, not %s' % type(bytes))
1955.3.15 by John Arbash Meinel
Deprecate 'Transport.append' in favor of Transport.append_file or Transport.append_bytes
1014
        return self.append_file(relpath, StringIO(bytes), mode=mode)
1955.3.2 by John Arbash Meinel
Implement and test 'Transport.append_bytes', cleanup the tests of plain append
1015
1185.11.19 by John Arbash Meinel
Testing put and append, also testing agaist file-like objects as well as strings.
1016
    def append_multi(self, files, pb=None):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1017
        """Append the text in each file-like or string object to
1018
        the supplied location.
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1019
1020
        :param files: A set of (path, f) entries
4463.1.1 by Martin Pool
Update docstrings for recent progress changes
1021
        :param pb:  An optional ProgressTask for indicating percent done.
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1022
        """
1955.3.15 by John Arbash Meinel
Deprecate 'Transport.append' in favor of Transport.append_file or Transport.append_bytes
1023
        return self._iterate_over(files, self.append_file, pb, 'append', expand=True)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1024
1025
    def copy(self, rel_from, rel_to):
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1026
        """Copy the item at rel_from to the location at rel_to.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1027
1028
        Override this for efficiency if a specific transport can do it
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1029
        faster than this default implementation.
1030
        """
1955.3.11 by John Arbash Meinel
Clean up the rest of the api calls to deprecated functions in the test suite, and make sure Transport._pump is only accepting files, not strings
1031
        self.put_file(rel_to, self.get(rel_from))
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1032
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1033
    def copy_multi(self, relpaths, pb=None):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1034
        """Copy a bunch of entries.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1035
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1036
        :param relpaths: A list of tuples of the form [(from, to), (from, to),...]
1037
        """
1038
        # This is the non-pipelined implementation, so that
1039
        # implementors don't have to implement everything.
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
1040
        return self._iterate_over(relpaths, self.copy, pb, 'copy', expand=True)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1041
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
1042
    def copy_to(self, relpaths, other, mode=None, pb=None):
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1043
        """Copy a set of entries from self into another Transport.
1044
1045
        :param relpaths: A list/generator of entries to be copied.
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
1046
        :param mode: This is the target mode for the newly created files
1185.16.156 by John Arbash Meinel
Adding a note about changing copy_to's interface
1047
        TODO: This interface needs to be updated so that the target location
1048
              can be different from the source location.
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1049
        """
1050
        # The dummy implementation just does a simple get + put
1051
        def copy_entry(path):
1955.3.11 by John Arbash Meinel
Clean up the rest of the api calls to deprecated functions in the test suite, and make sure Transport._pump is only accepting files, not strings
1052
            other.put_file(path, self.get(path), mode=mode)
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1053
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
1054
        return len(self._iterate_over(relpaths, copy_entry, pb, 'copy_to', expand=False))
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1055
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1056
    def copy_tree(self, from_relpath, to_relpath):
1057
        """Copy a subtree from one relpath to another.
1058
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1059
        If a faster implementation is available, specific transports should
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1060
        implement it.
1061
        """
1062
        source = self.clone(from_relpath)
1063
        target = self.clone(to_relpath)
4634.148.5 by Martin Pool
Additional fix for setting permissions across ftp (thanks Parth)
1064
1065
        # create target directory with the same rwx bits as source.
1066
        # use mask to ensure that bits other than rwx are ignored.
4634.148.1 by Martin Pool
Backport fix for permissions of backup.bzr
1067
        stat = self.stat(from_relpath)
4634.148.5 by Martin Pool
Additional fix for setting permissions across ftp (thanks Parth)
1068
        target.mkdir('.', stat.st_mode & 0777)
1551.21.5 by Aaron Bentley
Implement copy_tree on copy_tree_to_transport
1069
        source.copy_tree_to_transport(target)
1070
1071
    def copy_tree_to_transport(self, to_transport):
1072
        """Copy a subtree from one transport to another.
1073
1074
        self.base is used as the source tree root, and to_transport.base
1075
        is used as the target.  to_transport.base must exist (and be a
1076
        directory).
1077
        """
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1078
        files = []
1079
        directories = ['.']
1080
        while directories:
1081
            dir = directories.pop()
1082
            if dir != '.':
1551.21.5 by Aaron Bentley
Implement copy_tree on copy_tree_to_transport
1083
                to_transport.mkdir(dir)
1084
            for path in self.list_dir(dir):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1085
                path = dir + '/' + path
1551.21.5 by Aaron Bentley
Implement copy_tree on copy_tree_to_transport
1086
                stat = self.stat(path)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1087
                if S_ISDIR(stat.st_mode):
1088
                    directories.append(path)
1089
                else:
1090
                    files.append(path)
1551.21.5 by Aaron Bentley
Implement copy_tree on copy_tree_to_transport
1091
        self.copy_to(files, to_transport)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1092
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
1093
    def rename(self, rel_from, rel_to):
1094
        """Rename a file or directory.
1095
1096
        This *must* fail if the destination is a nonempty directory - it must
1097
        not automatically remove it.  It should raise DirectoryNotEmpty, or
1098
        some other PathError if the case can't be specifically detected.
1099
1100
        If the destination is an empty directory or a file this function may
1101
        either fail or succeed, depending on the underlying transport.  It
1102
        should not attempt to remove the destination if overwriting is not the
1103
        native transport behaviour.  If at all possible the transport should
1104
        ensure that the rename either completes or not, without leaving the
1105
        destination deleted and the new file not moved in place.
1106
1107
        This is intended mainly for use in implementing LockDir.
1108
        """
1109
        # transports may need to override this
1553.5.17 by Martin Pool
Transport.rename should be unimplemented in base class
1110
        raise NotImplementedError(self.rename)
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
1111
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1112
    def move(self, rel_from, rel_to):
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1113
        """Move the item at rel_from to the location at rel_to.
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
1114
1115
        The destination is deleted if possible, even if it's a non-empty
1116
        directory tree.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1117
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1118
        If a transport can directly implement this it is suggested that
1119
        it do so for efficiency.
1120
        """
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1121
        if S_ISDIR(self.stat(rel_from).st_mode):
1122
            self.copy_tree(rel_from, rel_to)
1123
            self.delete_tree(rel_from)
1124
        else:
1125
            self.copy(rel_from, rel_to)
1126
            self.delete(rel_from)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1127
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1128
    def move_multi(self, relpaths, pb=None):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1129
        """Move a bunch of entries.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1130
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1131
        :param relpaths: A list of tuples of the form [(from1, to1), (from2, to2),...]
1132
        """
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
1133
        return self._iterate_over(relpaths, self.move, pb, 'move', expand=True)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1134
1135
    def move_multi_to(self, relpaths, rel_to):
1136
        """Move a bunch of entries to a single location.
1137
        This differs from move_multi in that you give a list of from, and
1138
        a single destination, rather than multiple destinations.
1139
1140
        :param relpaths: A list of relative paths [from1, from2, from3, ...]
1141
        :param rel_to: A directory where each entry should be placed.
1142
        """
1143
        # This is not implemented, because you need to do special tricks to
1144
        # extract the basename, and add it to rel_to
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
1145
        raise NotImplementedError(self.move_multi_to)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1146
1147
    def delete(self, relpath):
1148
        """Delete the item at relpath"""
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
1149
        raise NotImplementedError(self.delete)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1150
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
1151
    def delete_multi(self, relpaths, pb=None):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1152
        """Queue up a bunch of deletes to be done.
1153
        """
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
1154
        return self._iterate_over(relpaths, self.delete, pb, 'delete', expand=False)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1155
1534.4.15 by Robert Collins
Remove shutil dependency in upgrade - create a delete_tree method for transports.
1156
    def delete_tree(self, relpath):
1157
        """Delete an entire tree. This may require a listable transport."""
1158
        subtree = self.clone(relpath)
1159
        files = []
1160
        directories = ['.']
1161
        pending_rmdirs = []
1162
        while directories:
1163
            dir = directories.pop()
1164
            if dir != '.':
1165
                pending_rmdirs.append(dir)
1166
            for path in subtree.list_dir(dir):
1167
                path = dir + '/' + path
1168
                stat = subtree.stat(path)
1169
                if S_ISDIR(stat.st_mode):
1170
                    directories.append(path)
1171
                else:
1172
                    files.append(path)
1173
        subtree.delete_multi(files)
1174
        pending_rmdirs.reverse()
1175
        for dir in pending_rmdirs:
1176
            subtree.rmdir(dir)
1177
        self.rmdir(relpath)
1178
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
1179
    def __repr__(self):
1180
        return "<%s.%s url=%s>" % (self.__module__, self.__class__.__name__, self.base)
1181
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1182
    def stat(self, relpath):
1183
        """Return the stat information for a file.
1184
        WARNING: This may not be implementable for all protocols, so use
1185
        sparingly.
1442.1.44 by Robert Collins
Many transport related tweaks:
1186
        NOTE: This returns an object with fields such as 'st_size'. It MAY
1187
        or MAY NOT return the literal result of an os.stat() call, so all
1188
        access should be via named fields.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1189
        ALSO NOTE: Stats of directories may not be supported on some
1442.1.44 by Robert Collins
Many transport related tweaks:
1190
        transports.
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1191
        """
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
1192
        raise NotImplementedError(self.stat)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1193
1534.4.15 by Robert Collins
Remove shutil dependency in upgrade - create a delete_tree method for transports.
1194
    def rmdir(self, relpath):
1195
        """Remove a directory at the given path."""
1196
        raise NotImplementedError
1197
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1198
    def stat_multi(self, relpaths, pb=None):
1199
        """Stat multiple files and return the information.
1200
        """
1201
        #TODO:  Is it worth making this a generator instead of a
1202
        #       returning a list?
1203
        stats = []
1204
        def gather(path):
1205
            stats.append(self.stat(path))
1206
907.1.14 by John Arbash Meinel
Handling some transport functions which take only a single argument.
1207
        count = self._iterate_over(relpaths, gather, pb, 'stat', expand=False)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
1208
        return stats
1209
5056.1.4 by Neil Santos
Changed stat() in SFTPTransport and LocalTransport back to calling plain stat(), instead of lstat().
1210
    def readlink(self, relpath):
1211
        """Return a string representing the path to which the symbolic link points."""
1212
        raise errors.TransportNotPossible("Dereferencing symlinks is not supported on %s" % self)
1213
5056.1.9 by Neil Santos
Renamed link() methods to hardlink(), as per mbp's suggestion
1214
    def hardlink(self, source, link_name):
5056.1.4 by Neil Santos
Changed stat() in SFTPTransport and LocalTransport back to calling plain stat(), instead of lstat().
1215
        """Create a hardlink pointing to source named link_name."""
5056.1.1 by Neil Santos
Added default link() and symlink() methods to Transport.
1216
        raise errors.TransportNotPossible("Hard links are not supported on %s" % self)
1217
1218
    def symlink(self, source, link_name):
5056.1.4 by Neil Santos
Changed stat() in SFTPTransport and LocalTransport back to calling plain stat(), instead of lstat().
1219
        """Create a symlink pointing to source named link_name."""
5056.1.1 by Neil Santos
Added default link() and symlink() methods to Transport.
1220
        raise errors.TransportNotPossible("Symlinks are not supported on %s" % self)
1221
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
1222
    def listable(self):
1223
        """Return True if this store supports listing."""
1540.3.1 by Martin Pool
First-cut implementation of pycurl. Substantially faster than using urllib.
1224
        raise NotImplementedError(self.listable)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1225
1226
    def list_dir(self, relpath):
1227
        """Return a list of all files at the given location.
1228
        WARNING: many transports do not support this, so trying avoid using
1229
        it if at all possible.
1230
        """
1910.16.1 by Andrew Bennetts
lock_read and lock_write may raise TransportNotPossible.
1231
        raise errors.TransportNotPossible("Transport %r has not "
1530.1.21 by Robert Collins
Review feedback fixes.
1232
                                          "implemented list_dir "
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1233
                                          "(but must claim to be listable "
1910.16.1 by Andrew Bennetts
lock_read and lock_write may raise TransportNotPossible.
1234
                                          "to trigger this error)."
1235
                                          % (self))
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
1236
907.1.24 by John Arbash Meinel
Remote functionality work.
1237
    def lock_read(self, relpath):
1238
        """Lock the given file for shared (read) access.
1910.16.1 by Andrew Bennetts
lock_read and lock_write may raise TransportNotPossible.
1239
1240
        WARNING: many transports do not support this, so trying avoid using it.
1241
        These methods may be removed in the future.
1242
1243
        Transports may raise TransportNotPossible if OS-level locks cannot be
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1244
        taken over this transport.
907.1.24 by John Arbash Meinel
Remote functionality work.
1245
1246
        :return: A lock object, which should contain an unlock() function.
1247
        """
1910.16.1 by Andrew Bennetts
lock_read and lock_write may raise TransportNotPossible.
1248
        raise errors.TransportNotPossible("transport locks not supported on %s" % self)
907.1.24 by John Arbash Meinel
Remote functionality work.
1249
1250
    def lock_write(self, relpath):
1251
        """Lock the given file for exclusive (write) access.
1910.16.1 by Andrew Bennetts
lock_read and lock_write may raise TransportNotPossible.
1252
1253
        WARNING: many transports do not support this, so trying avoid using it.
1254
        These methods may be removed in the future.
1255
1256
        Transports may raise TransportNotPossible if OS-level locks cannot be
1257
        taken over this transport.
907.1.24 by John Arbash Meinel
Remote functionality work.
1258
1259
        :return: A lock object, which should contain an unlock() function.
1260
        """
1910.16.1 by Andrew Bennetts
lock_read and lock_write may raise TransportNotPossible.
1261
        raise errors.TransportNotPossible("transport locks not supported on %s" % self)
907.1.24 by John Arbash Meinel
Remote functionality work.
1262
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1263
    def is_readonly(self):
1264
        """Return true if this connection cannot be written to."""
1265
        return False
1266
1608.2.7 by Martin Pool
Rename supports_unix_modebits to _can_roundtrip_unix_modebits for clarity
1267
    def _can_roundtrip_unix_modebits(self):
1608.2.5 by Martin Pool
Add Transport.supports_unix_modebits, so tests can
1268
        """Return true if this transport can store and retrieve unix modebits.
1269
1270
        (For example, 0700 to make a directory owner-private.)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1271
1272
        Note: most callers will not want to switch on this, but should rather
1608.2.5 by Martin Pool
Add Transport.supports_unix_modebits, so tests can
1273
        just try and set permissions and let them be either stored or not.
1274
        This is intended mainly for the use of the test suite.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1275
1276
        Warning: this is not guaranteed to be accurate as sometimes we can't
1608.2.5 by Martin Pool
Add Transport.supports_unix_modebits, so tests can
1277
        be sure: for example with vfat mounted on unix, or a windows sftp
1278
        server."""
1279
        # TODO: Perhaps return a e.g. TransportCharacteristics that can answer
1280
        # several questions about the transport.
1281
        return False
1282
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1283
    def _reuse_for(self, other_base):
2485.8.43 by Vincent Ladeuil
Cleaning.
1284
        # This is really needed for ConnectedTransport only, but it's easier to
1285
        # have Transport refuses to be reused than testing that the reuse
1286
        # should be asked to ConnectedTransport only.
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1287
        return None
907.1.24 by John Arbash Meinel
Remote functionality work.
1288
5247.2.12 by Vincent Ladeuil
Ensure that all transports close their underlying connection.
1289
    def disconnect(self):
1290
        # This is really needed for ConnectedTransport only, but it's easier to
1291
        # have Transport do nothing than testing that the disconnect should be
1292
        # asked to ConnectedTransport only.
1293
        pass
1294
3878.4.5 by Vincent Ladeuil
Don't use the exception as a parameter for _redirected_to.
1295
    def _redirected_to(self, source, target):
3878.4.1 by Vincent Ladeuil
Fix bug #245964 by preserving decorators during redirections (when
1296
        """Returns a transport suitable to re-issue a redirected request.
1297
3878.4.5 by Vincent Ladeuil
Don't use the exception as a parameter for _redirected_to.
1298
        :param source: The source url as returned by the server.
1299
        :param target: The target url as returned by the server.
3878.4.1 by Vincent Ladeuil
Fix bug #245964 by preserving decorators during redirections (when
1300
1301
        The redirection can be handled only if the relpath involved is not
1302
        renamed by the redirection.
1303
1304
        :returns: A transport or None.
1305
        """
1306
        # This returns None by default, meaning the transport can't handle the
1307
        # redirection.
1308
        return None
1309
1310
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
1311
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1312
class _SharedConnection(object):
1313
    """A connection shared between several transports."""
1314
3104.4.1 by Andrew Bennetts
Fix paths sent by bzr+http client to correctly adjust for shared medium.
1315
    def __init__(self, connection=None, credentials=None, base=None):
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1316
        """Constructor.
1317
1318
        :param connection: An opaque object specific to each transport.
1319
1320
        :param credentials: An opaque object containing the credentials used to
1321
            create the connection.
1322
        """
1323
        self.connection = connection
1324
        self.credentials = credentials
3104.4.1 by Andrew Bennetts
Fix paths sent by bzr+http client to correctly adjust for shared medium.
1325
        self.base = base
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1326
1327
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1328
class ConnectedTransport(Transport):
1329
    """A transport connected to a remote server.
1330
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1331
    This class provide the basis to implement transports that need to connect
1332
    to a remote server.
1333
1334
    Host and credentials are available as private attributes, cloning preserves
1335
    them and share the underlying, protocol specific, connection.
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1336
    """
1337
2485.8.59 by Vincent Ladeuil
Update from review comments.
1338
    def __init__(self, base, _from_transport=None):
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1339
        """Constructor.
1340
2485.8.62 by Vincent Ladeuil
From review comments, fix typos and deprecate some functions.
1341
        The caller should ensure that _from_transport points at the same host
1342
        as the new base.
1343
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1344
        :param base: transport root URL
1345
2485.8.59 by Vincent Ladeuil
Update from review comments.
1346
        :param _from_transport: optional transport to build from. The built
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1347
            transport will share the connection with this transport.
1348
        """
2485.8.59 by Vincent Ladeuil
Update from review comments.
1349
        if not base.endswith('/'):
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1350
            base += '/'
1351
        (self._scheme,
1352
         self._user, self._password,
1353
         self._host, self._port,
2485.8.47 by Vincent Ladeuil
Remove _initial_split_url hack.
1354
         self._path) = self._split_url(base)
2485.8.59 by Vincent Ladeuil
Update from review comments.
1355
        if _from_transport is not None:
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1356
            # Copy the password as it does not appear in base and will be lost
2485.8.59 by Vincent Ladeuil
Update from review comments.
1357
            # otherwise. It can appear in the _split_url above if the user
1358
            # provided it on the command line. Otherwise, daughter classes will
1359
            # prompt the user for one when appropriate.
1360
            self._password = _from_transport._password
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1361
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1362
        base = self._unsplit_url(self._scheme,
1363
                                 self._user, self._password,
1364
                                 self._host, self._port,
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1365
                                 self._path)
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1366
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1367
        super(ConnectedTransport, self).__init__(base)
2485.8.59 by Vincent Ladeuil
Update from review comments.
1368
        if _from_transport is None:
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1369
            self._shared_connection = _SharedConnection()
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1370
        else:
2485.8.59 by Vincent Ladeuil
Update from review comments.
1371
            self._shared_connection = _from_transport._shared_connection
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1372
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1373
    def clone(self, offset=None):
1374
        """Return a new transport with root at self.base + offset
1375
1376
        We leave the daughter classes take advantage of the hint
1377
        that it's a cloning not a raw creation.
1378
        """
1379
        if offset is None:
2485.8.59 by Vincent Ladeuil
Update from review comments.
1380
            return self.__class__(self.base, _from_transport=self)
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1381
        else:
2485.8.59 by Vincent Ladeuil
Update from review comments.
1382
            return self.__class__(self.abspath(offset), _from_transport=self)
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1383
2485.8.47 by Vincent Ladeuil
Remove _initial_split_url hack.
1384
    @staticmethod
1385
    def _split_url(url):
3873.3.1 by Martin Pool
Move Transport._split_url to urlutils, and ad a simple test
1386
        return urlutils.parse_url(url)
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1387
2485.8.47 by Vincent Ladeuil
Remove _initial_split_url hack.
1388
    @staticmethod
1389
    def _unsplit_url(scheme, user, password, host, port, path):
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1390
        """
1391
        Build the full URL for the given already URL encoded path.
1392
1393
        user, password, host and path will be quoted if they contain reserved
1394
        chars.
1395
1396
        :param scheme: protocol
1397
1398
        :param user: login
1399
1400
        :param password: associated password
1401
1402
        :param host: the server address
1403
1404
        :param port: the associated port
1405
1406
        :param path: the absolute path on the server
1407
1408
        :return: The corresponding URL.
1409
        """
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1410
        netloc = urllib.quote(host)
1411
        if user is not None:
1412
            # Note that we don't put the password back even if we
1413
            # have one so that it doesn't get accidentally
1414
            # exposed.
1415
            netloc = '%s@%s' % (urllib.quote(user), netloc)
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1416
        if port is not None:
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1417
            netloc = '%s:%d' % (netloc, port)
4505.3.1 by Andy Kilner
Fix up another tilde bug.
1418
        path = urlutils.escape(path)
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1419
        return urlparse.urlunparse((scheme, netloc, path, None, None, None))
1420
1421
    def relpath(self, abspath):
2485.8.29 by Vincent Ladeuil
Cometic changes (and a typo).
1422
        """Return the local path portion from a given absolute path"""
1423
        scheme, user, password, host, port, path = self._split_url(abspath)
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1424
        error = []
1425
        if (scheme != self._scheme):
1426
            error.append('scheme mismatch')
1427
        if (user != self._user):
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1428
            error.append('user name mismatch')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1429
        if (host != self._host):
1430
            error.append('host mismatch')
1431
        if (port != self._port):
1432
            error.append('port mismatch')
1433
        if not (path == self._path[:-1] or path.startswith(self._path)):
1434
            error.append('path mismatch')
1435
        if error:
1436
            extra = ', '.join(error)
1437
            raise errors.PathNotChild(abspath, self.base, extra=extra)
1438
        pl = len(self._path)
1439
        return path[pl:].strip('/')
1440
1441
    def abspath(self, relpath):
1442
        """Return the full url to the given relative path.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1443
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1444
        :param relpath: the relative path urlencoded
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1445
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1446
        :returns: the Unicode version of the absolute path for relpath.
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1447
        """
2485.8.25 by Vincent Ladeuil
Separate abspath from _remote_path, the intents are different.
1448
        relative = urlutils.unescape(relpath).encode('utf-8')
1449
        path = self._combine_paths(self._path, relative)
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1450
        return self._unsplit_url(self._scheme, self._user, self._password,
1451
                                 self._host, self._port,
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1452
                                 path)
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1453
1454
    def _remote_path(self, relpath):
1455
        """Return the absolute path part of the url to the given relative path.
2485.8.28 by Vincent Ladeuil
Further simplifications and doc updates.
1456
1457
        This is the path that the remote server expect to receive in the
1458
        requests, daughter classes should redefine this method if needed and
1459
        use the result to build their requests.
1460
1461
        :param relpath: the path relative to the transport base urlencoded.
1462
1463
        :return: the absolute Unicode path on the server,
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1464
        """
1465
        relative = urlutils.unescape(relpath).encode('utf-8')
1466
        remote_path = self._combine_paths(self._path, relative)
1467
        return remote_path
1468
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
1469
    def _get_shared_connection(self):
1470
        """Get the object shared amongst cloned transports.
1471
1472
        This should be used only by classes that needs to extend the sharing
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1473
        with objects other than transports.
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
1474
1475
        Use _get_connection to get the connection itself.
1476
        """
1477
        return self._shared_connection
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
1478
1479
    def _set_connection(self, connection, credentials=None):
2485.8.34 by Vincent Ladeuil
Refactor mutiple connections detection and fix false positives. Only
1480
        """Record a newly created connection with its associated credentials.
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1481
2485.8.30 by Vincent Ladeuil
Implement reliable connection sharing.
1482
        Note: To ensure that connection is still shared after a temporary
1483
        failure and a new one needs to be created, daughter classes should
2485.8.34 by Vincent Ladeuil
Refactor mutiple connections detection and fix false positives. Only
1484
        always call this method to set the connection and do so each time a new
1485
        connection is created.
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
1486
1487
        :param connection: An opaque object representing the connection used by
1488
            the daughter class.
1489
1490
        :param credentials: An opaque object representing the credentials
1491
            needed to create the connection.
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1492
        """
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1493
        self._shared_connection.connection = connection
1494
        self._shared_connection.credentials = credentials
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
1495
1496
    def _get_connection(self):
2485.8.30 by Vincent Ladeuil
Implement reliable connection sharing.
1497
        """Returns the transport specific connection object."""
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1498
        return self._shared_connection.connection
2485.8.30 by Vincent Ladeuil
Implement reliable connection sharing.
1499
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
1500
    def _get_credentials(self):
2485.8.34 by Vincent Ladeuil
Refactor mutiple connections detection and fix false positives. Only
1501
        """Returns the credentials used to establish the connection."""
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1502
        return self._shared_connection.credentials
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
1503
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
1504
    def _update_credentials(self, credentials):
1505
        """Update the credentials of the current connection.
1506
1507
        Some protocols can renegociate the credentials within a connection,
1508
        this method allows daughter classes to share updated credentials.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1509
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
1510
        :param credentials: the updated credentials.
1511
        """
1512
        # We don't want to call _set_connection here as we are only updating
1513
        # the credentials not creating a new connection.
2485.8.55 by Vincent Ladeuil
Cleanup connection accessors.
1514
        self._shared_connection.credentials = credentials
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
1515
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1516
    def _reuse_for(self, other_base):
1517
        """Returns a transport sharing the same connection if possible.
1518
1519
        Note: we share the connection if the expected credentials are the
1520
        same: (host, port, user). Some protocols may disagree and redefine the
1521
        criteria in daughter classes.
1522
1523
        Note: we don't compare the passwords here because other_base may have
1524
        been obtained from an existing transport.base which do not mention the
1525
        password.
1526
1527
        :param other_base: the URL we want to share the connection with.
1528
1529
        :return: A new transport or None if the connection cannot be shared.
1530
        """
2990.2.2 by Vincent Ladeuil
Detect invalid transport reuse attempts by catching invalid URLs.
1531
        try:
1532
            (scheme, user, password,
1533
             host, port, path) = self._split_url(other_base)
1534
        except errors.InvalidURL:
1535
            # No hope in trying to reuse an existing transport for an invalid
1536
            # URL
1537
            return None
1538
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1539
        transport = None
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
1540
        # Don't compare passwords, they may be absent from other_base or from
1541
        # self and they don't carry more information than user anyway.
2485.8.59 by Vincent Ladeuil
Update from review comments.
1542
        if (scheme == self._scheme
1543
            and user == self._user
1544
            and host == self._host
1545
            and port == self._port):
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1546
            if not path.endswith('/'):
1547
                # This normally occurs at __init__ time, but it's easier to do
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
1548
                # it now to avoid creating two transports for the same base.
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1549
                path += '/'
1550
            if self._path  == path:
1551
                # shortcut, it's really the same transport
1552
                return self
1553
            # We don't call clone here because the intent is different: we
1554
            # build a new transport on a different base (which may be totally
1555
            # unrelated) but we share the connection.
2485.8.59 by Vincent Ladeuil
Update from review comments.
1556
            transport = self.__class__(other_base, _from_transport=self)
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1557
        return transport
1558
5247.2.12 by Vincent Ladeuil
Ensure that all transports close their underlying connection.
1559
    def disconnect(self):
1560
        """Disconnect the transport.
1561
1562
        If and when required the transport willl reconnect automatically.
1563
        """
1564
        raise NotImplementedError(self.disconnect)
1565
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1566
2476.3.8 by Vincent Ladeuil
Mark transports that need to be instrumented or refactored to check
1567
def get_transport(base, possible_transports=None):
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
1568
    """Open a transport to access a URL or directory.
1569
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
1570
    :param base: either a URL or a directory name.
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1571
1572
    :param transports: optional reusable transports list. If not None, created
2485.8.59 by Vincent Ladeuil
Update from review comments.
1573
        transports will be added to the list.
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1574
1575
    :return: A new transport optionally sharing its connection with one of
2485.8.59 by Vincent Ladeuil
Update from review comments.
1576
        possible_transports.
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
1577
    """
907.1.13 by John Arbash Meinel
Fixed bzr root.
1578
    if base is None:
1685.1.11 by John Arbash Meinel
Not all of the registered transports use :// as part of their path, specifically memory:/
1579
        base = '.'
1843.1.1 by John Arbash Meinel
Update get_transport to raise a nicer error which includes dependency info
1580
    last_err = None
3251.3.1 by Aaron Bentley
Add support for directory services
1581
    from bzrlib.directory_service import directories
1582
    base = directories.dereference(base)
1843.1.1 by John Arbash Meinel
Update get_transport to raise a nicer error which includes dependency info
1583
1685.1.33 by John Arbash Meinel
Be more of a Nazi about URLs not being unicode
1584
    def convert_path_to_url(base, error_str):
5254.2.1 by Gordon Tyler
Fixed how get_transport's convert_path_to_url tests whether a path is actually a URL.
1585
        if urlutils.is_url(base):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1586
            # This looks like a URL, but we weren't able to
1685.1.33 by John Arbash Meinel
Be more of a Nazi about URLs not being unicode
1587
            # instantiate it as such raise an appropriate error
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
1588
            # FIXME: we have a 'error_str' unused and we use last_err below
1843.1.1 by John Arbash Meinel
Update get_transport to raise a nicer error which includes dependency info
1589
            raise errors.UnsupportedProtocol(base, last_err)
1685.1.33 by John Arbash Meinel
Be more of a Nazi about URLs not being unicode
1590
        # This doesn't look like a protocol, consider it a local path
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
1591
        new_base = urlutils.local_path_to_url(base)
1908.3.1 by Carl Friedrich Bolz
Clean up some mutter() calls.
1592
        # mutter('converting os path %r => url %s', base, new_base)
1685.1.33 by John Arbash Meinel
Be more of a Nazi about URLs not being unicode
1593
        return new_base
1594
1595
    # Catch any URLs which are passing Unicode rather than ASCII
1596
    try:
1597
        base = base.encode('ascii')
1598
    except UnicodeError:
1599
        # Only local paths can be Unicode
1600
        base = convert_path_to_url(base,
1601
            'URLs must be properly escaped (protocol: %s)')
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
1602
1603
    transport = None
1551.18.10 by Aaron Bentley
get_transport appends to possible_transports if it's an empty list
1604
    if possible_transports is not None:
2476.3.8 by Vincent Ladeuil
Mark transports that need to be instrumented or refactored to check
1605
        for t in possible_transports:
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1606
            t_same_connection = t._reuse_for(base)
1607
            if t_same_connection is not None:
1608
                # Add only new transports
1609
                if t_same_connection not in possible_transports:
1610
                    possible_transports.append(t_same_connection)
1611
                return t_same_connection
1612
3882.1.1 by Martin Pool
Don't call iteritems on transport_list_registry, because it may change during iteration
1613
    for proto, factory_list in transport_list_registry.items():
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1614
        if proto is not None and base.startswith(proto):
1615
            transport, last_err = _try_transport_factories(base, factory_list)
1616
            if transport:
1551.18.10 by Aaron Bentley
get_transport appends to possible_transports if it's an empty list
1617
                if possible_transports is not None:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1618
                    if transport in possible_transports:
1619
                        raise AssertionError()
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1620
                    possible_transports.append(transport)
1621
                return transport
1622
2485.8.43 by Vincent Ladeuil
Cleaning.
1623
    # We tried all the different protocols, now try one last time
1624
    # as a local protocol
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1625
    base = convert_path_to_url(base, 'Unsupported protocol: %s')
1626
2485.8.43 by Vincent Ladeuil
Cleaning.
1627
    # The default handler is the filesystem handler, stored as protocol None
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1628
    factory_list = transport_list_registry.get(None)
1629
    transport, last_err = _try_transport_factories(base, factory_list)
1630
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
1631
    return transport
1632
1633
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
1634
def _try_transport_factories(base, factory_list):
1635
    last_err = None
1636
    for factory in factory_list:
1637
        try:
1638
            return factory.get_obj()(base), None
1639
        except errors.DependencyNotPresent, e:
1640
            mutter("failed to instantiate transport %r for %r: %r" %
1641
                    (factory, base, e))
1642
            last_err = e
1643
            continue
1644
    return None, last_err
1645
1646
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1647
def do_catching_redirections(action, transport, redirected):
2164.2.21 by Vincent Ladeuil
Take bundles into account.
1648
    """Execute an action with given transport catching redirections.
1649
1650
    This is a facility provided for callers needing to follow redirections
2164.2.25 by Vincent Ladeuil
Fix typos noticed by Aaron.
1651
    silently. The silence is relative: it is the caller responsability to
2164.2.21 by Vincent Ladeuil
Take bundles into account.
1652
    inform the user about each redirection or only inform the user of a user
1653
    via the exception parameter.
1654
1655
    :param action: A callable, what the caller want to do while catching
1656
                  redirections.
1657
    :param transport: The initial transport used.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1658
    :param redirected: A callable receiving the redirected transport and the
2164.2.21 by Vincent Ladeuil
Take bundles into account.
1659
                  RedirectRequested exception.
1660
1661
    :return: Whatever 'action' returns
1662
    """
1663
    MAX_REDIRECTIONS = 8
1664
1665
    # If a loop occurs, there is little we can do. So we don't try to detect
1666
    # them, just getting out if too much redirections occurs. The solution
1667
    # is outside: where the loop is defined.
1668
    for redirections in range(MAX_REDIRECTIONS):
1669
        try:
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1670
            return action(transport)
2164.2.21 by Vincent Ladeuil
Take bundles into account.
1671
        except errors.RedirectRequested, e:
1672
            redirection_notice = '%s is%s redirected to %s' % (
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1673
                e.source, e.permanently, e.target)
1674
            transport = redirected(transport, e, redirection_notice)
2164.2.21 by Vincent Ladeuil
Take bundles into account.
1675
    else:
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1676
        # Loop exited without resolving redirect ? Either the
1677
        # user has kept a very very very old reference or a loop
2164.2.25 by Vincent Ladeuil
Fix typos noticed by Aaron.
1678
        # occurred in the redirections.  Nothing we can cure here:
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1679
        # tell the user. Note that as the user has been informed
1680
        # about each redirection (it is the caller responsibility
1681
        # to do that in redirected via the provided
1682
        # redirection_notice). The caller may provide more
2164.2.25 by Vincent Ladeuil
Fix typos noticed by Aaron.
1683
        # information if needed (like what file or directory we
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1684
        # were trying to act upon when the redirection loop
2164.2.25 by Vincent Ladeuil
Fix typos noticed by Aaron.
1685
        # occurred).
2164.2.22 by Vincent Ladeuil
Take Aaron's review comments into account.
1686
        raise errors.TooManyRedirections
2164.2.21 by Vincent Ladeuil
Take bundles into account.
1687
1688
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1689
class Server(object):
1530.1.21 by Robert Collins
Review feedback fixes.
1690
    """A Transport Server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1691
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
1692
    The Server interface provides a server for a given transport type.
1530.1.21 by Robert Collins
Review feedback fixes.
1693
    """
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1694
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
1695
    def start_server(self):
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1696
        """Setup the server to service requests."""
1697
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
1698
    def stop_server(self):
1530.1.3 by Robert Collins
transport implementations now tested consistently.
1699
        """Remove the server and cleanup any resources it owns."""
1700
1701
1185.16.81 by mbp at sourcefrog
[merge] robert
1702
# None is the default transport, for things with no url scheme
2241.2.9 by ghigo
add the 'file://' prefix to the urlspec topic
1703
register_transport_proto('file://',
1704
            help="Access using the standard filesystem (default)")
1185.16.79 by Martin Pool
Load transports when they're first used.
1705
register_lazy_transport('file://', 'bzrlib.transport.local', 'LocalTransport')
2241.2.3 by ghigo
removed the the registration of the 'None' transport, instead we use the set_default_transport function
1706
transport_list_registry.set_default_transport("file://")
2241.2.4 by ghigo
removed commented line
1707
2241.2.5 by ghigo
add the topics transport
1708
register_transport_proto('sftp://',
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
1709
            help="Access using SFTP (most SSH servers provide SFTP).",
1710
            register_netloc=True)
1185.16.79 by Martin Pool
Load transports when they're first used.
1711
register_lazy_transport('sftp://', 'bzrlib.transport.sftp', 'SFTPTransport')
2164.2.7 by v.ladeuil+lp at free
First implementation of transport hints.
1712
# Decorated http transport
2241.2.5 by ghigo
add the topics transport
1713
register_transport_proto('http+urllib://',
2241.2.11 by ghigo
On the basis of Robert Collins and John Arbash Meinel
1714
#                help="Read-only access of branches exported on the web."
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1715
                         register_netloc=True)
1540.3.23 by Martin Pool
Allow urls like http+pycurl://host/ to use a particular impl
1716
register_lazy_transport('http+urllib://', 'bzrlib.transport.http._urllib',
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
1717
                        'HttpTransport_urllib')
2241.2.5 by ghigo
add the topics transport
1718
register_transport_proto('https+urllib://',
2241.2.11 by ghigo
On the basis of Robert Collins and John Arbash Meinel
1719
#                help="Read-only access of branches exported on the web using SSL."
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1720
                         register_netloc=True)
1540.3.23 by Martin Pool
Allow urls like http+pycurl://host/ to use a particular impl
1721
register_lazy_transport('https+urllib://', 'bzrlib.transport.http._urllib',
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
1722
                        'HttpTransport_urllib')
2241.2.5 by ghigo
add the topics transport
1723
register_transport_proto('http+pycurl://',
2241.2.11 by ghigo
On the basis of Robert Collins and John Arbash Meinel
1724
#                help="Read-only access of branches exported on the web."
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1725
                         register_netloc=True)
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
1726
register_lazy_transport('http+pycurl://', 'bzrlib.transport.http._pycurl',
1727
                        'PyCurlTransport')
2241.2.5 by ghigo
add the topics transport
1728
register_transport_proto('https+pycurl://',
2241.2.11 by ghigo
On the basis of Robert Collins and John Arbash Meinel
1729
#                help="Read-only access of branches exported on the web using SSL."
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1730
                         register_netloc=True)
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
1731
register_lazy_transport('https+pycurl://', 'bzrlib.transport.http._pycurl',
1732
                        'PyCurlTransport')
2164.2.7 by v.ladeuil+lp at free
First implementation of transport hints.
1733
# Default http transports (last declared wins (if it can be imported))
2241.2.5 by ghigo
add the topics transport
1734
register_transport_proto('http://',
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1735
                 help="Read-only access of branches exported on the web.")
2241.2.5 by ghigo
add the topics transport
1736
register_transport_proto('https://',
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1737
            help="Read-only access of branches exported on the web using SSL.")
3882.2.1 by John Arbash Meinel
Use urllib for http connections, pycurl for https connections.
1738
# The default http implementation is urllib, but https is pycurl if available
1739
register_lazy_transport('http://', 'bzrlib.transport.http._pycurl',
1740
                        'PyCurlTransport')
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
1741
register_lazy_transport('http://', 'bzrlib.transport.http._urllib',
1742
                        'HttpTransport_urllib')
1743
register_lazy_transport('https://', 'bzrlib.transport.http._urllib',
1744
                        'HttpTransport_urllib')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1745
register_lazy_transport('https://', 'bzrlib.transport.http._pycurl',
1746
                        'PyCurlTransport')
2241.2.4 by ghigo
removed commented line
1747
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1748
register_transport_proto('ftp://', help="Access using passive FTP.")
1185.36.4 by Daniel Silverstone
Add FTP transport
1749
register_lazy_transport('ftp://', 'bzrlib.transport.ftp', 'FtpTransport')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1750
register_transport_proto('aftp://', help="Access using active FTP.")
1185.36.4 by Daniel Silverstone
Add FTP transport
1751
register_lazy_transport('aftp://', 'bzrlib.transport.ftp', 'FtpTransport')
5270.1.3 by Jelmer Vernooij
Remove unused imports, lazily load kerberos python module.
1752
register_transport_proto('gio+', help="Access using any GIO supported protocols.")
1753
register_lazy_transport('gio+', 'bzrlib.transport.gio_transport', 'GioTransport')
1754
1755
1756
# Default to trying GSSAPI authentication (if the kerberos module is
1757
# available)
5270.1.1 by Jelmer Vernooij
Always register GSSAPI proto's, even if we don't have an implementation that uses them.
1758
register_transport_proto('ftp+gssapi://', register_netloc=True)
1759
register_transport_proto('aftp+gssapi://', register_netloc=True)
1760
register_transport_proto('ftp+nogssapi://', register_netloc=True)
1761
register_transport_proto('aftp+nogssapi://', register_netloc=True)
5270.1.3 by Jelmer Vernooij
Remove unused imports, lazily load kerberos python module.
1762
register_lazy_transport('ftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1763
                        'GSSAPIFtpTransport')
1764
register_lazy_transport('aftp+gssapi://', 'bzrlib.transport.ftp._gssapi',
1765
                        'GSSAPIFtpTransport')
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',
1771
                        'FtpTransport')
1772
register_lazy_transport('aftp+nogssapi://', 'bzrlib.transport.ftp',
1773
                        'FtpTransport')
3331.2.4 by Jelmer Vernooij
Move GSSAPI support to a separate file.
1774
2241.2.1 by ghigo
Add the TransportRegistry class
1775
register_transport_proto('memory://')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1776
register_lazy_transport('memory://', 'bzrlib.transport.memory',
1777
                        'MemoryTransport')
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
1778
1779
# chroots cannot be implicitly accessed, they must be explicitly created:
2241.2.1 by ghigo
Add the TransportRegistry class
1780
register_transport_proto('chroot+')
2241.3.6 by ghigo
Upgraded to the latest bzr.dev
1781
2241.2.5 by ghigo
add the topics transport
1782
register_transport_proto('readonly+',
2241.2.11 by ghigo
On the basis of Robert Collins and John Arbash Meinel
1783
#              help="This modifier converts any transport to be readonly."
1784
            )
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1785
register_lazy_transport('readonly+', 'bzrlib.transport.readonly',
1786
                        'ReadonlyTransportDecorator')
2555.3.8 by Martin Pool
Add new BrokenRenameTransportDecorator
1787
2617.4.5 by Robert Collins
Reinstate the fakenfs+ decorator registration.
1788
register_transport_proto('fakenfs+')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1789
register_lazy_transport('fakenfs+', 'bzrlib.transport.fakenfs',
1790
                        'FakeNFSTransportDecorator')
2617.4.5 by Robert Collins
Reinstate the fakenfs+ decorator registration.
1791
3675.1.1 by Martin Pool
Merge and update log+ transport decorator
1792
register_transport_proto('log+')
1793
register_lazy_transport('log+', 'bzrlib.transport.log', 'TransportLogDecorator')
1794
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
1795
register_transport_proto('trace+')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1796
register_lazy_transport('trace+', 'bzrlib.transport.trace',
1797
                        'TransportTraceDecorator')
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
1798
2617.4.1 by Robert Collins
Add a new transport decorator unlistable+ for testing.
1799
register_transport_proto('unlistable+')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1800
register_lazy_transport('unlistable+', 'bzrlib.transport.unlistable',
1801
                        'UnlistableTransportDecorator')
2555.3.8 by Martin Pool
Add new BrokenRenameTransportDecorator
1802
1803
register_transport_proto('brokenrename+')
1804
register_lazy_transport('brokenrename+', 'bzrlib.transport.brokenrename',
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1805
                        'BrokenRenameTransportDecorator')
2555.3.8 by Martin Pool
Add new BrokenRenameTransportDecorator
1806
2241.2.1 by ghigo
Add the TransportRegistry class
1807
register_transport_proto('vfat+')
1910.19.1 by Andrew Bennetts
Support bzr:// urls to work with the new RPC-based transport which will be used
1808
register_lazy_transport('vfat+',
1608.2.4 by Martin Pool
[broken] Add FakeFVATTransport
1809
                        'bzrlib.transport.fakevfat',
1810
                        'FakeVFATTransportDecorator')
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
1811
3313.3.4 by Andrew Bennetts
Add a 'nosmart+' transport decorator.
1812
register_transport_proto('nosmart+')
1813
register_lazy_transport('nosmart+', 'bzrlib.transport.nosmart',
1814
                        'NoSmartTransportDecorator')
1815
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
1816
# These two schemes were registered, but don't seem to have an actual transport
1817
# protocol registered
1818
for scheme in ['ssh', 'bzr+loopback']:
2919.2.2 by John Arbash Meinel
fix a simple typo
1819
    register_urlparse_netloc_protocol(scheme)
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
1820
del scheme
1821
2241.2.5 by ghigo
add the topics transport
1822
register_transport_proto('bzr://',
2811.1.1 by Andrew Bennetts
Cherrypick fix proposed for 0.90.
1823
            help="Fast access using the Bazaar smart server.",
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1824
                         register_netloc=True)
2241.2.5 by ghigo
add the topics transport
1825
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1826
register_lazy_transport('bzr://', 'bzrlib.transport.remote',
2413.2.1 by Andrew Bennetts
Rename Smart.*Transport classes to RemoteTransport, RemoteTCPTransport, etc.
1827
                        'RemoteTCPTransport')
3453.5.1 by Andrew Bennetts
Add {bzrdir,repository,branch}_implementations tests for Remote objects using protocol v2 and pre-1.6 RPCs.
1828
register_transport_proto('bzr-v2://', register_netloc=True)
1829
1830
register_lazy_transport('bzr-v2://', 'bzrlib.transport.remote',
1831
                        'RemoteTCPTransportV2Only')
2241.2.5 by ghigo
add the topics transport
1832
register_transport_proto('bzr+http://',
2241.2.11 by ghigo
On the basis of Robert Collins and John Arbash Meinel
1833
#                help="Fast access using the Bazaar smart server over HTTP."
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1834
                         register_netloc=True)
1835
register_lazy_transport('bzr+http://', 'bzrlib.transport.remote',
2413.2.1 by Andrew Bennetts
Rename Smart.*Transport classes to RemoteTransport, RemoteTCPTransport, etc.
1836
                        'RemoteHTTPTransport')
2651.1.1 by John Ferlito
bzr+https support
1837
register_transport_proto('bzr+https://',
1838
#                help="Fast access using the Bazaar smart server over HTTPS."
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1839
                         register_netloc=True)
2651.1.1 by John Ferlito
bzr+https support
1840
register_lazy_transport('bzr+https://',
1841
                        'bzrlib.transport.remote',
1842
                        'RemoteHTTPTransport')
2241.2.5 by ghigo
add the topics transport
1843
register_transport_proto('bzr+ssh://',
2919.2.1 by John Arbash Meinel
Register netloc protocols as soon as the protocol is registered.
1844
            help="Fast access using the Bazaar smart server over SSH.",
1845
            register_netloc=True)
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
1846
register_lazy_transport('bzr+ssh://', 'bzrlib.transport.remote',
2413.2.1 by Andrew Bennetts
Rename Smart.*Transport classes to RemoteTransport, RemoteTCPTransport, etc.
1847
                        'RemoteSSHTransport')
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
1848
4011.4.2 by Jelmer Vernooij
Register ssh: rather than ssh://, avoid referring to smart server, which users may not be familiar with.
1849
register_transport_proto('ssh:')
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
1850
register_lazy_transport('ssh:', 'bzrlib.transport.remote',
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
1851
                        'HintingSSHTransport')
4370.4.6 by Jelmer Vernooij
Move server protocol registry to bzrlib.transport.
1852
1853
1854
transport_server_registry = registry.Registry()
5056.1.4 by Neil Santos
Changed stat() in SFTPTransport and LocalTransport back to calling plain stat(), instead of lstat().
1855
transport_server_registry.register_lazy('bzr', 'bzrlib.smart.server',
4370.4.6 by Jelmer Vernooij
Move server protocol registry to bzrlib.transport.
1856
    'serve_bzr', help="The Bazaar smart server protocol over TCP. (default port: 4155)")
1857
transport_server_registry.default_key = 'bzr'