~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

Merge from bzr.dev, resolving conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006 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
19
19
 
20
20
import tempfile
21
21
 
22
 
from bzrlib import (
23
 
    bzrdir,
24
 
    errors,
25
 
    registry,
26
 
    revision,
27
 
    )
 
22
from bzrlib import bzrdir, errors, registry, revision
28
23
from bzrlib.bundle.serializer import write_bundle
29
24
 
30
25
 
31
26
class SmartServerRequest(object):
32
 
    """Base class for request handlers."""
 
27
    """Base class for request handlers.
 
28
    """
33
29
 
34
30
    def __init__(self, backing_transport):
35
 
        """Constructor.
36
 
 
37
 
        :param backing_transport: the base transport to be used when performing
38
 
            this request.
39
 
        """
40
31
        self._backing_transport = backing_transport
41
32
 
42
33
    def _check_enabled(self):
77
68
 
78
69
 
79
70
class SmartServerResponse(object):
80
 
    """A response to a client request.
81
 
    
82
 
    This base class should not be used. Instead use
83
 
    SuccessfulSmartServerResponse and FailedSmartServerResponse as appropriate.
84
 
    """
 
71
    """Response generated by SmartServerRequestHandler."""
85
72
 
86
73
    def __init__(self, args, body=None):
87
74
        self.args = args
93
80
        return other.args == self.args and other.body == self.body
94
81
 
95
82
    def __repr__(self):
96
 
        return "<SmartServerResponse args=%r body=%r>" % (self.is_successful(), 
97
 
            self.args, self.body)
98
 
 
99
 
 
100
 
class FailedSmartServerResponse(SmartServerResponse):
101
 
    """A SmartServerResponse for a request which failed."""
102
 
 
103
 
    def is_successful(self):
104
 
        """FailedSmartServerResponse are not successful."""
105
 
        return False
106
 
 
107
 
 
108
 
class SuccessfulSmartServerResponse(SmartServerResponse):
109
 
    """A SmartServerResponse for a successfully completed request."""
110
 
 
111
 
    def is_successful(self):
112
 
        """SuccessfulSmartServerResponse are successful."""
113
 
        return True
 
83
        return "<SmartServerResponse args=%r body=%r>" % (self.args, self.body)
114
84
 
115
85
 
116
86
class SmartServerRequestHandler(object):
192
162
        try:
193
163
            return callable(*args, **kwargs)
194
164
        except errors.NoSuchFile, e:
195
 
            return FailedSmartServerResponse(('NoSuchFile', e.path))
 
165
            return SmartServerResponse(('NoSuchFile', e.path))
196
166
        except errors.FileExists, e:
197
 
            return FailedSmartServerResponse(('FileExists', e.path))
 
167
            return SmartServerResponse(('FileExists', e.path))
198
168
        except errors.DirectoryNotEmpty, e:
199
 
            return FailedSmartServerResponse(('DirectoryNotEmpty', e.path))
 
169
            return SmartServerResponse(('DirectoryNotEmpty', e.path))
200
170
        except errors.ShortReadvError, e:
201
 
            return FailedSmartServerResponse(('ShortReadvError',
 
171
            return SmartServerResponse(('ShortReadvError',
202
172
                e.path, str(e.offset), str(e.length), str(e.actual)))
203
173
        except UnicodeError, e:
204
174
            # If it is a DecodeError, than most likely we are starting
211
181
            else:
212
182
                val = 's:' + str_or_unicode.encode('base64')
213
183
            # This handles UnicodeEncodeError or UnicodeDecodeError
214
 
            return FailedSmartServerResponse((e.__class__.__name__,
 
184
            return SmartServerResponse((e.__class__.__name__,
215
185
                    e.encoding, val, str(e.start), str(e.end), e.reason))
216
186
        except errors.TransportNotPossible, e:
217
187
            if e.msg == "readonly transport":
218
 
                return FailedSmartServerResponse(('ReadOnlyError', ))
 
188
                return SmartServerResponse(('ReadOnlyError', ))
219
189
            else:
220
190
                raise
221
191
 
222
192
 
223
193
class HelloRequest(SmartServerRequest):
224
 
    """Answer a version request with the highest protocol version this server
225
 
    supports.
226
 
    """
 
194
    """Answer a version request with my version."""
227
195
 
228
196
    def do(self):
229
 
        return SuccessfulSmartServerResponse(('ok', '2'))
 
197
        return SmartServerResponse(('ok', '1'))
230
198
 
231
199
 
232
200
class GetBundleRequest(SmartServerRequest):
233
 
    """Get a bundle of from the null revision to the specified revision."""
234
201
 
235
202
    def do(self, path, revision_id):
236
203
        # open transport relative to our base
241
208
        base_revision = revision.NULL_REVISION
242
209
        write_bundle(repo, revision_id, base_revision, tmpf)
243
210
        tmpf.seek(0)
244
 
        return SuccessfulSmartServerResponse((), tmpf.read())
 
211
        return SmartServerResponse((), tmpf.read())
 
212
 
 
213
 
 
214
# This exists solely to help RemoteObjectHacking.  It should be removed
 
215
# eventually.  It should not be considered part of the real smart server
 
216
# protocol!
 
217
class ProbeDontUseRequest(SmartServerRequest):
 
218
 
 
219
    def do(self, path):
 
220
        from bzrlib.bzrdir import BzrDirFormat
 
221
        t = self._backing_transport.clone(path)
 
222
        default_format = BzrDirFormat.get_default_format()
 
223
        real_bzrdir = default_format.open(t, _found=True)
 
224
        try:
 
225
            real_bzrdir._format.probe_transport(t)
 
226
        except (errors.NotBranchError, errors.UnknownFormatError):
 
227
            answer = 'no'
 
228
        else:
 
229
            answer = 'yes'
 
230
        return SmartServerResponse((answer,))
245
231
 
246
232
 
247
233
class SmartServerIsReadonly(SmartServerRequest):
252
238
            answer = 'yes'
253
239
        else:
254
240
            answer = 'no'
255
 
        return SuccessfulSmartServerResponse((answer,))
 
241
        return SmartServerResponse((answer,))
256
242
 
257
243
 
258
244
request_handlers = registry.Registry()
316
302
request_handlers.register_lazy(
317
303
    'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock')
318
304
request_handlers.register_lazy(
319
 
    'Repository.tarball', 'bzrlib.smart.repository',
320
 
    'SmartServerRepositoryTarball')
321
 
request_handlers.register_lazy(
322
305
    'rmdir', 'bzrlib.smart.vfs', 'RmdirRequest')
323
306
request_handlers.register_lazy(
324
307
    'stat', 'bzrlib.smart.vfs', 'StatRequest')
325
308
request_handlers.register_lazy(
326
309
    'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly')
327
310
request_handlers.register_lazy(
328
 
    'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')
 
311
    'probe_dont_use', 'bzrlib.smart.request', 'ProbeDontUseRequest')