54
49
# Make the request object into an IVLE request which can be passed to apps
57
req = Request(req, html.write_html_head)
59
# Pass the apachereq to error reporter, since ivle req isn't created
61
handle_unknown_exception(apachereq, *sys.exc_info())
62
# Tell Apache not to generate its own errors as well
65
# Run the main handler, and catch all exceptions
67
return handler_(req, apachereq)
68
except mod_python.apache.SERVER_RETURN:
69
# An apache error. We discourage these, but they might still happen.
73
handle_unknown_exception(req, *sys.exc_info())
74
# Tell Apache not to generate its own errors as well
77
def handler_(req, apachereq):
79
Nested handler function. May raise exceptions. The top-level handler is
80
just used to catch exceptions.
81
Takes both an IVLE request and an Apache req.
51
req = Request(req, html.write_html_head)
83
53
# Check req.app to see if it is valid. 404 if not.
84
54
if req.app is not None and req.app not in conf.apps.app_url:
85
55
# Maybe it is a special app!
86
56
if req.app == 'logout':
89
req.throw_error(Request.HTTP_NOT_FOUND,
90
"There is no application called %s." % repr(req.app))
59
# TODO: Nicer 404 message?
60
req.throw_error(Request.HTTP_NOT_FOUND)
92
62
# Special handling for public mode - just call public app and get out
93
63
# NOTE: This will not behave correctly if the public app uses
104
74
app = conf.apps.app_url[req.app]
106
76
# Check if app requires auth. If so, perform authentication and login.
107
# This will either return a User object, None, or perform a redirect
108
# which we will not catch here.
109
77
if app.requireauth:
110
req.user = login.login(req)
111
logged_in = req.user is not None
78
req.username = login.login(req)
79
logged_in = req.username is not None
113
req.user = login.get_user_details(req)
81
req.username = login.get_username(req)
117
85
# Keep the user's session alive by writing to the session object.
118
# req.get_session().save()
119
# Well, it's a fine idea, but it creates considerable grief in the
120
# concurrent update department, so instead, we'll just make the
121
# sessions not time out.
86
req.get_session().save()
123
87
# If user did not specify an app, HTTP redirect to default app and
125
89
if req.app is None:
157
120
session = req.get_session()
158
121
session.invalidate()
160
req.add_cookie(forumutil.invalidated_forum_cookie())
161
123
req.throw_redirect(util.make_path(''))
163
def handle_unknown_exception(req, exc_type, exc_value, exc_traceback):
165
Given an exception that has just been thrown from IVLE, print its details
167
This is a full handler. It assumes nothing has been written, and writes a
169
req: May be EITHER an IVLE req or an Apache req.
170
IVLE reqs may have the HTML head/foot written (on a 400 error), but
171
the handler code may pass an apache req if an exception occurs before
172
the IVLE request is created.
174
req.content_type = "text/html"
175
# For some reason, some versions of mod_python have "_server" instead of
176
# "main_server". So we check for both.
178
admin_email = apache.main_server.server_admin
179
except AttributeError:
181
admin_email = apache._server.server_admin
182
except AttributeError:
185
httpcode = exc_value.httpcode
186
req.status = httpcode
187
except AttributeError:
189
req.status = apache.HTTP_INTERNAL_SERVER_ERROR
190
# We handle 3 types of error.
191
# IVLEErrors with 4xx response codes (client error).
192
# IVLEErrors with 5xx response codes (handled server error).
193
# Other exceptions (unhandled server error).
194
# IVLEErrors should not have other response codes than 4xx or 5xx
195
# (eg. throw_redirect should have been used for 3xx codes).
196
# Therefore, that is treated as an unhandled error.
198
if (exc_type == util.IVLEError and httpcode >= 400
199
and httpcode <= 499):
200
# IVLEErrors with 4xx response codes are client errors.
201
# Therefore, these have a "nice" response (we even coat it in the IVLE
203
req.write_html_head_foot = True
204
req.write('<div id="ivle_padding">\n')
206
codename, msg = req.get_http_codename(httpcode)
207
except AttributeError:
208
codename, msg = None, None
209
# Override the default message with the supplied one,
211
if exc_value.message is not None:
212
msg = exc_value.message
213
if codename is not None:
214
req.write("<h1>Error: %s</h1>\n" % cgi.escape(codename))
216
req.write("<h1>Error</h1>\n")
218
req.write("<p>%s</p>\n" % cgi.escape(msg))
220
req.write("<p>An unknown error occured.</p>\n")
221
req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
222
req.write('</div>\n')
224
# A "bad" error message. We shouldn't get here unless IVLE
225
# misbehaves (which is currently very easy, if things aren't set up
227
# Write the traceback.
228
# If this is a non-4xx IVLEError, get the message and httpcode and
229
# make the error message a bit nicer (but still include the
231
# We also need to special-case IVLEJailError, as we can get another
232
# almost-exception out of it.
234
codename, msg = None, None
236
if exc_type is util.IVLEJailError:
237
msg = exc_value.type_str + ": " + exc_value.message
238
tb = 'Exception information extracted from IVLEJailError:\n'
239
tb += urllib.unquote(exc_value.info)
242
codename, msg = req.get_http_codename(httpcode)
243
except AttributeError:
245
# Override the default message with the supplied one,
247
if hasattr(exc_value, 'message') and exc_value.message is not None:
248
msg = exc_value.message
249
# Prepend the exception type
250
if exc_type != util.IVLEError:
251
msg = exc_type.__name__ + ": " + msg
253
tb = ''.join(traceback.format_exception(exc_type, exc_value,
257
<head><title>IVLE Internal Server Error</title></head>
259
<h1>IVLE Internal Server Error""")
260
if (codename is not None
261
and httpcode != apache.HTTP_INTERNAL_SERVER_ERROR):
262
req.write(": %s" % cgi.escape(codename))
264
<p>An error has occured which is the fault of the IVLE developers or
268
req.write("<p>%s</p>\n" % cgi.escape(msg))
269
if httpcode is not None:
270
req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
272
<p>Please report this to <a href="mailto:%s">%s</a> (the system
273
administrator). Include the following information:</p>
274
""" % (cgi.escape(admin_email), cgi.escape(admin_email)))
277
req.write(cgi.escape(tb))
278
req.write("</pre>\n</body>\n")