~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/interpret.py

  • Committer: Matt Giuca
  • Date: 2010-07-20 05:45:41 UTC
  • Revision ID: matt.giuca@gmail.com-20100720054541-953ltb8rlo2vxhvq
ivle.interpret: Added 'jail_call' function, which allows regular IVLE web app code to call jail CGI functions and get their contents.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
import pwd
32
32
import subprocess
33
33
import cgi
 
34
import StringIO
34
35
 
35
36
# TODO: Make progressive output work
36
37
# Question: Will having a large buffer size stop progressive output from
483
484
        raise ExecutionError('subprocess ended with code %d, stderr: "%s"' %
484
485
                             (exitcode, stderr))
485
486
    return (stdout, stderr)
 
487
 
 
488
def jail_call(req, cgi_script, script_name, query_string=None,
 
489
    request_method="GET", extra_overrides=None):
 
490
    """
 
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.
 
494
 
 
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.
 
500
        eg: "/fileservice/"
 
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.
 
507
 
 
508
    Returns a triple (status_code, content_type, contents).
 
509
    """
 
510
    interp_object = interpreter_objects["cgi-python"]
 
511
    user_jail_dir = os.path.join(req.config['paths']['jails']['mounts'],
 
512
                                 req.user.login)
 
513
    overrides = {
 
514
        "SCRIPT_NAME": script_name,
 
515
        "QUERY_STRING": query_string,
 
516
        "REQUEST_URI": "%s%s%s" % (script_name, "?" if query_string else "",
 
517
                                   query_string),
 
518
        "REQUEST_METHOD": request_method,
 
519
    }
 
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()
 
526
 
 
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.)
 
532
    """
 
533
    def __init__(self, req):
 
534
        StringIO.StringIO.__init__(self)
 
535
        self._real_req = req
 
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)