~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

  • Committer: Andrew Bennetts
  • Date: 2007-08-17 08:31:52 UTC
  • mto: This revision was merged to the branch mainline in revision 3320.
  • Revision ID: andrew.bennetts@canonical.com-20070817083152-rmhqerwquini7tiz
Add translate_client_path method to SmartServerRequest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    errors,
25
25
    registry,
26
26
    revision,
 
27
    urlutils,
27
28
    )
28
29
from bzrlib.bundle.serializer import write_bundle
 
30
from bzrlib.trace import mutter
 
31
from bzrlib.transport import get_transport
 
32
from bzrlib.transport.chroot import ChrootServer
29
33
 
30
34
 
31
35
class SmartServerRequest(object):
32
36
    """Base class for request handlers."""
33
37
 
34
 
    def __init__(self, backing_transport):
 
38
    def __init__(self, backing_transport, root_client_path='/'):
35
39
        """Constructor.
36
40
 
37
41
        :param backing_transport: the base transport to be used when performing
38
42
            this request.
 
43
        :param root_client_path: the client path that maps to the root of
 
44
            backing_transport.  This is used to interpret relpaths received from
 
45
            the client.
39
46
        """
40
47
        self._backing_transport = backing_transport
 
48
#        self._real_backing_transport = backing_transport
 
49
        if not root_client_path.startswith('/'):
 
50
            root_client_path = '/' + root_client_path
 
51
        if not root_client_path.endswith('/'):
 
52
            root_client_path += '/'
 
53
        self._root_client_path = root_client_path
41
54
 
42
55
    def _check_enabled(self):
43
56
        """Raises DisabledMethod if this method is disabled."""
63
76
        """
64
77
        self._check_enabled()
65
78
        return self.do(*args)
 
79
#        chrooted_backing = ChrootServer(self._real_backing_transport)
 
80
#        chrooted_backing.setUp()
 
81
#        self._backing_transport = get_transport(chrooted_backing.get_url())
 
82
#        try:
 
83
#            return self.do(*args)
 
84
#        finally:
 
85
#            self._backing_transport = None
 
86
#            chrooted_backing.tearDown()
66
87
 
67
88
    def do_body(self, body_bytes):
68
89
        """Called if the client sends a body with the request.
74
95
        # this NotImplementedError and translate it into a 'bad request' error
75
96
        # to send to the client.
76
97
        raise NotImplementedError(self.do_body)
 
98
    
 
99
    def translate_client_path(self, client_path):
 
100
        if not client_path.startswith('/'):
 
101
            client_path = '/' + client_path
 
102
        if client_path.startswith(self._root_client_path):
 
103
            path = client_path[len(self._root_client_path):]
 
104
            relpath = urlutils.joinpath('/', path)
 
105
            assert relpath.startswith('/')
 
106
            return '.' + relpath
 
107
        else:
 
108
            raise errors.PathNotChild(client_path, self._root_client_path)
 
109
 
 
110
    def transport_from_client_path(self, client_path):
 
111
        # inputs:
 
112
        #  * 'path': path the client sent
 
113
        #  * 'self._backing_transport': transport rooted at what we're serving
 
114
        #  * xxx: path to _backing_transport root as a client path
 
115
        relpath = self.translate_client_path(client_path)
 
116
        return self._backing_transport.clone(relpath)
77
117
 
78
118
 
79
119
class SmartServerResponse(object):
93
133
        return other.args == self.args and other.body == self.body
94
134
 
95
135
    def __repr__(self):
96
 
        return "<SmartServerResponse args=%r body=%r>" % (self.is_successful(), 
 
136
        status = {True: 'OK', False: 'ERR'}[self.is_successful()]
 
137
        return "<SmartServerResponse status=%s args=%r body=%r>" % (status,
97
138
            self.args, self.body)
98
139
 
99
140
 
130
171
    # TODO: Better way of representing the body for commands that take it,
131
172
    # and allow it to be streamed into the server.
132
173
 
133
 
    def __init__(self, backing_transport, commands):
 
174
    def __init__(self, backing_transport, commands, root_client_path):
134
175
        """Constructor.
135
176
 
136
177
        :param backing_transport: a Transport to handle requests for.
138
179
            subclasses. e.g. bzrlib.transport.smart.vfs.vfs_commands.
139
180
        """
140
181
        self._backing_transport = backing_transport
 
182
        self._root_client_path = root_client_path
141
183
        self._commands = commands
142
184
        self._body_bytes = ''
143
185
        self.response = None
163
205
 
164
206
    def dispatch_command(self, cmd, args):
165
207
        """Deprecated compatibility method.""" # XXX XXX
 
208
        #mutter('%s[%s]: %r %r)' % (self._backing_transport.server.backing_transport.base,
 
209
        #    self._backing_transport.base_path, cmd, args))
166
210
        try:
167
211
            command = self._commands.get(cmd)
168
212
        except LookupError:
169
213
            raise errors.SmartProtocolError("bad request %r" % (cmd,))
170
 
        self._command = command(self._backing_transport)
 
214
        self._command = command(self._backing_transport, self._root_client_path)
171
215
        self._run_handler_code(self._command.execute, args, {})
172
216
 
173
217
    def _run_handler_code(self, callable, args, kwargs):
182
226
        result = self._call_converting_errors(callable, args, kwargs)
183
227
 
184
228
        if result is not None:
 
229
            #mutter('  -> %r' % (result,))
185
230
            self.response = result
186
231
            self.finished_reading = True
187
232