~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

  • Committer: Martin
  • Date: 2010-05-25 17:27:52 UTC
  • mfrom: (5254 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5257.
  • Revision ID: gzlist@googlemail.com-20100525172752-amm089xcikv968sw
Merge bzr.dev to unite with similar changes already made

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
32
32
 
33
33
 
34
34
import tempfile
 
35
import thread
35
36
import threading
36
37
 
37
38
from bzrlib import (
38
39
    bzrdir,
 
40
    debug,
39
41
    errors,
 
42
    osutils,
40
43
    registry,
41
44
    revision,
42
45
    trace,
86
89
    # XXX: rename this class to BaseSmartServerRequestHandler ?  A request
87
90
    # *handler* is a different concept to the request.
88
91
 
89
 
    def __init__(self, backing_transport, root_client_path='/'):
 
92
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
90
93
        """Constructor.
91
94
 
92
95
        :param backing_transport: the base transport to be used when performing
96
99
            from the client.  Clients will not be able to refer to paths above
97
100
            this root.  If root_client_path is None, then no translation will
98
101
            be performed on client paths.  Default is '/'.
 
102
        :param jail_root: if specified, the root of the BzrDir.open jail to use
 
103
            instead of backing_transport.
99
104
        """
100
105
        self._backing_transport = backing_transport
 
106
        if jail_root is None:
 
107
            jail_root = backing_transport
 
108
        self._jail_root = jail_root
101
109
        if root_client_path is not None:
102
110
            if not root_client_path.startswith('/'):
103
111
                root_client_path = '/' + root_client_path
155
163
        return self.do_body(body_bytes)
156
164
 
157
165
    def setup_jail(self):
158
 
        jail_info.transports = [self._backing_transport]
 
166
        jail_info.transports = [self._jail_root]
159
167
 
160
168
    def teardown_jail(self):
161
169
        jail_info.transports = None
183
191
            relpath = urlutils.joinpath('/', path)
184
192
            if not relpath.startswith('/'):
185
193
                raise ValueError(relpath)
186
 
            return '.' + relpath
 
194
            return urlutils.escape('.' + relpath)
187
195
        else:
188
196
            raise errors.PathNotChild(client_path, self._root_client_path)
189
197
 
265
273
    # TODO: Better way of representing the body for commands that take it,
266
274
    # and allow it to be streamed into the server.
267
275
 
268
 
    def __init__(self, backing_transport, commands, root_client_path):
 
276
    def __init__(self, backing_transport, commands, root_client_path,
 
277
        jail_root=None):
269
278
        """Constructor.
270
279
 
271
280
        :param backing_transport: a Transport to handle requests for.
275
284
        self._backing_transport = backing_transport
276
285
        self._root_client_path = root_client_path
277
286
        self._commands = commands
 
287
        if jail_root is None:
 
288
            jail_root = backing_transport
 
289
        self._jail_root = jail_root
278
290
        self.response = None
279
291
        self.finished_reading = False
280
292
        self._command = None
 
293
        if 'hpss' in debug.debug_flags:
 
294
            self._request_start_time = osutils.timer_func()
 
295
            self._thread_id = thread.get_ident()
 
296
 
 
297
    def _trace(self, action, message, extra_bytes=None, include_time=False):
 
298
        # It is a bit of a shame that this functionality overlaps with that of 
 
299
        # ProtocolThreeRequester._trace. However, there is enough difference
 
300
        # that just putting it in a helper doesn't help a lot. And some state
 
301
        # is taken from the instance.
 
302
        if include_time:
 
303
            t = '%5.3fs ' % (osutils.timer_func() - self._request_start_time)
 
304
        else:
 
305
            t = ''
 
306
        if extra_bytes is None:
 
307
            extra = ''
 
308
        else:
 
309
            extra = ' ' + repr(extra_bytes[:40])
 
310
            if len(extra) > 33:
 
311
                extra = extra[:29] + extra[-1] + '...'
 
312
        trace.mutter('%12s: [%s] %s%s%s'
 
313
                     % (action, self._thread_id, t, message, extra))
281
314
 
282
315
    def accept_body(self, bytes):
283
316
        """Accept body data."""
285
318
            # no active command object, so ignore the event.
286
319
            return
287
320
        self._run_handler_code(self._command.do_chunk, (bytes,), {})
 
321
        if 'hpss' in debug.debug_flags:
 
322
            self._trace('accept body',
 
323
                        '%d bytes' % (len(bytes),), bytes)
288
324
 
289
325
    def end_of_body(self):
290
326
        """No more body data will be received."""
291
327
        self._run_handler_code(self._command.do_end, (), {})
292
328
        # cannot read after this.
293
329
        self.finished_reading = True
 
330
        if 'hpss' in debug.debug_flags:
 
331
            self._trace('end of body', '', include_time=True)
294
332
 
295
333
    def _run_handler_code(self, callable, args, kwargs):
296
334
        """Run some handler specific code 'callable'.
325
363
 
326
364
    def headers_received(self, headers):
327
365
        # Just a no-op at the moment.
328
 
        pass
 
366
        if 'hpss' in debug.debug_flags:
 
367
            self._trace('headers', repr(headers))
329
368
 
330
369
    def args_received(self, args):
331
370
        cmd = args[0]
333
372
        try:
334
373
            command = self._commands.get(cmd)
335
374
        except LookupError:
 
375
            if 'hpss' in debug.debug_flags:
 
376
                self._trace('hpss unknown request', 
 
377
                            cmd, repr(args)[1:-1])
336
378
            raise errors.UnknownSmartMethod(cmd)
 
379
        if 'hpss' in debug.debug_flags:
 
380
            from bzrlib.smart import vfs
 
381
            if issubclass(command, vfs.VfsRequest):
 
382
                action = 'hpss vfs req'
 
383
            else:
 
384
                action = 'hpss request'
 
385
            self._trace(action, 
 
386
                        '%s %s' % (cmd, repr(args)[1:-1]))
337
387
        self._command = command(
338
 
            self._backing_transport, self._root_client_path)
 
388
            self._backing_transport, self._root_client_path, self._jail_root)
339
389
        self._run_handler_code(self._command.execute, args, {})
340
390
 
341
391
    def end_received(self):
343
393
            # no active command object, so ignore the event.
344
394
            return
345
395
        self._run_handler_code(self._command.do_end, (), {})
 
396
        if 'hpss' in debug.debug_flags:
 
397
            self._trace('end', '', include_time=True)
346
398
 
347
399
    def post_body_error_received(self, error_args):
348
400
        # Just a no-op at the moment.
458
510
    'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
459
511
request_handlers.register_lazy( 'Branch.set_config_option',
460
512
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
 
513
request_handlers.register_lazy( 'Branch.set_config_option_dict',
 
514
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOptionDict')
461
515
request_handlers.register_lazy( 'Branch.set_last_revision',
462
516
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
463
517
request_handlers.register_lazy(
501
555
request_handlers.register_lazy(
502
556
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')
503
557
request_handlers.register_lazy(
 
558
    'BzrDir.open_2.1', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir_2_1')
 
559
request_handlers.register_lazy(
504
560
    'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
505
561
    'SmartServerRequestOpenBranch')
506
562
request_handlers.register_lazy(
507
563
    'BzrDir.open_branchV2', 'bzrlib.smart.bzrdir',
508
564
    'SmartServerRequestOpenBranchV2')
509
565
request_handlers.register_lazy(
 
566
    'BzrDir.open_branchV3', 'bzrlib.smart.bzrdir',
 
567
    'SmartServerRequestOpenBranchV3')
 
568
request_handlers.register_lazy(
510
569
    'delete', 'bzrlib.smart.vfs', 'DeleteRequest')
511
570
request_handlers.register_lazy(
512
571
    'get', 'bzrlib.smart.vfs', 'GetRequest')