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

93 by mattgiuca
New directory hierarchy.
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2008 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# Module: dispatch.request
19
# Author: Matt Giuca
20
# Date:   12/12/2007
21
22
# Builds an IVLE request object from a mod_python request object.
23
# See design notes/apps/dispatch.txt for a full specification of this request
24
# object.
25
26
import common.util
27
import mod_python
124 by mattgiuca
dispatch/request: Added new fields: method and username.
28
from mod_python import (util, Session)
259 by mattgiuca
setup.py: Added a new config variable "public_host", which lets the admin set
29
import conf
93 by mattgiuca
New directory hierarchy.
30
31
class Request:
32
    """An IVLE request object. This is presented to the IVLE apps as a way of
33
    interacting with the web server and the dispatcher.
34
35
    Request object attributes:
124 by mattgiuca
dispatch/request: Added new fields: method and username.
36
        method (read)
37
            String. The request method (eg. 'GET', 'POST', etc)
93 by mattgiuca
New directory hierarchy.
38
        uri (read)
39
            String. The path portion of the URI.
40
        app (read)
41
            String. Name of the application specified in the URL, or None.
42
        path (read)
43
            String. The path specified in the URL *not including* the
44
            application or the IVLE location prefix. eg. a URL of
45
            "/ivle/files/joe/myfiles" has a path of "joe/myfiles".
124 by mattgiuca
dispatch/request: Added new fields: method and username.
46
        username (read)
47
            String. Login name of the user who is currently logged in, or
48
            None.
255 by mattgiuca
dispatch.request: Added "hostname" field.
49
        hostname (read)
50
            String. Hostname the server is running on.
142 by mattgiuca
dispatch.request: Added headers_in and headers_out as readable (and
51
        headers_in (read)
52
            Table object representing headers sent by the client.
53
        headers_out (read, can be written to)
54
            Table object representing headers to be sent to the client.
259 by mattgiuca
setup.py: Added a new config variable "public_host", which lets the admin set
55
        publicmode (read)
56
            Bool. True if the request came for the "public host" as
57
            configured in conf.py. Note that public mode requests do not
58
            have an app (app is set to None).
93 by mattgiuca
New directory hierarchy.
59
60
        status (write)
61
            Int. Response status number. Use one of the status codes defined
62
            in class Request.
63
        content_type (write)
64
            String. The Content-Type (mime type) header value.
65
        location (write)
66
            String. Response "Location" header value. Used with HTTP redirect
67
            responses.
68
        title (write)
69
            String. HTML page title. Used if write_html_head_foot is True, in
70
            the HTML title element text.
169 by mattgiuca
Added global common css file (media/common/ivle.css).
71
        styles (write)
72
            List of strings. Write a list of URLs to CSS files here, and they
73
            will be incorporated as <link rel="stylesheet" type="text/css">
74
            elements in the head, if write_html_head_foot is True.
75
            URLs should be relative to the IVLE root; they will be fixed up
76
            to be site-relative.
77
        scripts (write)
78
            List of strings. Write a list of URLs to JS files here, and they
79
            will be incorporated as <script type="text/javascript"> elements
80
            in the head, if write_html_head_foot is True.
81
            URLs should be relative to the IVLE root; they will be fixed up
82
            to be site-relative.
93 by mattgiuca
New directory hierarchy.
83
        write_html_head_foot (write)
84
            Boolean. If True, dispatch assumes that this is an XHTML page, and
85
            will immediately write a full HTML head, open the body element,
86
            and write heading contents to the page, before any bytes are
87
            written. It will then write footer contents and close the body and
88
            html elements at the end of execution.  
89
90
            This value should be set to true by all applications for all HTML
91
            output (unless there is a good reason, eg. exec). The
92
            applications should therefore output HTML content assuming that
93
            it will be written inside the body tag. Do not write opening or
94
            closing <html> or <body> tags.
95
    """
96
97
    # Special code for an OK response.
98
    # Do not use HTTP_OK; for some reason Apache produces an "OK" error
99
    # message if you do that.
100
    OK  = 0
101
102
    # HTTP status codes
103
104
    HTTP_CONTINUE                     = 100
105
    HTTP_SWITCHING_PROTOCOLS          = 101
106
    HTTP_PROCESSING                   = 102
107
    HTTP_OK                           = 200
108
    HTTP_CREATED                      = 201
109
    HTTP_ACCEPTED                     = 202
110
    HTTP_NON_AUTHORITATIVE            = 203
111
    HTTP_NO_CONTENT                   = 204
112
    HTTP_RESET_CONTENT                = 205
113
    HTTP_PARTIAL_CONTENT              = 206
114
    HTTP_MULTI_STATUS                 = 207
115
    HTTP_MULTIPLE_CHOICES             = 300
116
    HTTP_MOVED_PERMANENTLY            = 301
117
    HTTP_MOVED_TEMPORARILY            = 302
118
    HTTP_SEE_OTHER                    = 303
119
    HTTP_NOT_MODIFIED                 = 304
120
    HTTP_USE_PROXY                    = 305
121
    HTTP_TEMPORARY_REDIRECT           = 307
122
    HTTP_BAD_REQUEST                  = 400
123
    HTTP_UNAUTHORIZED                 = 401
124
    HTTP_PAYMENT_REQUIRED             = 402
125
    HTTP_FORBIDDEN                    = 403
126
    HTTP_NOT_FOUND                    = 404
127
    HTTP_METHOD_NOT_ALLOWED           = 405
128
    HTTP_NOT_ACCEPTABLE               = 406
129
    HTTP_PROXY_AUTHENTICATION_REQUIRED= 407
130
    HTTP_REQUEST_TIME_OUT             = 408
131
    HTTP_CONFLICT                     = 409
132
    HTTP_GONE                         = 410
133
    HTTP_LENGTH_REQUIRED              = 411
134
    HTTP_PRECONDITION_FAILED          = 412
135
    HTTP_REQUEST_ENTITY_TOO_LARGE     = 413
136
    HTTP_REQUEST_URI_TOO_LARGE        = 414
137
    HTTP_UNSUPPORTED_MEDIA_TYPE       = 415
138
    HTTP_RANGE_NOT_SATISFIABLE        = 416
139
    HTTP_EXPECTATION_FAILED           = 417
140
    HTTP_UNPROCESSABLE_ENTITY         = 422
141
    HTTP_LOCKED                       = 423
142
    HTTP_FAILED_DEPENDENCY            = 424
143
    HTTP_INTERNAL_SERVER_ERROR        = 500
144
    HTTP_NOT_IMPLEMENTED              = 501
145
    HTTP_BAD_GATEWAY                  = 502
146
    HTTP_SERVICE_UNAVAILABLE          = 503
147
    HTTP_GATEWAY_TIME_OUT             = 504
148
    HTTP_VERSION_NOT_SUPPORTED        = 505
149
    HTTP_VARIANT_ALSO_VARIES          = 506
150
    HTTP_INSUFFICIENT_STORAGE         = 507
151
    HTTP_NOT_EXTENDED                 = 510
152
153
    def __init__(self, req, write_html_head):
154
        """Builds an IVLE request object from a mod_python request object.
155
        This results in an object with all of the necessary methods and
156
        additional fields.
157
158
        req: A mod_python request object.
159
        write_html_head: Function which is called when writing the automatic
160
            HTML header. Accepts a single argument, the IVLE request object.
161
        """
162
163
        # Methods are mostly wrappers around the Apache request object
164
        self.apache_req = req
165
        self.func_write_html_head = write_html_head
166
        self.headers_written = False
167
259 by mattgiuca
setup.py: Added a new config variable "public_host", which lets the admin set
168
        # Determine if the browser used the public host name to make the
169
        # request (in which case we are in "public mode")
170
        if req.hostname == conf.public_host:
171
            self.publicmode = True
172
        else:
173
            self.publicmode = False
174
93 by mattgiuca
New directory hierarchy.
175
        # Inherit values for the input members
124 by mattgiuca
dispatch/request: Added new fields: method and username.
176
        self.method = req.method
93 by mattgiuca
New directory hierarchy.
177
        self.uri = req.uri
178
        # Split the given path into the app (top-level dir) and sub-path
179
        # (after first stripping away the root directory)
259 by mattgiuca
setup.py: Added a new config variable "public_host", which lets the admin set
180
        path = common.util.unmake_path(req.uri)
181
        if self.publicmode:
182
            self.app = None
183
            self.path = path
184
        else:
185
            (self.app, self.path) = (common.util.split_path(path))
124 by mattgiuca
dispatch/request: Added new fields: method and username.
186
        self.username = None
255 by mattgiuca
dispatch.request: Added "hostname" field.
187
        self.hostname = req.hostname
142 by mattgiuca
dispatch.request: Added headers_in and headers_out as readable (and
188
        self.headers_in = req.headers_in
189
        self.headers_out = req.headers_out
93 by mattgiuca
New directory hierarchy.
190
191
        # Default values for the output members
145 by mattgiuca
fileservice: Removed bad setting of response status to req.OK (this was
192
        self.status = Request.HTTP_OK
93 by mattgiuca
New directory hierarchy.
193
        self.content_type = None        # Use Apache's default
194
        self.location = None
195
        self.title = None     # Will be set by dispatch before passing to app
169 by mattgiuca
Added global common css file (media/common/ivle.css).
196
        self.styles = []
197
        self.scripts = []
93 by mattgiuca
New directory hierarchy.
198
        self.write_html_head_foot = False
247 by mattgiuca
request.py: Added get_cgi_environ method. This asks Apache to emulate CGI
199
        self.got_common_vars = False
93 by mattgiuca
New directory hierarchy.
200
201
    def __writeheaders(self):
202
        """Writes out the HTTP and HTML headers before any real data is
203
        written."""
204
        self.headers_written = True
205
        # Prepare the HTTP and HTML headers before the first write is made
206
        if self.content_type != None:
207
            self.apache_req.content_type = self.content_type
208
        self.apache_req.status = self.status
209
        if self.location != None:
210
            self.apache_req.headers_out['Location'] = self.location
211
        if self.write_html_head_foot:
212
            # Write the HTML header, pass "self" (request object)
213
            self.func_write_html_head(self)
214
215
    def ensure_headers_written(self):
216
        """Writes out the HTTP and HTML headers if they haven't already been
217
        written."""
218
        if not self.headers_written:
219
            self.__writeheaders()
220
221
    def write(self, string, flush=1):
222
        """Writes string directly to the client, then flushes the buffer,
223
        unless flush is 0."""
224
225
        if not self.headers_written:
226
            self.__writeheaders()
227
        self.apache_req.write(string, flush)
228
229
    def flush(self):
230
        """Flushes the output buffer."""
231
        self.apache_req.flush()
232
233
    def sendfile(self, filename):
234
        """Sends the named file directly to the client."""
235
        if not self.headers_written:
236
            self.__writeheaders()
237
        self.apache_req.sendfile(filename)
238
239
    def read(self, len=None):
240
        """Reads at most len bytes directly from the client. (See mod_python
241
        Request.read)."""
242
        if len is None:
246 by mattgiuca
request.py: Fixed Request.read (wasn't returning anything).
243
            return self.apache_req.read()
93 by mattgiuca
New directory hierarchy.
244
        else:
246 by mattgiuca
request.py: Fixed Request.read (wasn't returning anything).
245
            return self.apache_req.read(len)
93 by mattgiuca
New directory hierarchy.
246
247
    def throw_error(self, httpcode):
248
        """Writes out an HTTP error of the specified code. Raises an exception
249
        which is caught by the dispatch or web server, so any code following
250
        this call will not be executed.
251
252
        httpcode: An HTTP response status code. Pass a constant from the
253
        Request class.
254
        """
255
        raise mod_python.apache.SERVER_RETURN, httpcode
256
257
    def throw_redirect(self, location):
258
        """Writes out an HTTP redirect to the specified URL. Raises an
259
        exception which is caught by the dispatch or web server, so any
260
        code following this call will not be executed.
261
262
        httpcode: An HTTP response status code. Pass a constant from the
263
        Request class.
264
        """
265
        mod_python.util.redirect(self.apache_req, location)
124 by mattgiuca
dispatch/request: Added new fields: method and username.
266
267
    def get_session(self):
268
        """Returns a mod_python Session object for this request.
269
        Note that this is dependent on mod_python and may need to change
270
        interface if porting away from mod_python."""
271
        # Cache the session object
272
        if not hasattr(self, 'session'):
273
            self.session = Session.Session(self.apache_req)
274
        return self.session
275
276
    def get_fieldstorage(self):
277
        """Returns a mod_python FieldStorage object for this request.
278
        Note that this is dependent on mod_python and may need to change
279
        interface if porting away from mod_python."""
280
        # Cache the fieldstorage object
281
        if not hasattr(self, 'fields'):
282
            self.fields = util.FieldStorage(self.apache_req)
283
        return self.fields
247 by mattgiuca
request.py: Added get_cgi_environ method. This asks Apache to emulate CGI
284
285
    def get_cgi_environ(self):
286
        """Returns the CGI environment emulation for this request. (Calls
287
        add_common_vars). The environment is returned as a mapping
288
        compatible with os.environ."""
289
        if not self.got_common_vars:
290
            self.apache_req.add_common_vars()
291
            self.got_common_vars = True
292
        return self.apache_req.subprocess_env