~abentley/bzr/cp-4470

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2009-04-24 16:44:16 UTC
  • mfrom: (3995.123.151 1.14)
  • Revision ID: launchpad@pqm.canonical.com-20090424164416-xkbn2oygg227p6z2
[rs=jml] Upgrade Bazaar to 1.14rc2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
"""Basic server-side logic for dealing with requests.
18
 
 
19
 
**XXX**:
20
 
 
21
 
The class names are a little confusing: the protocol will instantiate a
22
 
SmartServerRequestHandler, whose dispatch_command method creates an instance of
23
 
a SmartServerRequest subclass.
24
 
 
25
 
The request_handlers registry tracks SmartServerRequest classes (rather than
26
 
SmartServerRequestHandler).
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Infrastructure for server-side request handlers.
 
18
 
 
19
Interesting module attributes:
 
20
    * The request_handlers registry maps verb names to SmartServerRequest
 
21
      classes.
 
22
    * The jail_info threading.local() object is used to prevent accidental
 
23
      opening of BzrDirs outside of the backing transport, or any other
 
24
      transports placed in jail_info.transports.  The jail_info is reset on
 
25
      every call into a request handler (which can happen an arbitrary number
 
26
      of times during a request).
27
27
"""
28
28
 
 
29
# XXX: The class names are a little confusing: the protocol will instantiate a
 
30
# SmartServerRequestHandler, whose dispatch_command method creates an instance
 
31
# of a SmartServerRequest subclass.
 
32
 
 
33
 
29
34
import tempfile
 
35
import threading
30
36
 
31
37
from bzrlib import (
32
38
    bzrdir,
42
48
""")
43
49
 
44
50
 
 
51
jail_info = threading.local()
 
52
jail_info.transports = None
 
53
 
 
54
 
 
55
def _install_hook():
 
56
    bzrdir.BzrDir.hooks.install_named_hook(
 
57
        'pre_open', _pre_open_hook, 'checking server jail')
 
58
 
 
59
 
 
60
def _pre_open_hook(transport):
 
61
    allowed_transports = getattr(jail_info, 'transports', None)
 
62
    if allowed_transports is None:
 
63
        return
 
64
    abspath = transport.base
 
65
    for allowed_transport in allowed_transports:
 
66
        try:
 
67
            allowed_transport.relpath(abspath)
 
68
        except errors.PathNotChild:
 
69
            continue
 
70
        else:
 
71
            return
 
72
    raise errors.BzrError('jail break: %r' % (abspath,))
 
73
 
 
74
 
 
75
_install_hook()
 
76
 
 
77
 
45
78
class SmartServerRequest(object):
46
79
    """Base class for request handlers.
47
80
 
121
154
        self._body_chunks = None
122
155
        return self.do_body(body_bytes)
123
156
 
 
157
    def setup_jail(self):
 
158
        jail_info.transports = [self._backing_transport]
 
159
 
 
160
    def teardown_jail(self):
 
161
        jail_info.transports = None
 
162
 
124
163
    def translate_client_path(self, client_path):
125
164
        """Translate a path received from a network client into a local
126
165
        relpath.
277
316
        # XXX: most of this error conversion is VFS-related, and thus ought to
278
317
        # be in SmartServerVFSRequestHandler somewhere.
279
318
        try:
280
 
            return callable(*args, **kwargs)
 
319
            self._command.setup_jail()
 
320
            try:
 
321
                return callable(*args, **kwargs)
 
322
            finally:
 
323
                self._command.teardown_jail()
281
324
        except (KeyboardInterrupt, SystemExit):
282
325
            raise
283
326
        except Exception, err:
344
387
        return ('ReadError', err.path)
345
388
    elif isinstance(err, errors.PermissionDenied):
346
389
        return ('PermissionDenied', err.path, err.extra)
 
390
    elif isinstance(err, errors.TokenMismatch):
 
391
        return ('TokenMismatch', err.given_token, err.lock_token)
 
392
    elif isinstance(err, errors.LockContention):
 
393
        return ('LockContention', err.lock, err.msg)
347
394
    # Unserialisable error.  Log it, and return a generic error
348
395
    trace.log_exception_quietly()
349
396
    return ('error', str(err))
401
448
    'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
402
449
request_handlers.register_lazy(
403
450
    'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
404
 
request_handlers.register_lazy(
405
 
    'Branch.revision_history', 'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
406
 
request_handlers.register_lazy(
407
 
    'Branch.set_last_revision', 'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
 
451
request_handlers.register_lazy( 'Branch.revision_history',
 
452
    'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
 
453
request_handlers.register_lazy( 'Branch.set_config_option',
 
454
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
 
455
request_handlers.register_lazy( 'Branch.set_last_revision',
 
456
    'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
408
457
request_handlers.register_lazy(
409
458
    'Branch.set_last_revision_info', 'bzrlib.smart.branch',
410
459
    'SmartServerBranchRequestSetLastRevisionInfo')
482
531
request_handlers.register_lazy(
483
532
    'Repository.insert_stream', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStream')
484
533
request_handlers.register_lazy(
 
534
    'Repository.insert_stream_locked', 'bzrlib.smart.repository', 'SmartServerRepositoryInsertStreamLocked')
 
535
request_handlers.register_lazy(
485
536
    'Repository.is_shared', 'bzrlib.smart.repository', 'SmartServerRepositoryIsShared')
486
537
request_handlers.register_lazy(
487
538
    'Repository.lock_write', 'bzrlib.smart.repository', 'SmartServerRepositoryLockWrite')