~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/chroot.py

Various hopefully improvements, but wsgi is broken, handing over to spiv :).

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Implementation of Transport that prevents access to locations above a set
18
18
root.
19
19
"""
 
20
from urlparse import urlparse
20
21
 
21
22
from bzrlib import errors, urlutils
 
23
from bzrlib.osutils import pathjoin
22
24
from bzrlib.transport.decorator import TransportDecorator, DecoratorServer
23
25
 
24
26
 
25
27
class ChrootTransportDecorator(TransportDecorator):
26
28
    """A decorator that can convert any transport to be chrooted.
27
29
 
28
 
    This is requested via the 'chrooted+' prefix to get_transport().
 
30
    This is requested via the 'chroot+' prefix to get_transport().
29
31
    """
30
32
 
31
33
    def __init__(self, url, _decorated=None, chroot=None):
35
37
            self.chroot_url = self._decorated.base
36
38
        else:
37
39
            self.chroot_url = chroot
 
40
        self.chroot_relative = '/' + self._decorated.base[len(self.chroot_url):]
38
41
 
39
42
    @classmethod
40
43
    def _get_url_prefix(self):
58
61
        return TransportDecorator.append_bytes(self, relpath, bytes, mode=mode)
59
62
 
60
63
    def clone(self, offset=None):
61
 
        self._ensure_relpath_is_child(offset)
62
 
        return TransportDecorator.clone(self, offset)
 
64
        if offset is None: return self
 
65
        # the new URL we want to clone to is
 
66
        # self.chroot_url + an adjusted self.chroot_relative, with the leading
 
67
        # / removed.
 
68
        newrelative = pathjoin(self.chroot_relative, offset)
 
69
        newabs = self.chroot_url + newrelative[1:]
 
70
        # now split to get a abspath without scheme
 
71
        parsed = urlparse(newabs)
 
72
        decorated_clone = self._decorated.clone(parsed[2])
 
73
        return ChrootTransportDecorator(self._get_url_prefix() + newabs,
 
74
            decorated_clone, self.chroot_url)
63
75
 
64
76
    def delete(self, relpath):
65
77
        self._ensure_relpath_is_child(relpath)