483
484
raise ExecutionError('subprocess ended with code %d, stderr: "%s"' %
484
485
(exitcode, stderr))
485
486
return (stdout, stderr)
488
def jail_call(req, cgi_script, script_name, query_string=None,
489
request_method="GET", extra_overrides=None):
491
Makes a call to a CGI script inside the jail from outside the jail.
492
This can be used to allow Python scripts to access jail-only functions and
493
data without having to perform a full API request.
495
req: A Request object (will not be written to or attributes modified).
496
cgi_script: Path to cgi script outside of jail.
497
eg: os.path.join(req.config['paths']['share'],
498
'services/fileservice')
499
script_name: Name to set as SCRIPT_NAME for the CGI environment.
501
query_string: Query string to set as QUERY_STRING for the CGI environment.
502
eg: "action=svnrepostat&path=/users/studenta/"
503
request_method: Method to set as REQUEST_METHOD for the CGI environment.
504
eg: "POST". Defaults to "GET".
505
extra_overrides: A dict mapping env var names to strings, to override
506
arbitrary environment variables in the resulting CGI environent.
508
Returns a triple (status_code, content_type, contents).
510
interp_object = interpreter_objects["cgi-python"]
511
user_jail_dir = os.path.join(req.config['paths']['jails']['mounts'],
514
"SCRIPT_NAME": script_name,
515
"QUERY_STRING": query_string,
516
"REQUEST_URI": "%s%s%s" % (script_name, "?" if query_string else "",
518
"REQUEST_METHOD": request_method,
520
if extra_overrides is not None:
521
overrides.update(extra_overrides)
522
result = DummyReq(req)
523
interpret_file(result, req.user, user_jail_dir, cgi_script, interp_object,
524
gentle=False, overrides=overrides)
525
return result.status, result.content_type, result.getvalue()
527
class DummyReq(StringIO.StringIO):
528
"""A dummy request object, built from a real request object, which can be
529
used like a req but doesn't mutate the existing request.
530
(Used for reading CGI responses as strings rather than forwarding their
531
output to the current request.)
533
def __init__(self, req):
534
StringIO.StringIO.__init__(self)
536
def get_cgi_environ(self):
537
return self._real_req.get_cgi_environ()
538
def __getattr__(self, name):
539
return getattr(self._real_req, name)