jbe@210: -- TODO: function incomplete yet jbe@210: jbe@210: function request.handler(http_request) jbe@212: request._http_request = http_request jbe@210: jbe@210: local success, error_info = xpcall( jbe@210: function() jbe@210: jbe@210: -- restore slots if coming from http redirect jbe@210: if cgi.params.tempstore then jbe@210: trace.restore_slots{} jbe@210: local blob = tempstore.pop(cgi.params.tempstore) jbe@210: if blob then slot.restore_all(blob) end jbe@210: end jbe@210: jbe@210: local function file_exists(filename) jbe@210: local file = io.open(filename, "r") jbe@210: if file then jbe@210: io.close(file) jbe@210: return true jbe@210: else jbe@210: return false jbe@210: end jbe@210: end jbe@210: jbe@210: if request.is_404() then jbe@210: request.set_status("404 Not Found") jbe@210: if request.get_404_route() then jbe@210: request.forward(request.get_404_route()) jbe@210: else jbe@210: error("No 404 page set.") jbe@210: end jbe@210: elseif request.get_action() then jbe@210: trace.request{ jbe@210: module = request.get_module(), jbe@210: action = request.get_action() jbe@210: } jbe@210: if jbe@210: request.get_404_route() and jbe@210: not file_exists( jbe@210: encode.action_file_path{ jbe@210: module = request.get_module(), jbe@210: action = request.get_action() jbe@210: } jbe@210: ) jbe@210: then jbe@210: request.set_status("404 Not Found") jbe@210: request.forward(request.get_404_route()) jbe@210: else jbe@210: if cgi.method ~= "POST" then jbe@210: request.set_status("405 Method Not Allowed") jbe@210: cgi.add_header("Allow: POST") jbe@210: error("Tried to invoke an action with a GET request.") jbe@210: end jbe@210: local action_status = execute.filtered_action{ jbe@210: module = request.get_module(), jbe@210: action = request.get_action(), jbe@210: } jbe@210: if not request.is_rerouted() then jbe@210: local routing_mode, routing_module, routing_view jbe@210: routing_mode = cgi.params["_webmcp_routing." .. action_status .. ".mode"] jbe@210: routing_module = cgi.params["_webmcp_routing." .. action_status .. ".module"] jbe@210: routing_view = cgi.params["_webmcp_routing." .. action_status .. ".view"] jbe@210: routing_anchor = cgi.params["_webmcp_routing." .. action_status .. ".anchor"] jbe@210: if not (routing_mode or routing_module or routing_view) then jbe@210: action_status = "default" jbe@210: routing_mode = cgi.params["_webmcp_routing.default.mode"] jbe@210: routing_module = cgi.params["_webmcp_routing.default.module"] jbe@210: routing_view = cgi.params["_webmcp_routing.default.view"] jbe@210: routing_anchor = cgi.params["_webmcp_routing.default.anchor"] jbe@210: end jbe@210: assert(routing_module, "Routing information has no module.") jbe@210: assert(routing_view, "Routing information has no view.") jbe@210: if routing_mode == "redirect" then jbe@210: local routing_params = {} jbe@210: for key, value in pairs(cgi.params) do jbe@210: local status, stripped_key = string.match( jbe@210: key, "^_webmcp_routing%.([^%.]*)%.params%.(.*)$" jbe@210: ) jbe@210: if status == action_status then jbe@210: routing_params[stripped_key] = value jbe@210: end jbe@210: end jbe@210: request.redirect{ jbe@210: module = routing_module, jbe@210: view = routing_view, jbe@210: id = cgi.params["_webmcp_routing." .. action_status .. ".id"], jbe@210: params = routing_params, jbe@210: anchor = routing_anchor jbe@210: } jbe@210: elseif routing_mode == "forward" then jbe@210: request.forward{ module = routing_module, view = routing_view } jbe@210: else jbe@210: error("Missing or unknown routing mode in request parameters.") jbe@210: end jbe@210: end jbe@210: end jbe@210: else jbe@210: -- no action jbe@210: trace.request{ jbe@210: module = request.get_module(), jbe@210: view = request.get_view() jbe@210: } jbe@210: if jbe@210: request.get_404_route() and jbe@210: not file_exists( jbe@210: encode.view_file_path{ jbe@210: module = request.get_module(), jbe@210: view = request.get_view() jbe@210: } jbe@210: ) jbe@210: then jbe@210: request.set_status("404 Not Found") jbe@210: request.forward(request.get_404_route()) jbe@210: end jbe@210: end jbe@210: jbe@210: if not request.get_redirect_data() then jbe@210: request.process_forward() jbe@210: local view = request.get_view() jbe@210: if string.find(view, "^_") then jbe@210: error("Tried to call a private view (prefixed with underscore).") jbe@210: end jbe@210: execute.filtered_view{ jbe@210: module = request.get_module(), jbe@210: view = view, jbe@210: } jbe@210: end jbe@210: jbe@210: -- force error due to missing absolute base URL until its too late to display error message jbe@210: --if request.get_redirect_data() then jbe@210: -- request.get_absolute_baseurl() jbe@210: --end jbe@210: jbe@210: end, jbe@210: jbe@210: function(errobj) jbe@210: return { jbe@210: errobj = errobj, jbe@210: stacktrace = string.gsub( jbe@210: debug.traceback('', 2), jbe@210: "^\r?\n?stack traceback:\r?\n?", "" jbe@210: ) jbe@210: } jbe@210: end jbe@210: ) jbe@210: jbe@210: if not success then trace.error{} end jbe@210: jbe@210: -- laufzeitermittlung jbe@210: trace.exectime{ real = extos.monotonic_hires_time(), cpu = os.clock() } jbe@210: jbe@210: slot.select('trace', trace.render) -- render trace information jbe@210: jbe@210: local redirect_data = request.get_redirect_data() jbe@210: jbe@210: -- log error and switch to error layout, unless success jbe@210: if not success then jbe@210: local errobj = error_info.errobj jbe@210: local stacktrace = error_info.stacktrace jbe@210: if not request.get_status() and not request.get_json_request_slots() then jbe@210: request.set_status("500 Internal Server Error") jbe@210: end jbe@210: slot.set_layout('system_error') jbe@210: slot.select('system_error', function() jbe@210: if getmetatable(errobj) == mondelefant.errorobject_metatable then jbe@210: slot.put( jbe@210: "
Database error of class ",
jbe@210: encode.html(errobj.code),
jbe@210: " occured:
",
jbe@210: encode.html(errobj.message),
jbe@210: "
", encode.html(tostring(errobj)), "
") jbe@210: end jbe@210: slot.put("Stack trace follows:
")
jbe@210: slot.put(encode.html_newlines(encode.html(stacktrace)))
jbe@210: slot.put("