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

« back to all changes in this revision

Viewing changes to src/apps/server/__init__.py

  • Committer: mattgiuca
  • Date: 2007-12-18 23:46:54 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:82
server/__init__: Rewrote with a better modular architecture.
    Now obeys white/blacklist and looks in conf to get the interpreter to use.
    (Note: Crufty execute_cgi is still present).

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
from common import (util, studpath)
28
28
import conf
 
29
import conf.app.server
29
30
 
30
31
import functools
31
32
import mimetypes
34
35
 
35
36
def handle(req):
36
37
    """Handler for the Server application which serves pages."""
37
 
 
38
 
    mimetypes.init()
39
 
    (type, encoding) = mimetypes.guess_type(req.path)
40
 
 
41
 
    if type is None:
42
 
        type = 'text/plain'
43
 
 
44
38
    req.write_html_head_foot = False
45
39
 
46
40
    # Get the username of the student whose work we are browsing, and the path
51
45
        # TODO: Nicer 404 message?
52
46
        req.throw_error(req.HTTP_NOT_FOUND)
53
47
 
54
 
    # If this type has a special interpreter, call that instead of just
55
 
    # serving the content.
56
 
    if type in executable_types:
57
 
        return executable_types[type](path, req)
 
48
    serve_file(req, user, path)
 
49
 
 
50
def serve_file(req, owner, filename):
 
51
    """Serves a file, using one of three possibilities: interpreting the file,
 
52
    serving it directly, or denying it and returning a 403 Forbidden error.
 
53
    No return value. Writes to req (possibly throwing a server error exception
 
54
    using req.throw_error).
 
55
    
 
56
    req: An IVLE request object.
 
57
    owner: Username of the user who owns the file being served.
 
58
    filename: Filename in the local file system.
 
59
    """
 
60
 
 
61
    # First get the mime type of this file
 
62
    # (Note that importing common.util has already initialised mime types)
 
63
    (type, _) = mimetypes.guess_type(filename)
 
64
    if type is None:
 
65
        type = conf.app.server.default_mimetype
 
66
 
 
67
    # If this type is to be interpreted
 
68
    if type in conf.app.server.interpreters:
 
69
        interp_name = conf.app.server.interpreters[type]
 
70
        try:
 
71
            # Get the interpreter function object
 
72
            interp_object = interpreter_objects[interp_name]
 
73
        except KeyError:
 
74
            # TODO: Nicer 500 message (this is due to bad configuration in
 
75
            # conf/app/server.py)
 
76
            req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR)
 
77
        interpret_file(req, owner, filename, interp_object)
 
78
 
58
79
    else:
59
 
        req.content_type = type
60
 
        req.sendfile(path)
 
80
        # Otherwise, use the blacklist/whitelist to see if this file should be
 
81
        # served or disallowed
 
82
        if conf.app.server.blacklist_served_filetypes:
 
83
            toserve = type not in conf.app.server.served_filetypes_blacklist
 
84
        else:
 
85
            toserve = type in conf.app.server.served_filetypes_whitelist
 
86
 
 
87
        # toserve or not toserve
 
88
        if not toserve:
 
89
            # TODO: Nicer 403 message
 
90
            req.throw_error(req.HTTP_FORBIDDEN)
 
91
        else:
 
92
            serve_file_direct(req, filename, type)
 
93
 
 
94
def interpret_file(req, owner, filename, interpreter):
 
95
    """Serves a file by interpreting it using one of IVLE's builtin
 
96
    interpreters.
 
97
 
 
98
    req: An IVLE request object.
 
99
    owner: Username of the user who owns the file being served.
 
100
    filename: Filename in the local file system.
 
101
    interpreter: A function object to call.
 
102
    """
 
103
    # Make sure the file exists (otherwise some interpreters may not actually
 
104
    # complain).
 
105
    # Don't test for execute permission, that will only be required for
 
106
    # certain interpreters.
 
107
    if not os.access(filename, os.R_OK):
 
108
        req.throw_error(req.HTTP_NOT_FOUND)
 
109
    return interpreter(filename, req)
 
110
 
 
111
def serve_file_direct(req, filename, type):
 
112
    """Serves a file by directly writing it out to the response.
 
113
 
 
114
    req: An IVLE request object.
 
115
    filename: Filename in the local file system.
 
116
    type: String. Mime type to serve the file with.
 
117
    """
 
118
    if not os.access(filename, os.R_OK):
 
119
        req.throw_error(req.HTTP_NOT_FOUND)
 
120
    req.content_type = type
 
121
    req.sendfile(filename)
61
122
 
62
123
# Used to store mutable data
63
124
class Dummy:
165
226
</body>
166
227
</html>""")
167
228
 
168
 
# Mapping of mime types to executables
 
229
# Mapping of interpreter names (as given in conf/app/server.py) to
 
230
# interpreter functions.
169
231
 
170
 
executable_types = {
171
 
    'text/x-python'
 
232
interpreter_objects = {
 
233
    'cgi-python'
172
234
        : functools.partial(execute_cgi, '/usr/bin/python'),
 
235
    # Should also have:
 
236
    # cgi-generic
 
237
    # python-server-page
173
238
}
174
239