jbe@210: -- TODO: function incomplete yet jbe@210: jbe@215: local function file_exists(filename) jbe@215: local file = io.open(filename, "r") jbe@215: if file then jbe@215: io.close(file) jbe@215: return true jbe@215: else jbe@215: return false jbe@215: end jbe@215: end jbe@215: jbe@216: function request.process(route) jbe@216: jbe@210: local success, error_info = xpcall( jbe@210: function() jbe@210: jbe@210: -- restore slots if coming from http redirect jbe@215: local tempstore_value = request.get_param{method = "GET", name = "_tempstore"} jbe@215: if tempstore_value then jbe@210: trace.restore_slots{} jbe@215: local blob = tempstore.pop(tempstore_value) jbe@210: if blob then slot.restore_all(blob) end jbe@210: end jbe@210: 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: "

" jbe@210: ) jbe@210: else jbe@210: slot.put("

", 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("

") jbe@210: end) jbe@210: elseif redirect_data then jbe@210: local redirect_params = {} jbe@210: for key, value in pairs(redirect_data.params) do jbe@210: redirect_params[key] = value jbe@210: end jbe@210: local slot_dump = slot.dump_all() jbe@210: if slot_dump ~= "" then jbe@210: redirect_params.tempstore = tempstore.save(slot_dump) jbe@210: end jbe@210: local json_request_slots = request.get_json_request_slots() jbe@210: if json_request_slots then jbe@210: redirect_params["_webmcp_json_slots[]"] = json_request_slots jbe@210: end jbe@210: cgi.redirect( jbe@210: encode.url{ jbe@210: base = request.get_absolute_baseurl(), jbe@210: module = redirect_data.module, jbe@210: view = redirect_data.view, jbe@210: id = redirect_data.id, jbe@210: params = redirect_params, jbe@210: anchor = redirect_data.anchor jbe@210: } jbe@210: ) jbe@210: cgi.send_data() jbe@210: end jbe@210: jbe@210: if not success or not redirect_data then jbe@210: jbe@210: local http_status = request.get_status() jbe@210: if http_status then jbe@210: cgi.set_status(http_status) jbe@210: end jbe@210: jbe@210: local json_request_slots = request.get_json_request_slots() jbe@210: if json_request_slots then jbe@210: cgi.set_content_type('application/json') jbe@210: local data = {} jbe@210: for idx, slot_ident in ipairs(json_request_slots) do jbe@210: data[slot_ident] = slot.get_content(slot_ident) jbe@210: end jbe@210: cgi.send_data(encode.json(data)) jbe@210: else jbe@210: cgi.set_content_type(slot.get_content_type()) jbe@210: cgi.send_data(slot.render_layout()) jbe@210: end jbe@210: end jbe@210: jbe@210: end