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
17
"""Basic server-side logic for dealing with requests.
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.
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
17
"""Infrastructure for server-side request handlers.
19
Interesting module attributes:
20
* The request_handlers registry maps verb names to SmartServerRequest
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).
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.
31
37
from bzrlib import (
51
jail_info = threading.local()
52
jail_info.transports = None
56
bzrdir.BzrDir.hooks.install_named_hook(
57
'pre_open', _pre_open_hook, 'checking server jail')
60
def _pre_open_hook(transport):
61
allowed_transports = getattr(jail_info, 'transports', None)
62
if allowed_transports is None:
64
abspath = transport.base
65
for allowed_transport in allowed_transports:
67
allowed_transport.relpath(abspath)
68
except errors.PathNotChild:
72
raise errors.JailBreak(abspath)
45
78
class SmartServerRequest(object):
46
79
"""Base class for request handlers.
121
154
self._body_chunks = None
122
155
return self.do_body(body_bytes)
157
def setup_jail(self):
158
jail_info.transports = [self._backing_transport]
160
def teardown_jail(self):
161
jail_info.transports = None
124
163
def translate_client_path(self, client_path):
125
164
"""Translate a path received from a network client into a local
137
176
return client_path
138
177
if not client_path.startswith('/'):
139
178
client_path = '/' + client_path
179
if client_path + '/' == self._root_client_path:
140
181
if client_path.startswith(self._root_client_path):
141
182
path = client_path[len(self._root_client_path):]
142
183
relpath = urlutils.joinpath('/', path)
277
318
# XXX: most of this error conversion is VFS-related, and thus ought to
278
319
# be in SmartServerVFSRequestHandler somewhere.
280
return callable(*args, **kwargs)
321
self._command.setup_jail()
323
return callable(*args, **kwargs)
325
self._command.teardown_jail()
281
326
except (KeyboardInterrupt, SystemExit):
283
328
except Exception, err:
405
450
'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
406
451
request_handlers.register_lazy(
407
452
'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
408
request_handlers.register_lazy(
409
'Branch.revision_history', 'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
410
request_handlers.register_lazy(
411
'Branch.set_last_revision', 'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
453
request_handlers.register_lazy( 'Branch.revision_history',
454
'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
455
request_handlers.register_lazy( 'Branch.set_config_option',
456
'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
457
request_handlers.register_lazy( 'Branch.set_last_revision',
458
'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
412
459
request_handlers.register_lazy(
413
460
'Branch.set_last_revision_info', 'bzrlib.smart.branch',
414
461
'SmartServerBranchRequestSetLastRevisionInfo')
416
463
'Branch.set_last_revision_ex', 'bzrlib.smart.branch',
417
464
'SmartServerBranchRequestSetLastRevisionEx')
418
465
request_handlers.register_lazy(
466
'Branch.set_parent_location', 'bzrlib.smart.branch',
467
'SmartServerBranchRequestSetParentLocation')
468
request_handlers.register_lazy(
419
469
'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock')
420
470
request_handlers.register_lazy(
421
471
'BzrDir.cloning_metadir', 'bzrlib.smart.bzrdir',
436
486
'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir',
437
487
'SmartServerRequestFindRepositoryV3')
438
488
request_handlers.register_lazy(
489
'BzrDir.get_config_file', 'bzrlib.smart.bzrdir',
490
'SmartServerBzrDirRequestConfigFile')
491
request_handlers.register_lazy(
439
492
'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir',
440
493
'SmartServerRequestInitializeBzrDir')
441
494
request_handlers.register_lazy(
495
'BzrDirFormat.initialize_ex', 'bzrlib.smart.bzrdir',
496
'SmartServerRequestBzrDirInitializeEx')
497
request_handlers.register_lazy(
498
'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')
499
request_handlers.register_lazy(
442
500
'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
443
501
'SmartServerRequestOpenBranch')
444
502
request_handlers.register_lazy(
508
566
'stat', 'bzrlib.smart.vfs', 'StatRequest')
509
567
request_handlers.register_lazy(
510
568
'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly')
511
request_handlers.register_lazy(
512
'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir')