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

« back to all changes in this revision

Viewing changes to www/dispatch/request.py

  • Committer: wagrant
  • Date: 2008-07-16 01:26:48 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:884
common.svn: Add a wrapper object to make a pysvn listing object look
            like the result of os.stat.
fileservice_lib: Factor out the last bit of statting duplication, this
                 time from the pysvn listing bit.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
import common.util
27
27
import mod_python
28
 
from mod_python import (util, Session)
 
28
from mod_python import (util, Session, Cookie)
 
29
import conf
 
30
import plugins.console
29
31
 
30
32
class Request:
31
33
    """An IVLE request object. This is presented to the IVLE apps as a way of
42
44
            String. The path specified in the URL *not including* the
43
45
            application or the IVLE location prefix. eg. a URL of
44
46
            "/ivle/files/joe/myfiles" has a path of "joe/myfiles".
45
 
        username (read)
46
 
            String. Login name of the user who is currently logged in, or
 
47
        user (read)
 
48
            User object. Details of the user who is currently logged in, or
47
49
            None.
 
50
        hostname (read)
 
51
            String. Hostname the server is running on.
48
52
        headers_in (read)
49
53
            Table object representing headers sent by the client.
50
54
        headers_out (read, can be written to)
51
55
            Table object representing headers to be sent to the client.
 
56
        publicmode (read)
 
57
            Bool. True if the request came for the "public host" as
 
58
            configured in conf.py. Note that public mode requests do not
 
59
            have an app (app is set to None).
52
60
 
53
61
        status (write)
54
62
            Int. Response status number. Use one of the status codes defined
73
81
            in the head, if write_html_head_foot is True.
74
82
            URLs should be relative to the IVLE root; they will be fixed up
75
83
            to be site-relative.
 
84
        scripts_init (write)
 
85
            List of strings. Write a list of JS function names, and they
 
86
            will be added as window.addListener('load', ..., false); calls
 
87
            in the head, if write_html_head_foot is True.
 
88
            This is the propper way to specify functions that need to run at 
 
89
            page load time.
76
90
        write_html_head_foot (write)
77
91
            Boolean. If True, dispatch assumes that this is an XHTML page, and
78
92
            will immediately write a full HTML head, open the body element,
158
172
        self.func_write_html_head = write_html_head
159
173
        self.headers_written = False
160
174
 
 
175
        # Determine if the browser used the public host name to make the
 
176
        # request (in which case we are in "public mode")
 
177
        if req.hostname == conf.public_host:
 
178
            self.publicmode = True
 
179
        else:
 
180
            self.publicmode = False
 
181
 
161
182
        # Inherit values for the input members
162
183
        self.method = req.method
163
184
        self.uri = req.uri
164
185
        # Split the given path into the app (top-level dir) and sub-path
165
186
        # (after first stripping away the root directory)
166
 
        (self.app, self.path) = (
167
 
            common.util.split_path(common.util.unmake_path(req.uri)))
168
 
        self.username = None
 
187
        path = common.util.unmake_path(req.uri)
 
188
        if self.publicmode:
 
189
            self.app = None
 
190
            (_, self.path) = (common.util.split_path(path))
 
191
        else:
 
192
            (self.app, self.path) = (common.util.split_path(path))
 
193
        self.user = None
 
194
        self.hostname = req.hostname
169
195
        self.headers_in = req.headers_in
170
196
        self.headers_out = req.headers_out
171
197
 
176
202
        self.title = None     # Will be set by dispatch before passing to app
177
203
        self.styles = []
178
204
        self.scripts = []
 
205
        self.scripts_init = []
179
206
        self.write_html_head_foot = False
 
207
        self.got_common_vars = False
180
208
 
181
209
    def __writeheaders(self):
182
210
        """Writes out the HTTP and HTML headers before any real data is
183
211
        written."""
184
212
        self.headers_written = True
 
213
        
 
214
        # app is the App object for the chosen app
 
215
        if self.app is None:
 
216
            app = conf.apps.app_url[conf.apps.default_app]
 
217
        else:
 
218
            app = conf.apps.app_url[self.app]
 
219
 
 
220
        # Write any final modifications to header content
 
221
        if app.useconsole and self.user:
 
222
            plugins.console.insert_scripts_styles(self.scripts, self.styles, \
 
223
                self.scripts_init)
 
224
 
185
225
        # Prepare the HTTP and HTML headers before the first write is made
186
226
        if self.content_type != None:
187
227
            self.apache_req.content_type = self.content_type
204
244
 
205
245
        if not self.headers_written:
206
246
            self.__writeheaders()
207
 
        self.apache_req.write(string, flush)
 
247
        if isinstance(string, unicode):
 
248
            # Encode unicode strings as UTF-8
 
249
            # (Otherwise cannot handle being written to a bytestream)
 
250
            self.apache_req.write(string.encode('utf8'), flush)
 
251
        else:
 
252
            # 8-bit clean strings just get written directly.
 
253
            # This includes binary strings.
 
254
            self.apache_req.write(string, flush)
208
255
 
209
256
    def flush(self):
210
257
        """Flushes the output buffer."""
220
267
        """Reads at most len bytes directly from the client. (See mod_python
221
268
        Request.read)."""
222
269
        if len is None:
223
 
            self.apache_req.read()
 
270
            return self.apache_req.read()
224
271
        else:
225
 
            self.apache_req.read(len)
 
272
            return self.apache_req.read(len)
226
273
 
227
 
    def throw_error(self, httpcode):
 
274
    def throw_error(self, httpcode, message=None):
228
275
        """Writes out an HTTP error of the specified code. Raises an exception
229
276
        which is caught by the dispatch or web server, so any code following
230
277
        this call will not be executed.
232
279
        httpcode: An HTTP response status code. Pass a constant from the
233
280
        Request class.
234
281
        """
235
 
        raise mod_python.apache.SERVER_RETURN, httpcode
 
282
        raise common.util.IVLEError(httpcode, message)
236
283
 
237
284
    def throw_redirect(self, location):
238
285
        """Writes out an HTTP redirect to the specified URL. Raises an
244
291
        """
245
292
        mod_python.util.redirect(self.apache_req, location)
246
293
 
 
294
    def add_cookie(self, cookie, value=None, **attributes):
 
295
        """Inserts a cookie into this request object's headers."""
 
296
        if value is None:
 
297
            Cookie.add_cookie(self.apache_req, cookie)
 
298
        else:
 
299
            Cookie.add_cookie(self.apache_req, cookie, value, **attributes)
 
300
 
247
301
    def get_session(self):
248
302
        """Returns a mod_python Session object for this request.
249
303
        Note that this is dependent on mod_python and may need to change
250
304
        interface if porting away from mod_python."""
251
 
        # Cache the session object
 
305
        # Cache the session object and set the timeout to 24 hours.
252
306
        if not hasattr(self, 'session'):
253
 
            self.session = Session.Session(self.apache_req)
 
307
            self.session = Session.FileSession(self.apache_req,
 
308
                                               timeout = 60 * 60 * 24)
254
309
        return self.session
255
310
 
256
311
    def get_fieldstorage(self):
261
316
        if not hasattr(self, 'fields'):
262
317
            self.fields = util.FieldStorage(self.apache_req)
263
318
        return self.fields
 
319
 
 
320
    def get_cgi_environ(self):
 
321
        """Returns the CGI environment emulation for this request. (Calls
 
322
        add_common_vars). The environment is returned as a mapping
 
323
        compatible with os.environ."""
 
324
        if not self.got_common_vars:
 
325
            self.apache_req.add_common_vars()
 
326
            self.got_common_vars = True
 
327
        return self.apache_req.subprocess_env
 
328
 
 
329
    @staticmethod
 
330
    def get_http_codename(code):
 
331
        """Given a HTTP error code int, returns a (name, description)
 
332
        pair, suitable for displaying to the user.
 
333
        May return (None,None) if code is unknown.
 
334
        Only lists common 4xx and 5xx codes (since this is just used
 
335
        to display throw_error error messages).
 
336
        """
 
337
        try:
 
338
            return http_codenames[code]
 
339
        except KeyError:
 
340
            return None, None
 
341
 
 
342
# Human strings for HTTP response codes
 
343
http_codenames = {
 
344
    Request.HTTP_BAD_REQUEST:
 
345
        ("Bad Request",
 
346
        "Your browser sent a request IVLE did not understand."),
 
347
    Request.HTTP_UNAUTHORIZED:
 
348
        ("Unauthorized",
 
349
        "You are not allowed to view this part of IVLE."),
 
350
    Request.HTTP_FORBIDDEN:
 
351
        ("Forbidden",
 
352
        "You are not allowed to view this part of IVLE."),
 
353
    Request.HTTP_NOT_FOUND:
 
354
        ("Not Found",
 
355
        "The application or file you requested does not exist."),
 
356
    Request.HTTP_METHOD_NOT_ALLOWED:
 
357
        ("Method Not Allowed",
 
358
        "Your browser is interacting with IVLE in the wrong way."
 
359
        "This is probably a bug in IVLE. "
 
360
        "Please report it to the administrators."),
 
361
    Request.HTTP_INTERNAL_SERVER_ERROR:
 
362
        ("Internal Server Error",
 
363
        "An unknown error occured in IVLE."),
 
364
    Request.HTTP_NOT_IMPLEMENTED:
 
365
        ("Not Implemented",
 
366
        "The application or file you requested has not been implemented "
 
367
        "in IVLE."),
 
368
    Request.HTTP_SERVICE_UNAVAILABLE:
 
369
        ("Service Unavailable",
 
370
        "IVLE is currently experiencing technical difficulties. "
 
371
        "Please try again later."),
 
372
}