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

« back to all changes in this revision

Viewing changes to ivle/dispatch/request.py

  • Committer: William Grant
  • Date: 2009-05-28 02:43:56 UTC
  • Revision ID: grantw@unimelb.edu.au-20090528024356-mlrhizz7omnr71hd
Test ivle.mimetypes.nice_filetype.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
object.
26
26
"""
27
27
 
28
 
import mod_python
29
 
from mod_python import (util, Session, Cookie)
 
28
try:
 
29
    import mod_python.Session
 
30
    import mod_python.Cookie
 
31
    import mod_python.util
 
32
except ImportError:
 
33
    # This needs to be importable from outside Apache.
 
34
    pass
 
35
 
 
36
import os.path
30
37
 
31
38
import ivle.util
32
 
import ivle.conf
33
39
import ivle.database
34
 
import plugins.console # XXX: Relies on www/ being in the Python path.
 
40
from ivle.webapp.base.plugins import CookiePlugin
35
41
 
36
42
class Request:
37
43
    """An IVLE request object. This is presented to the IVLE apps as a way of
73
79
        location (write)
74
80
            String. Response "Location" header value. Used with HTTP redirect
75
81
            responses.
76
 
        title (write)
77
 
            String. HTML page title. Used if write_html_head_foot is True, in
78
 
            the HTML title element text.
79
82
        styles (write)
80
83
            List of strings. Write a list of URLs to CSS files here, and they
81
84
            will be incorporated as <link rel="stylesheet" type="text/css">
94
97
            in the head, if write_html_head_foot is True.
95
98
            This is the propper way to specify functions that need to run at 
96
99
            page load time.
97
 
        write_html_head_foot (write)
98
 
            Boolean. If True, dispatch assumes that this is an XHTML page, and
99
 
            will immediately write a full HTML head, open the body element,
100
 
            and write heading contents to the page, before any bytes are
101
 
            written. It will then write footer contents and close the body and
102
 
            html elements at the end of execution.  
103
 
 
104
 
            This value should be set to true by all applications for all HTML
105
 
            output (unless there is a good reason, eg. exec). The
106
 
            applications should therefore output HTML content assuming that
107
 
            it will be written inside the body tag. Do not write opening or
108
 
            closing <html> or <body> tags.
109
100
    """
110
101
 
111
102
    # Special code for an OK response.
164
155
    HTTP_INSUFFICIENT_STORAGE         = 507
165
156
    HTTP_NOT_EXTENDED                 = 510
166
157
 
167
 
    def __init__(self, req, write_html_head):
168
 
        """Builds an IVLE request object from a mod_python request object.
169
 
        This results in an object with all of the necessary methods and
170
 
        additional fields.
 
158
    def __init__(self, req, config):
 
159
        """Create an IVLE request from a mod_python one.
171
160
 
172
 
        req: A mod_python request object.
173
 
        write_html_head: Function which is called when writing the automatic
174
 
            HTML header. Accepts a single argument, the IVLE request object.
 
161
        @param req: A mod_python request.
 
162
        @param config: An IVLE configuration.
175
163
        """
176
164
 
177
165
        # Methods are mostly wrappers around the Apache request object
178
166
        self.apache_req = req
179
 
        self.func_write_html_head = write_html_head
 
167
        self.config = config
180
168
        self.headers_written = False
181
169
 
182
170
        # Determine if the browser used the public host name to make the
183
171
        # request (in which case we are in "public mode")
184
 
        if req.hostname == ivle.conf.public_host:
 
172
        if req.hostname == config['urls']['public_host']:
185
173
            self.publicmode = True
186
174
        else:
187
175
            self.publicmode = False
191
179
        self.uri = req.uri
192
180
        # Split the given path into the app (top-level dir) and sub-path
193
181
        # (after first stripping away the root directory)
194
 
        path = ivle.util.unmake_path(req.uri)
 
182
        path = self.unmake_path(req.uri)
195
183
        (self.app, self.path) = (ivle.util.split_path(path))
196
184
        self.user = None
197
185
        self.hostname = req.hostname
200
188
 
201
189
        # Open a database connection and transaction, keep it around for users
202
190
        # of the Request object to use
203
 
        self.store = ivle.database.get_store()
 
191
        self.store = ivle.database.get_store(config)
204
192
 
205
193
        # Default values for the output members
206
194
        self.status = Request.HTTP_OK
207
195
        self.content_type = None        # Use Apache's default
208
196
        self.location = None
209
 
        self.title = None     # Will be set by dispatch before passing to app
210
197
        self.styles = []
211
198
        self.scripts = []
212
199
        self.scripts_init = []
213
 
        self.write_html_head_foot = False
214
200
        # In some cases we don't want the template JS (such as the username
215
201
        # and public FQDN) in the output HTML. In that case, set this to 0.
216
202
        self.write_javascript_settings = True
224
210
        """Writes out the HTTP and HTML headers before any real data is
225
211
        written."""
226
212
        self.headers_written = True
227
 
        
228
 
        # app is the App object for the chosen app
229
 
        try:
230
 
            app = ivle.conf.apps.app_url[self.app]
231
 
        except KeyError:
232
 
            app = None
233
 
 
234
 
        # Write any final modifications to header content
235
 
        if app and app.useconsole and self.user:
236
 
            plugins.console.insert_scripts_styles(self.scripts, self.styles, \
237
 
                self.scripts_init)
238
213
 
239
214
        # Prepare the HTTP and HTML headers before the first write is made
240
215
        if self.content_type != None:
242
217
        self.apache_req.status = self.status
243
218
        if self.location != None:
244
219
            self.apache_req.headers_out['Location'] = self.location
245
 
        if self.write_html_head_foot:
246
 
            # Write the HTML header, pass "self" (request object)
247
 
            self.func_write_html_head(self)
248
220
 
249
221
    def ensure_headers_written(self):
250
222
        """Writes out the HTTP and HTML headers if they haven't already been
270
242
    def logout(self):
271
243
        """Log out the current user by destroying the session state.
272
244
        Then redirect to the top-level IVLE page."""
273
 
        # List of cookies that IVLE uses (to be removed at logout)
274
 
        ivle_cookies = ["ivleforumcookie", "clipboard"]
275
 
        
276
245
        if hasattr(self, 'session'):
277
246
            self.session.invalidate()
278
247
            self.session.delete()
279
248
            # Invalidates all IVLE cookies
280
 
            all_cookies = Cookie.get_cookies(self)
281
 
            for cookie in all_cookies:
282
 
                if cookie in ivle_cookies:
283
 
                    self.add_cookie(Cookie.Cookie(cookie,'',expires=1,path='/'))
284
 
        self.throw_redirect(ivle.util.make_path('')) 
 
249
            all_cookies = mod_python.Cookie.get_cookies(self)
 
250
 
 
251
            # Create cookies for plugins that might request them.
 
252
            for plugin in self.config.plugin_index[CookiePlugin]:
 
253
                for cookie in plugin.cookies:
 
254
                    self.add_cookie(mod_python.Cookie.Cookie(cookie, '',
 
255
                                                    expires=1, path='/'))
 
256
        self.throw_redirect(self.make_path(''))
285
257
 
286
258
 
287
259
    def flush(self):
302
274
        else:
303
275
            return self.apache_req.read(len)
304
276
 
305
 
    def throw_error(self, httpcode, message=None):
306
 
        """Writes out an HTTP error of the specified code. Raises an exception
307
 
        which is caught by the dispatch or web server, so any code following
308
 
        this call will not be executed.
309
 
 
310
 
        httpcode: An HTTP response status code. Pass a constant from the
311
 
        Request class.
312
 
        """
313
 
        raise ivle.util.IVLEError(httpcode, message)
314
 
 
315
277
    def throw_redirect(self, location):
316
278
        """Writes out an HTTP redirect to the specified URL. Raises an
317
279
        exception which is caught by the dispatch or web server, so any
327
289
    def add_cookie(self, cookie, value=None, **attributes):
328
290
        """Inserts a cookie into this request object's headers."""
329
291
        if value is None:
330
 
            Cookie.add_cookie(self.apache_req, cookie)
 
292
            mod_python.Cookie.add_cookie(self.apache_req, cookie)
331
293
        else:
332
 
            Cookie.add_cookie(self.apache_req, cookie, value, **attributes)
 
294
            mod_python.Cookie.add_cookie(self.apache_req, cookie, value, **attributes)
 
295
 
 
296
    def make_path(self, path):
 
297
        """Prepend the IVLE URL prefix to the given path.
 
298
 
 
299
        This is used when generating URLs to send to the client.
 
300
 
 
301
        This method is DEPRECATED. We no longer support use of a prefix.
 
302
        """
 
303
        return os.path.join(self.config['urls']['root'], path)
 
304
 
 
305
    def unmake_path(self, path):
 
306
        """Strip the IVLE URL prefix from the given path, if present.
 
307
 
 
308
        Also normalises the path.
 
309
 
 
310
        This method is DEPRECATED. We no longer support use of a prefix.
 
311
        """
 
312
        path = os.path.normpath(path)
 
313
        root = os.path.normpath(self.config['urls']['root'])
 
314
 
 
315
        if path.startswith(root):
 
316
            path = path[len(root):]
 
317
            # Take out the slash as well
 
318
            if len(path) > 0 and path[0] == os.sep:
 
319
                path = path[1:]
 
320
 
 
321
        return path
333
322
 
334
323
    def get_session(self):
335
324
        """Returns a mod_python Session object for this request.
336
325
        Note that this is dependent on mod_python and may need to change
337
 
        interface if porting away from mod_python."""
 
326
        interface if porting away from mod_python.
 
327
 
 
328
        IMPORTANT: Call unlock() on the session as soon as you are done with
 
329
                   it! If you don't, all other requests will block!
 
330
        """
338
331
        # Cache the session object and set the timeout to 24 hours.
339
332
        if not hasattr(self, 'session'):
340
 
            self.session = Session.FileSession(self.apache_req,
 
333
            self.session = mod_python.Session.FileSession(self.apache_req,
341
334
                                               timeout = 60 * 60 * 24)
342
335
        return self.session
343
336
 
347
340
        interface if porting away from mod_python."""
348
341
        # Cache the fieldstorage object
349
342
        if not hasattr(self, 'fields'):
350
 
            self.fields = util.FieldStorage(self.apache_req)
 
343
            self.fields = mod_python.util.FieldStorage(self.apache_req)
351
344
        return self.fields
352
345
 
353
346
    def get_cgi_environ(self):