/brz/remove-bazaar

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