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

« back to all changes in this revision

Viewing changes to ivle/dispatch/request.py

  • Committer: William Grant
  • Date: 2010-02-26 03:36:30 UTC
  • Revision ID: grantw@unimelb.edu.au-20100226033630-gqoerwl59i10mbao
Add forgotten template.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
    import mod_python.Session
30
30
    import mod_python.Cookie
31
31
    import mod_python.util
 
32
    import mod_python.apache
 
33
 
 
34
    class PotentiallySecureFileSession(mod_python.Session.FileSession):
 
35
        """A mod_python FileSession that sets secure cookie when appropriate.
 
36
 
 
37
        A secure cookie will be set if the request itself is over HTTPS, or if
 
38
        a proxy in front has set X-Forwarded-Proto: https. Otherwise the cookie
 
39
        will be insecure.
 
40
        """
 
41
        def make_cookie(self):
 
42
            cookie = super(PotentiallySecureFileSession, self).make_cookie()
 
43
            if (self._req.is_https() or
 
44
                self._req.headers_in.get('X-Forwarded-Proto') == 'https'):
 
45
                cookie.secure = True
 
46
            return cookie
32
47
except ImportError:
33
48
    # This needs to be importable from outside Apache.
34
49
    pass
35
50
 
 
51
import os.path
 
52
 
36
53
import ivle.util
37
54
import ivle.database
38
55
from ivle.webapp.base.plugins import CookiePlugin
 
56
import ivle.webapp.security
 
57
 
39
58
 
40
59
class Request:
41
60
    """An IVLE request object. This is presented to the IVLE apps as a way of
77
96
        location (write)
78
97
            String. Response "Location" header value. Used with HTTP redirect
79
98
            responses.
80
 
        styles (write)
81
 
            List of strings. Write a list of URLs to CSS files here, and they
82
 
            will be incorporated as <link rel="stylesheet" type="text/css">
83
 
            elements in the head, if write_html_head_foot is True.
84
 
            URLs should be relative to the IVLE root; they will be fixed up
85
 
            to be site-relative.
86
 
        scripts (write)
87
 
            List of strings. Write a list of URLs to JS files here, and they
88
 
            will be incorporated as <script type="text/javascript"> elements
89
 
            in the head, if write_html_head_foot is True.
90
 
            URLs should be relative to the IVLE root; they will be fixed up
91
 
            to be site-relative.
92
 
        scripts_init (write)
93
 
            List of strings. Write a list of JS function names, and they
94
 
            will be added as window.addListener('load', ..., false); calls
95
 
            in the head, if write_html_head_foot is True.
96
 
            This is the propper way to specify functions that need to run at 
97
 
            page load time.
98
99
    """
99
100
 
100
101
    # Special code for an OK response.
104
105
 
105
106
    # HTTP status codes
106
107
 
107
 
    HTTP_CONTINUE                     = 100
108
 
    HTTP_SWITCHING_PROTOCOLS          = 101
109
 
    HTTP_PROCESSING                   = 102
110
108
    HTTP_OK                           = 200
111
 
    HTTP_CREATED                      = 201
112
 
    HTTP_ACCEPTED                     = 202
113
 
    HTTP_NON_AUTHORITATIVE            = 203
114
 
    HTTP_NO_CONTENT                   = 204
115
 
    HTTP_RESET_CONTENT                = 205
116
 
    HTTP_PARTIAL_CONTENT              = 206
117
 
    HTTP_MULTI_STATUS                 = 207
118
 
    HTTP_MULTIPLE_CHOICES             = 300
119
 
    HTTP_MOVED_PERMANENTLY            = 301
120
109
    HTTP_MOVED_TEMPORARILY            = 302
121
 
    HTTP_SEE_OTHER                    = 303
122
 
    HTTP_NOT_MODIFIED                 = 304
123
 
    HTTP_USE_PROXY                    = 305
124
 
    HTTP_TEMPORARY_REDIRECT           = 307
125
 
    HTTP_BAD_REQUEST                  = 400
126
 
    HTTP_UNAUTHORIZED                 = 401
127
 
    HTTP_PAYMENT_REQUIRED             = 402
128
110
    HTTP_FORBIDDEN                    = 403
129
111
    HTTP_NOT_FOUND                    = 404
130
 
    HTTP_METHOD_NOT_ALLOWED           = 405
131
 
    HTTP_NOT_ACCEPTABLE               = 406
132
 
    HTTP_PROXY_AUTHENTICATION_REQUIRED= 407
133
 
    HTTP_REQUEST_TIME_OUT             = 408
134
 
    HTTP_CONFLICT                     = 409
135
 
    HTTP_GONE                         = 410
136
 
    HTTP_LENGTH_REQUIRED              = 411
137
 
    HTTP_PRECONDITION_FAILED          = 412
138
 
    HTTP_REQUEST_ENTITY_TOO_LARGE     = 413
139
 
    HTTP_REQUEST_URI_TOO_LARGE        = 414
140
 
    HTTP_UNSUPPORTED_MEDIA_TYPE       = 415
141
 
    HTTP_RANGE_NOT_SATISFIABLE        = 416
142
 
    HTTP_EXPECTATION_FAILED           = 417
143
 
    HTTP_UNPROCESSABLE_ENTITY         = 422
144
 
    HTTP_LOCKED                       = 423
145
 
    HTTP_FAILED_DEPENDENCY            = 424
146
112
    HTTP_INTERNAL_SERVER_ERROR        = 500
147
 
    HTTP_NOT_IMPLEMENTED              = 501
148
 
    HTTP_BAD_GATEWAY                  = 502
149
 
    HTTP_SERVICE_UNAVAILABLE          = 503
150
 
    HTTP_GATEWAY_TIME_OUT             = 504
151
 
    HTTP_VERSION_NOT_SUPPORTED        = 505
152
 
    HTTP_VARIANT_ALSO_VARIES          = 506
153
 
    HTTP_INSUFFICIENT_STORAGE         = 507
154
 
    HTTP_NOT_EXTENDED                 = 510
 
113
 
 
114
    _store = None
155
115
 
156
116
    def __init__(self, req, config):
157
117
        """Create an IVLE request from a mod_python one.
177
137
        self.uri = req.uri
178
138
        # Split the given path into the app (top-level dir) and sub-path
179
139
        # (after first stripping away the root directory)
180
 
        path = ivle.util.unmake_path(req.uri)
181
 
        (self.app, self.path) = (ivle.util.split_path(path))
182
 
        self.user = None
 
140
        (self.app, self.path) = (ivle.util.split_path(req.uri))
183
141
        self.hostname = req.hostname
184
142
        self.headers_in = req.headers_in
185
143
        self.headers_out = req.headers_out
186
144
 
187
 
        # Open a database connection and transaction, keep it around for users
188
 
        # of the Request object to use
189
 
        self.store = ivle.database.get_store(config)
190
 
 
191
145
        # Default values for the output members
192
146
        self.status = Request.HTTP_OK
193
147
        self.content_type = None        # Use Apache's default
194
148
        self.location = None
195
 
        self.styles = []
196
 
        self.scripts = []
197
 
        self.scripts_init = []
198
149
        # In some cases we don't want the template JS (such as the username
199
150
        # and public FQDN) in the output HTML. In that case, set this to 0.
200
151
        self.write_javascript_settings = True
201
152
        self.got_common_vars = False
202
153
 
203
154
    def __del__(self):
204
 
        """Cleanup."""
205
 
        self.store.close()
 
155
        self.cleanup()
 
156
 
 
157
    def cleanup(self):
 
158
        """Cleanup."""
 
159
        if self._store is not None:
 
160
            self._store.close()
 
161
            self._store = None
 
162
 
 
163
    def commit(self):
 
164
        """Cleanup."""
 
165
        if self._store is not None:
 
166
            self._store.commit()
206
167
 
207
168
    def __writeheaders(self):
208
169
        """Writes out the HTTP and HTML headers before any real data is
251
212
                for cookie in plugin.cookies:
252
213
                    self.add_cookie(mod_python.Cookie.Cookie(cookie, '',
253
214
                                                    expires=1, path='/'))
254
 
        self.throw_redirect(ivle.util.make_path('')) 
 
215
        self.throw_redirect(self.make_path(''))
255
216
 
256
217
 
257
218
    def flush(self):
291
252
        else:
292
253
            mod_python.Cookie.add_cookie(self.apache_req, cookie, value, **attributes)
293
254
 
 
255
    def make_path(self, path):
 
256
        """Prepend the IVLE URL prefix to the given path.
 
257
 
 
258
        This is used when generating URLs to send to the client.
 
259
 
 
260
        This method is DEPRECATED. We no longer support use of a prefix.
 
261
        """
 
262
        return os.path.join(self.config['urls']['root'], path)
 
263
 
294
264
    def get_session(self):
295
265
        """Returns a mod_python Session object for this request.
296
266
        Note that this is dependent on mod_python and may need to change
301
271
        """
302
272
        # Cache the session object and set the timeout to 24 hours.
303
273
        if not hasattr(self, 'session'):
304
 
            self.session = mod_python.Session.FileSession(self.apache_req,
305
 
                                               timeout = 60 * 60 * 24)
 
274
            self.session = PotentiallySecureFileSession(
 
275
                self.apache_req, timeout = 60 * 60 * 24)
306
276
        return self.session
307
277
 
308
278
    def get_fieldstorage(self):
323
293
            self.got_common_vars = True
324
294
        return self.apache_req.subprocess_env
325
295
 
326
 
    @staticmethod
327
 
    def get_http_codename(code):
328
 
        """Given a HTTP error code int, returns a (name, description)
329
 
        pair, suitable for displaying to the user.
330
 
        May return (None,None) if code is unknown.
331
 
        Only lists common 4xx and 5xx codes (since this is just used
332
 
        to display throw_error error messages).
333
 
        """
 
296
    @property
 
297
    def store(self):
 
298
        # Open a database connection and transaction, keep it around for users
 
299
        # of the Request object to use.
 
300
        if self._store is None:
 
301
            self._store = ivle.database.get_store(self.config)
 
302
        return self._store
 
303
 
 
304
    @property
 
305
    def user(self):
 
306
        # Get and cache the request user, or None if it's not valid.
 
307
        # This is a property so that we don't create a store unless
 
308
        # some code actually requests the user.
334
309
        try:
335
 
            return http_codenames[code]
336
 
        except KeyError:
337
 
            return None, None
 
310
            return self._user
 
311
        except AttributeError:
 
312
            if self.publicmode:
 
313
                self._user = None
 
314
            else:
 
315
                temp_user = ivle.webapp.security.get_user_details(self)
 
316
                if temp_user and temp_user.valid:
 
317
                    self._user = temp_user
 
318
                else:
 
319
                    self._user = None
 
320
            return self._user
338
321
 
339
 
# Human strings for HTTP response codes
340
 
http_codenames = {
341
 
    Request.HTTP_BAD_REQUEST:
342
 
        ("Bad Request",
343
 
        "Your browser sent a request IVLE did not understand."),
344
 
    Request.HTTP_UNAUTHORIZED:
345
 
        ("Unauthorized",
346
 
        "You are not allowed to view this part of IVLE."),
347
 
    Request.HTTP_FORBIDDEN:
348
 
        ("Forbidden",
349
 
        "You are not allowed to view this part of IVLE."),
350
 
    Request.HTTP_NOT_FOUND:
351
 
        ("Not Found",
352
 
        "The application or file you requested does not exist."),
353
 
    Request.HTTP_METHOD_NOT_ALLOWED:
354
 
        ("Method Not Allowed",
355
 
        "Your browser is interacting with IVLE in the wrong way."
356
 
        "This is probably a bug in IVLE. "
357
 
        "Please report it to the administrators."),
358
 
    Request.HTTP_INTERNAL_SERVER_ERROR:
359
 
        ("Internal Server Error",
360
 
        "An unknown error occured in IVLE."),
361
 
    Request.HTTP_NOT_IMPLEMENTED:
362
 
        ("Not Implemented",
363
 
        "The application or file you requested has not been implemented "
364
 
        "in IVLE."),
365
 
    Request.HTTP_SERVICE_UNAVAILABLE:
366
 
        ("Service Unavailable",
367
 
        "IVLE is currently experiencing technical difficulties. "
368
 
        "Please try again later."),
369
 
}