~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

  • Committer: Robert Collins
  • Date: 2009-03-31 00:12:10 UTC
  • mto: This revision was merged to the branch mainline in revision 4219.
  • Revision ID: robertc@robertcollins.net-20090331001210-fufeq2heozx9jne0
Fix Tree.get_symlink_target to decode from the disk encoding to get a unicode encoded string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006, 2007 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
36
35
import threading
37
36
 
38
37
from bzrlib import (
39
38
    bzrdir,
40
 
    debug,
41
39
    errors,
42
 
    osutils,
43
40
    registry,
44
41
    revision,
45
42
    trace,
72
69
            continue
73
70
        else:
74
71
            return
75
 
    raise errors.JailBreak(abspath)
 
72
    raise errors.BzrError('jail break: %r' % (abspath,))
76
73
 
77
74
 
78
75
_install_hook()
89
86
    # XXX: rename this class to BaseSmartServerRequestHandler ?  A request
90
87
    # *handler* is a different concept to the request.
91
88
 
92
 
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
 
89
    def __init__(self, backing_transport, root_client_path='/'):
93
90
        """Constructor.
94
91
 
95
92
        :param backing_transport: the base transport to be used when performing
99
96
            from the client.  Clients will not be able to refer to paths above
100
97
            this root.  If root_client_path is None, then no translation will
101
98
            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.
104
99
        """
105
100
        self._backing_transport = backing_transport
106
 
        if jail_root is None:
107
 
            jail_root = backing_transport
108
 
        self._jail_root = jail_root
109
101
        if root_client_path is not None:
110
102
            if not root_client_path.startswith('/'):
111
103
                root_client_path = '/' + root_client_path
163
155
        return self.do_body(body_bytes)
164
156
 
165
157
    def setup_jail(self):
166
 
        jail_info.transports = [self._jail_root]
 
158
        jail_info.transports = [self._backing_transport]
167
159
 
168
160
    def teardown_jail(self):
169
161
        jail_info.transports = None
184
176
            return client_path
185
177
        if not client_path.startswith('/'):
186
178
            client_path = '/' + client_path
187
 
        if client_path + '/' == self._root_client_path:
188
 
            return '.'
189
179
        if client_path.startswith(self._root_client_path):
190
180
            path = client_path[len(self._root_client_path):]
191
181
            relpath = urlutils.joinpath('/', path)
192
182
            if not relpath.startswith('/'):
193
183
                raise ValueError(relpath)
194
 
            return urlutils.escape('.' + relpath)
 
184
            return '.' + relpath
195
185
        else:
196
186
            raise errors.PathNotChild(client_path, self._root_client_path)
197
187
 
273
263
    # TODO: Better way of representing the body for commands that take it,
274
264
    # and allow it to be streamed into the server.
275
265
 
276
 
    def __init__(self, backing_transport, commands, root_client_path,
277
 
        jail_root=None):
 
266
    def __init__(self, backing_transport, commands, root_client_path):
278
267
        """Constructor.
279
268
 
280
269
        :param backing_transport: a Transport to handle requests for.
284
273
        self._backing_transport = backing_transport
285
274
        self._root_client_path = root_client_path
286
275
        self._commands = commands
287
 
        if jail_root is None:
288
 
            jail_root = backing_transport
289
 
        self._jail_root = jail_root
290
276
        self.response = None
291
277
        self.finished_reading = False
292
278
        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))
314
279
 
315
280
    def accept_body(self, bytes):
316
281
        """Accept body data."""
317
 
        if self._command is None:
318
 
            # no active command object, so ignore the event.
319
 
            return
320
282
        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)
324
283
 
325
284
    def end_of_body(self):
326
285
        """No more body data will be received."""
327
286
        self._run_handler_code(self._command.do_end, (), {})
328
287
        # cannot read after this.
329
288
        self.finished_reading = True
330
 
        if 'hpss' in debug.debug_flags:
331
 
            self._trace('end of body', '', include_time=True)
 
289
 
 
290
    def dispatch_command(self, cmd, args):
 
291
        """Deprecated compatibility method.""" # XXX XXX
 
292
        try:
 
293
            command = self._commands.get(cmd)
 
294
        except LookupError:
 
295
            raise errors.UnknownSmartMethod(cmd)
 
296
        self._command = command(self._backing_transport, self._root_client_path)
 
297
        self._run_handler_code(self._command.execute, args, {})
332
298
 
333
299
    def _run_handler_code(self, callable, args, kwargs):
334
300
        """Run some handler specific code 'callable'.
363
329
 
364
330
    def headers_received(self, headers):
365
331
        # Just a no-op at the moment.
366
 
        if 'hpss' in debug.debug_flags:
367
 
            self._trace('headers', repr(headers))
 
332
        pass
368
333
 
369
334
    def args_received(self, args):
370
335
        cmd = args[0]
372
337
        try:
373
338
            command = self._commands.get(cmd)
374
339
        except LookupError:
375
 
            if 'hpss' in debug.debug_flags:
376
 
                self._trace('hpss unknown request', 
377
 
                            cmd, repr(args)[1:-1])
378
340
            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]))
387
 
        self._command = command(
388
 
            self._backing_transport, self._root_client_path, self._jail_root)
 
341
        self._command = command(self._backing_transport)
389
342
        self._run_handler_code(self._command.execute, args, {})
390
343
 
391
344
    def end_received(self):
392
 
        if self._command is None:
393
 
            # no active command object, so ignore the event.
394
 
            return
395
345
        self._run_handler_code(self._command.do_end, (), {})
396
 
        if 'hpss' in debug.debug_flags:
397
 
            self._trace('end', '', include_time=True)
398
346
 
399
347
    def post_body_error_received(self, error_args):
400
348
        # Just a no-op at the moment.
408
356
        return ('FileExists', err.path)
409
357
    elif isinstance(err, errors.DirectoryNotEmpty):
410
358
        return ('DirectoryNotEmpty', err.path)
411
 
    elif isinstance(err, errors.IncompatibleRepositories):
412
 
        return ('IncompatibleRepositories', str(err.source), str(err.target),
413
 
            str(err.details))
414
359
    elif isinstance(err, errors.ShortReadvError):
415
360
        return ('ShortReadvError', err.path, str(err.offset), str(err.length),
416
361
                str(err.actual))
445
390
    elif isinstance(err, errors.TokenMismatch):
446
391
        return ('TokenMismatch', err.given_token, err.lock_token)
447
392
    elif isinstance(err, errors.LockContention):
448
 
        return ('LockContention',)
 
393
        return ('LockContention', err.lock, err.msg)
449
394
    # Unserialisable error.  Log it, and return a generic error
450
395
    trace.log_exception_quietly()
451
396
    return ('error', str(err))
498
443
    'Branch.get_tags_bytes', 'bzrlib.smart.branch',
499
444
    'SmartServerBranchGetTagsBytes')
500
445
request_handlers.register_lazy(
501
 
    'Branch.set_tags_bytes', 'bzrlib.smart.branch',
502
 
    'SmartServerBranchSetTagsBytes')
503
 
request_handlers.register_lazy(
504
446
    'Branch.get_stacked_on_url', 'bzrlib.smart.branch', 'SmartServerBranchRequestGetStackedOnURL')
505
447
request_handlers.register_lazy(
506
448
    'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
507
449
request_handlers.register_lazy(
508
450
    'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
509
 
request_handlers.register_lazy( 'Branch.revision_history',
510
 
    'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
511
 
request_handlers.register_lazy( 'Branch.set_config_option',
512
 
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
513
 
request_handlers.register_lazy( 'Branch.set_config_option_dict',
514
 
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOptionDict')
515
 
request_handlers.register_lazy( 'Branch.set_last_revision',
516
 
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
 
451
request_handlers.register_lazy(
 
452
    'Branch.revision_history', 'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
 
453
request_handlers.register_lazy(
 
454
    'Branch.set_last_revision', 'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
517
455
request_handlers.register_lazy(
518
456
    'Branch.set_last_revision_info', 'bzrlib.smart.branch',
519
457
    'SmartServerBranchRequestSetLastRevisionInfo')
521
459
    'Branch.set_last_revision_ex', 'bzrlib.smart.branch',
522
460
    'SmartServerBranchRequestSetLastRevisionEx')
523
461
request_handlers.register_lazy(
524
 
    'Branch.set_parent_location', 'bzrlib.smart.branch',
525
 
    'SmartServerBranchRequestSetParentLocation')
526
 
request_handlers.register_lazy(
527
462
    'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock')
528
463
request_handlers.register_lazy(
529
464
    'BzrDir.cloning_metadir', 'bzrlib.smart.bzrdir',
544
479
    'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir',
545
480
    'SmartServerRequestFindRepositoryV3')
546
481
request_handlers.register_lazy(
547
 
    'BzrDir.get_config_file', 'bzrlib.smart.bzrdir',
548
 
    'SmartServerBzrDirRequestConfigFile')
549
 
request_handlers.register_lazy(
550
482
    'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir',
551
483
    'SmartServerRequestInitializeBzrDir')
552
484
request_handlers.register_lazy(
553
 
    'BzrDirFormat.initialize_ex_1.16', 'bzrlib.smart.bzrdir',
554
 
    'SmartServerRequestBzrDirInitializeEx')
555
 
request_handlers.register_lazy(
556
 
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')
557
 
request_handlers.register_lazy(
558
 
    'BzrDir.open_2.1', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir_2_1')
559
 
request_handlers.register_lazy(
560
485
    'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
561
486
    'SmartServerRequestOpenBranch')
562
487
request_handlers.register_lazy(
563
488
    'BzrDir.open_branchV2', 'bzrlib.smart.bzrdir',
564
489
    'SmartServerRequestOpenBranchV2')
565
490
request_handlers.register_lazy(
566
 
    'BzrDir.open_branchV3', 'bzrlib.smart.bzrdir',
567
 
    'SmartServerRequestOpenBranchV3')
568
 
request_handlers.register_lazy(
569
491
    'delete', 'bzrlib.smart.vfs', 'DeleteRequest')
570
492
request_handlers.register_lazy(
571
493
    'get', 'bzrlib.smart.vfs', 'GetRequest')
607
529
request_handlers.register_lazy(
608
530
    'Repository.insert_stream', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream')
609
531
request_handlers.register_lazy(
610
 
    'Repository.insert_stream_1.19', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream_1_19')
611
 
request_handlers.register_lazy(
612
532
    'Repository.insert_stream_locked', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStreamLocked')
613
533
request_handlers.register_lazy(
614
534
    'Repository.is_shared', 'bzrlib.smart.repository', 'SmartServerRepositoryIsShared')
620
540
request_handlers.register_lazy(
621
541
    'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock')
622
542
request_handlers.register_lazy(
623
 
    'Repository.get_rev_id_for_revno', 'bzrlib.smart.repository',
624
 
    'SmartServerRepositoryGetRevIdForRevno')
625
 
request_handlers.register_lazy(
626
543
    'Repository.get_stream', 'bzrlib.smart.repository',
627
544
    'SmartServerRepositoryGetStream')
628
545
request_handlers.register_lazy(
629
 
    'Repository.get_stream_1.19', 'bzrlib.smart.repository',
630
 
    'SmartServerRepositoryGetStream_1_19')
631
 
request_handlers.register_lazy(
632
546
    'Repository.tarball', 'bzrlib.smart.repository',
633
547
    'SmartServerRepositoryTarball')
634
548
request_handlers.register_lazy(
637
551
    'stat', 'bzrlib.smart.vfs', 'StatRequest')
638
552
request_handlers.register_lazy(
639
553
    'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly')
 
554
request_handlers.register_lazy(
 
555
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')