~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

  • Committer: Andrew Bennetts
  • Date: 2009-04-02 05:53:12 UTC
  • mto: This revision was merged to the branch mainline in revision 4242.
  • Revision ID: andrew.bennetts@canonical.com-20090402055312-h7mvgumvm7e620mj
Fix nits in spelling and naming.

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
31
31
# of a SmartServerRequest subclass.
32
32
 
33
33
 
 
34
import tempfile
34
35
import threading
35
36
 
36
37
from bzrlib import (
37
38
    bzrdir,
38
 
    debug,
39
39
    errors,
40
 
    osutils,
41
40
    registry,
42
41
    revision,
43
42
    trace,
46
45
from bzrlib.lazy_import import lazy_import
47
46
lazy_import(globals(), """
48
47
from bzrlib.bundle import serializer
49
 
 
50
 
import tempfile
51
 
import thread
52
48
""")
53
49
 
54
50
 
62
58
 
63
59
 
64
60
def _pre_open_hook(transport):
65
 
    allowed_transports = getattr(jail_info, 'transports', None)
 
61
    allowed_transports = jail_info.transports
66
62
    if allowed_transports is None:
67
63
        return
68
64
    abspath = transport.base
73
69
            continue
74
70
        else:
75
71
            return
76
 
    raise errors.JailBreak(abspath)
 
72
    raise errors.BzrError('jail break: %r' % (abspath,))
77
73
 
78
74
 
79
75
_install_hook()
90
86
    # XXX: rename this class to BaseSmartServerRequestHandler ?  A request
91
87
    # *handler* is a different concept to the request.
92
88
 
93
 
    def __init__(self, backing_transport, root_client_path='/', jail_root=None):
 
89
    def __init__(self, backing_transport, root_client_path='/'):
94
90
        """Constructor.
95
91
 
96
92
        :param backing_transport: the base transport to be used when performing
100
96
            from the client.  Clients will not be able to refer to paths above
101
97
            this root.  If root_client_path is None, then no translation will
102
98
            be performed on client paths.  Default is '/'.
103
 
        :param jail_root: if specified, the root of the BzrDir.open jail to use
104
 
            instead of backing_transport.
105
99
        """
106
100
        self._backing_transport = backing_transport
107
 
        if jail_root is None:
108
 
            jail_root = backing_transport
109
 
        self._jail_root = jail_root
110
101
        if root_client_path is not None:
111
102
            if not root_client_path.startswith('/'):
112
103
                root_client_path = '/' + root_client_path
135
126
        It will return a SmartServerResponse if the command does not expect a
136
127
        body.
137
128
 
138
 
        :param args: the arguments of the request.
 
129
        :param *args: the arguments of the request.
139
130
        """
140
131
        self._check_enabled()
141
132
        return self.do(*args)
164
155
        return self.do_body(body_bytes)
165
156
 
166
157
    def setup_jail(self):
167
 
        jail_info.transports = [self._jail_root]
 
158
        jail_info.transports = [self._backing_transport]
168
159
 
169
160
    def teardown_jail(self):
170
161
        jail_info.transports = None
185
176
            return client_path
186
177
        if not client_path.startswith('/'):
187
178
            client_path = '/' + client_path
188
 
        if client_path + '/' == self._root_client_path:
189
 
            return '.'
190
179
        if client_path.startswith(self._root_client_path):
191
180
            path = client_path[len(self._root_client_path):]
192
181
            relpath = urlutils.joinpath('/', path)
193
182
            if not relpath.startswith('/'):
194
183
                raise ValueError(relpath)
195
 
            return urlutils.escape('.' + relpath)
 
184
            return '.' + relpath
196
185
        else:
197
186
            raise errors.PathNotChild(client_path, self._root_client_path)
198
187
 
274
263
    # TODO: Better way of representing the body for commands that take it,
275
264
    # and allow it to be streamed into the server.
276
265
 
277
 
    def __init__(self, backing_transport, commands, root_client_path,
278
 
        jail_root=None):
 
266
    def __init__(self, backing_transport, commands, root_client_path):
279
267
        """Constructor.
280
268
 
281
269
        :param backing_transport: a Transport to handle requests for.
285
273
        self._backing_transport = backing_transport
286
274
        self._root_client_path = root_client_path
287
275
        self._commands = commands
288
 
        if jail_root is None:
289
 
            jail_root = backing_transport
290
 
        self._jail_root = jail_root
291
276
        self.response = None
292
277
        self.finished_reading = False
293
278
        self._command = None
294
 
        if 'hpss' in debug.debug_flags:
295
 
            self._request_start_time = osutils.timer_func()
296
 
            self._thread_id = thread.get_ident()
297
 
 
298
 
    def _trace(self, action, message, extra_bytes=None, include_time=False):
299
 
        # It is a bit of a shame that this functionality overlaps with that of 
300
 
        # ProtocolThreeRequester._trace. However, there is enough difference
301
 
        # that just putting it in a helper doesn't help a lot. And some state
302
 
        # is taken from the instance.
303
 
        if include_time:
304
 
            t = '%5.3fs ' % (osutils.timer_func() - self._request_start_time)
305
 
        else:
306
 
            t = ''
307
 
        if extra_bytes is None:
308
 
            extra = ''
309
 
        else:
310
 
            extra = ' ' + repr(extra_bytes[:40])
311
 
            if len(extra) > 33:
312
 
                extra = extra[:29] + extra[-1] + '...'
313
 
        trace.mutter('%12s: [%s] %s%s%s'
314
 
                     % (action, self._thread_id, t, message, extra))
315
279
 
316
280
    def accept_body(self, bytes):
317
281
        """Accept body data."""
318
 
        if self._command is None:
319
 
            # no active command object, so ignore the event.
320
 
            return
321
282
        self._run_handler_code(self._command.do_chunk, (bytes,), {})
322
 
        if 'hpss' in debug.debug_flags:
323
 
            self._trace('accept body',
324
 
                        '%d bytes' % (len(bytes),), bytes)
325
283
 
326
284
    def end_of_body(self):
327
285
        """No more body data will be received."""
328
286
        self._run_handler_code(self._command.do_end, (), {})
329
287
        # cannot read after this.
330
288
        self.finished_reading = True
331
 
        if 'hpss' in debug.debug_flags:
332
 
            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, {})
333
298
 
334
299
    def _run_handler_code(self, callable, args, kwargs):
335
300
        """Run some handler specific code 'callable'.
364
329
 
365
330
    def headers_received(self, headers):
366
331
        # Just a no-op at the moment.
367
 
        if 'hpss' in debug.debug_flags:
368
 
            self._trace('headers', repr(headers))
 
332
        pass
369
333
 
370
334
    def args_received(self, args):
371
335
        cmd = args[0]
373
337
        try:
374
338
            command = self._commands.get(cmd)
375
339
        except LookupError:
376
 
            if 'hpss' in debug.debug_flags:
377
 
                self._trace('hpss unknown request', 
378
 
                            cmd, repr(args)[1:-1])
379
340
            raise errors.UnknownSmartMethod(cmd)
380
 
        if 'hpss' in debug.debug_flags:
381
 
            from bzrlib.smart import vfs
382
 
            if issubclass(command, vfs.VfsRequest):
383
 
                action = 'hpss vfs req'
384
 
            else:
385
 
                action = 'hpss request'
386
 
            self._trace(action, 
387
 
                        '%s %s' % (cmd, repr(args)[1:-1]))
388
 
        self._command = command(
389
 
            self._backing_transport, self._root_client_path, self._jail_root)
 
341
        self._command = command(self._backing_transport)
390
342
        self._run_handler_code(self._command.execute, args, {})
391
343
 
392
344
    def end_received(self):
393
 
        if self._command is None:
394
 
            # no active command object, so ignore the event.
395
 
            return
396
345
        self._run_handler_code(self._command.do_end, (), {})
397
 
        if 'hpss' in debug.debug_flags:
398
 
            self._trace('end', '', include_time=True)
399
346
 
400
347
    def post_body_error_received(self, error_args):
401
348
        # Just a no-op at the moment.
409
356
        return ('FileExists', err.path)
410
357
    elif isinstance(err, errors.DirectoryNotEmpty):
411
358
        return ('DirectoryNotEmpty', err.path)
412
 
    elif isinstance(err, errors.IncompatibleRepositories):
413
 
        return ('IncompatibleRepositories', str(err.source), str(err.target),
414
 
            str(err.details))
415
359
    elif isinstance(err, errors.ShortReadvError):
416
360
        return ('ShortReadvError', err.path, str(err.offset), str(err.length),
417
361
                str(err.actual))
446
390
    elif isinstance(err, errors.TokenMismatch):
447
391
        return ('TokenMismatch', err.given_token, err.lock_token)
448
392
    elif isinstance(err, errors.LockContention):
449
 
        return ('LockContention',)
450
 
    elif isinstance(err, MemoryError):
451
 
        # GZ 2011-02-24: Copy bzrlib.trace -Dmem_dump functionality here?
452
 
        return ('MemoryError',)
 
393
        return ('LockContention', err.lock, err.msg)
453
394
    # Unserialisable error.  Log it, and return a generic error
454
395
    trace.log_exception_quietly()
455
 
    return ('error', trace._qualified_exception_name(err.__class__, True),
456
 
        str(err))
 
396
    return ('error', str(err))
457
397
 
458
398
 
459
399
class HelloRequest(SmartServerRequest):
503
443
    'Branch.get_tags_bytes', 'bzrlib.smart.branch',
504
444
    'SmartServerBranchGetTagsBytes')
505
445
request_handlers.register_lazy(
506
 
    'Branch.set_tags_bytes', 'bzrlib.smart.branch',
507
 
    'SmartServerBranchSetTagsBytes')
508
 
request_handlers.register_lazy(
509
 
    'Branch.heads_to_fetch', 'bzrlib.smart.branch',
510
 
    'SmartServerBranchHeadsToFetch')
511
 
request_handlers.register_lazy(
512
446
    'Branch.get_stacked_on_url', 'bzrlib.smart.branch', 'SmartServerBranchRequestGetStackedOnURL')
513
447
request_handlers.register_lazy(
514
448
    'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
515
449
request_handlers.register_lazy(
516
450
    'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
517
 
request_handlers.register_lazy( 'Branch.revision_history',
518
 
    'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
519
 
request_handlers.register_lazy( 'Branch.set_config_option',
520
 
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
521
 
request_handlers.register_lazy( 'Branch.set_config_option_dict',
522
 
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOptionDict')
523
 
request_handlers.register_lazy( 'Branch.set_last_revision',
524
 
    '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')
525
455
request_handlers.register_lazy(
526
456
    'Branch.set_last_revision_info', 'bzrlib.smart.branch',
527
457
    'SmartServerBranchRequestSetLastRevisionInfo')
529
459
    'Branch.set_last_revision_ex', 'bzrlib.smart.branch',
530
460
    'SmartServerBranchRequestSetLastRevisionEx')
531
461
request_handlers.register_lazy(
532
 
    'Branch.set_parent_location', 'bzrlib.smart.branch',
533
 
    'SmartServerBranchRequestSetParentLocation')
534
 
request_handlers.register_lazy(
535
462
    'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock')
536
463
request_handlers.register_lazy(
537
464
    'BzrDir.cloning_metadir', 'bzrlib.smart.bzrdir',
552
479
    'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir',
553
480
    'SmartServerRequestFindRepositoryV3')
554
481
request_handlers.register_lazy(
555
 
    'BzrDir.get_config_file', 'bzrlib.smart.bzrdir',
556
 
    'SmartServerBzrDirRequestConfigFile')
557
 
request_handlers.register_lazy(
558
482
    'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir',
559
483
    'SmartServerRequestInitializeBzrDir')
560
484
request_handlers.register_lazy(
561
 
    'BzrDirFormat.initialize_ex_1.16', 'bzrlib.smart.bzrdir',
562
 
    'SmartServerRequestBzrDirInitializeEx')
563
 
request_handlers.register_lazy(
564
 
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')
565
 
request_handlers.register_lazy(
566
 
    'BzrDir.open_2.1', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir_2_1')
567
 
request_handlers.register_lazy(
568
485
    'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
569
486
    'SmartServerRequestOpenBranch')
570
487
request_handlers.register_lazy(
571
488
    'BzrDir.open_branchV2', 'bzrlib.smart.bzrdir',
572
489
    'SmartServerRequestOpenBranchV2')
573
490
request_handlers.register_lazy(
574
 
    'BzrDir.open_branchV3', 'bzrlib.smart.bzrdir',
575
 
    'SmartServerRequestOpenBranchV3')
576
 
request_handlers.register_lazy(
577
491
    'delete', 'bzrlib.smart.vfs', 'DeleteRequest')
578
492
request_handlers.register_lazy(
579
493
    'get', 'bzrlib.smart.vfs', 'GetRequest')
615
529
request_handlers.register_lazy(
616
530
    'Repository.insert_stream', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream')
617
531
request_handlers.register_lazy(
618
 
    'Repository.insert_stream_1.19', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream_1_19')
619
 
request_handlers.register_lazy(
620
532
    'Repository.insert_stream_locked', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStreamLocked')
621
533
request_handlers.register_lazy(
622
534
    'Repository.is_shared', 'bzrlib.smart.repository', 'SmartServerRepositoryIsShared')
628
540
request_handlers.register_lazy(
629
541
    'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock')
630
542
request_handlers.register_lazy(
631
 
    'Repository.get_rev_id_for_revno', 'bzrlib.smart.repository',
632
 
    'SmartServerRepositoryGetRevIdForRevno')
633
 
request_handlers.register_lazy(
634
543
    'Repository.get_stream', 'bzrlib.smart.repository',
635
544
    'SmartServerRepositoryGetStream')
636
545
request_handlers.register_lazy(
637
 
    'Repository.get_stream_1.19', 'bzrlib.smart.repository',
638
 
    'SmartServerRepositoryGetStream_1_19')
639
 
request_handlers.register_lazy(
640
546
    'Repository.tarball', 'bzrlib.smart.repository',
641
547
    'SmartServerRepositoryTarball')
642
548
request_handlers.register_lazy(
645
551
    'stat', 'bzrlib.smart.vfs', 'StatRequest')
646
552
request_handlers.register_lazy(
647
553
    'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly')
 
554
request_handlers.register_lazy(
 
555
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')