webmcp
changeset 215:ba3dd4a17e3d
Some code cleanup/rearrangement for request handling
author | jbe |
---|---|
date | Mon Jan 12 01:48:11 2015 +0100 (2015-01-12) |
parents | 6ac7133bb58e |
children | fd0360594636 |
files | framework/bin/mcp.lua framework/env/request/__init.lua framework/env/request/default_router.lua framework/env/request/handler.lua framework/env/request/router.lua |
line diff
1.1 --- a/framework/bin/mcp.lua Sat Jan 10 10:44:17 2015 +0100 1.2 +++ b/framework/bin/mcp.lua Mon Jan 12 01:48:11 2015 +0100 1.3 @@ -188,10 +188,12 @@ 1.4 -- execute configurations 1.5 for i, config_name in ipairs(WEBMCP_CONFIG_NAMES) do 1.6 execute.config(config_name) 1.7 + execute.prefork_initializers() 1.8 end 1.9 1.10 -- interactive console mode 1.11 if WEBMCP_MODE == "interactive" then 1.12 + execute.postfork_initializers() 1.13 trace.disable() -- avoids memory leakage (TODO: needs general solution for moonbridge?) 1.14 end 1.15 1.16 @@ -199,13 +201,10 @@ 1.17 if WEBMCP_MODE == "listen" then 1.18 local http = require("moonbridge_http") 1.19 for i, listener in ipairs(listeners) do 1.20 - listener.prepare = execute.prefork_initializers 1.21 + listener.prepare = execute.postfork_initializers 1.22 listener.connect = http.generate_handler( 1.23 - request.get_http_options(), 1.24 - function(http_request) 1.25 - execute.postfork_initializers() 1.26 - request.handler(http_request) 1.27 - end 1.28 + request.handler, 1.29 + request.get_http_options() 1.30 ) 1.31 listener.finish = execute.finalizers 1.32 moonbridge_listen(listener)
2.1 --- a/framework/env/request/__init.lua Sat Jan 10 10:44:17 2015 +0100 2.2 +++ b/framework/env/request/__init.lua Mon Jan 12 01:48:11 2015 +0100 2.3 @@ -14,82 +14,6 @@ 2.4 request._json_requests_allowed = false 2.5 2.6 request._params = {} 2.7 -local depth 2.8 -if cgi then -- if-clause to support interactive mode 2.9 - if cgi.params._webmcp_404 then 2.10 - request.force_absolute_baseurl() 2.11 - request._is_404 = true 2.12 - end 2.13 - for key, value in pairs(cgi.params) do 2.14 - if not string.match(key, "^_webmcp_") then 2.15 - request._params[key] = value 2.16 - end 2.17 - end 2.18 - local path = cgi.params._webmcp_path 2.19 - if path then 2.20 - local function parse() 2.21 - local module, action, view, suffix, id 2.22 - if path == "" then 2.23 - request._module = "index" 2.24 - request._view = "index" 2.25 - return 2.26 - end 2.27 - module = string.match(path, "^([^/]+)/$") 2.28 - if module then 2.29 - request._module = module 2.30 - request._view = "index" 2.31 - return 2.32 - end 2.33 - module, action = string.match(path, "^([^/]+)/([^/.]+)$") 2.34 - if module then 2.35 - request._module = module 2.36 - request._action = action 2.37 - return 2.38 - end 2.39 - module, view, suffix = string.match(path, "^([^/]+)/([^/.]+)%.([^/]+)$") 2.40 - if module then 2.41 - request._module = module 2.42 - request._view = view 2.43 - request._suffix = suffix 2.44 - return 2.45 - end 2.46 - module, view, id, suffix = string.match(path, "^([^/]+)/([^/]+)/([^/.]+)%.([^/]+)$") 2.47 - if module then 2.48 - request._module = module 2.49 - request._view = view 2.50 - request._id = id 2.51 - request._suffix = suffix 2.52 - return 2.53 - end 2.54 - request._is_404 = true 2.55 - end 2.56 - parse() 2.57 - -- allow id to also be set by "_webmcp_id" parameter 2.58 - if cgi.params._webmcp_id ~= nil then 2.59 - request._id = cgi.params._webmcp_id 2.60 - end 2.61 - depth = 0 2.62 - for match in string.gmatch(path, "/") do 2.63 - depth = depth + 1 2.64 - end 2.65 - else 2.66 - request._module = cgi.params._webmcp_module 2.67 - request._action = cgi.params._webmcp_action 2.68 - request._view = cgi.params._webmcp_view 2.69 - request._suffix = cgi.params._webmcp_suffix 2.70 - request._id = cgi.params._webmcp_id 2.71 - depth = tonumber(cgi.params._webmcp_urldepth) 2.72 - end 2.73 -end 2.74 -if depth and depth > 0 then 2.75 - local elements = {} 2.76 - for i = 1, depth do 2.77 - elements[#elements+1] = "../" 2.78 - end 2.79 - request._relative_baseurl = table.concat(elements) 2.80 -else 2.81 - request._relative_baseurl = "./" 2.82 -end 2.83 2.84 request._app_basepath = assert( 2.85 os.getenv("WEBMCP_APP_BASEPATH"),
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/framework/env/request/default_router.lua Mon Jan 12 01:48:11 2015 +0100 3.3 @@ -0,0 +1,267 @@ 3.4 +-- TODO: function incomplete yet 3.5 + 3.6 +local function file_exists(filename) 3.7 + local file = io.open(filename, "r") 3.8 + if file then 3.9 + io.close(file) 3.10 + return true 3.11 + else 3.12 + return false 3.13 + end 3.14 +end 3.15 + 3.16 +function request.default_router(path) 3.17 + request._http_request = http_request 3.18 + local path = http_request.path 3.19 + local function parse_path() 3.20 + if not path then 3.21 + return 3.22 + end 3.23 + if path == "/" then 3.24 + return {module = "index", view = "index"} 3.25 + end 3.26 + module = string.match(path, "^/([^/]+)/$") 3.27 + if module then 3.28 + return {module = module, view = "index"} 3.29 + end 3.30 + module, action = string.match(path, "^/([^/]+)/([^/.]+)$") 3.31 + if module then 3.32 + return {module = module, action = action} 3.33 + end 3.34 + module, view, suffix = string.match(path, "^/([^/]+)/([^/.]+)%.([^/]+)$") 3.35 + if module then 3.36 + return {module = module, view = view, suffix = suffix} 3.37 + end 3.38 + module, view, id, suffix = string.match(path, "^/([^/]+)/([^/]+)/([^/.]+)%.([^/]+)$") 3.39 + if module then 3.40 + return {module = module, view = view, id = id, suffix = suffix} 3.41 + end 3.42 + end 3.43 + request._data = parse_path() 3.44 + if path then 3.45 + local elements = {} 3.46 + for match in string.gmatch(path, "/") do 3.47 + elements[#elements+1] = "../" 3.48 + end 3.49 + elements[#elements] = nil 3.50 + if #elements > 0 then 3.51 + request._relative_baseurl = table.concat(elements) 3.52 + else 3.53 + request._relative_baseurl = "./" 3.54 + end 3.55 + end 3.56 + local success, error_info = xpcall( 3.57 + function() 3.58 + 3.59 + -- restore slots if coming from http redirect 3.60 + local tempstore_value = request.get_param{method = "GET", name = "_tempstore"} 3.61 + if tempstore_value then 3.62 + trace.restore_slots{} 3.63 + local blob = tempstore.pop(tempstore_value) 3.64 + if blob then slot.restore_all(blob) end 3.65 + end 3.66 + 3.67 + 3.68 + if request.is_404() then 3.69 + request.set_status("404 Not Found") 3.70 + if request.get_404_route() then 3.71 + request.forward(request.get_404_route()) 3.72 + else 3.73 + error("No 404 page set.") 3.74 + end 3.75 + elseif request.get_action() then 3.76 + trace.request{ 3.77 + module = request.get_module(), 3.78 + action = request.get_action() 3.79 + } 3.80 + if 3.81 + request.get_404_route() and 3.82 + not file_exists( 3.83 + encode.action_file_path{ 3.84 + module = request.get_module(), 3.85 + action = request.get_action() 3.86 + } 3.87 + ) 3.88 + then 3.89 + request.set_status("404 Not Found") 3.90 + request.forward(request.get_404_route()) 3.91 + else 3.92 + if cgi.method ~= "POST" then 3.93 + request.set_status("405 Method Not Allowed") 3.94 + cgi.add_header("Allow: POST") 3.95 + error("Tried to invoke an action with a GET request.") 3.96 + end 3.97 + local action_status = execute.filtered_action{ 3.98 + module = request.get_module(), 3.99 + action = request.get_action(), 3.100 + } 3.101 + if not request.is_rerouted() then 3.102 + local routing_mode, routing_module, routing_view 3.103 + routing_mode = cgi.params["_webmcp_routing." .. action_status .. ".mode"] 3.104 + routing_module = cgi.params["_webmcp_routing." .. action_status .. ".module"] 3.105 + routing_view = cgi.params["_webmcp_routing." .. action_status .. ".view"] 3.106 + routing_anchor = cgi.params["_webmcp_routing." .. action_status .. ".anchor"] 3.107 + if not (routing_mode or routing_module or routing_view) then 3.108 + action_status = "default" 3.109 + routing_mode = cgi.params["_webmcp_routing.default.mode"] 3.110 + routing_module = cgi.params["_webmcp_routing.default.module"] 3.111 + routing_view = cgi.params["_webmcp_routing.default.view"] 3.112 + routing_anchor = cgi.params["_webmcp_routing.default.anchor"] 3.113 + end 3.114 + assert(routing_module, "Routing information has no module.") 3.115 + assert(routing_view, "Routing information has no view.") 3.116 + if routing_mode == "redirect" then 3.117 + local routing_params = {} 3.118 + for key, value in pairs(cgi.params) do 3.119 + local status, stripped_key = string.match( 3.120 + key, "^_webmcp_routing%.([^%.]*)%.params%.(.*)$" 3.121 + ) 3.122 + if status == action_status then 3.123 + routing_params[stripped_key] = value 3.124 + end 3.125 + end 3.126 + request.redirect{ 3.127 + module = routing_module, 3.128 + view = routing_view, 3.129 + id = cgi.params["_webmcp_routing." .. action_status .. ".id"], 3.130 + params = routing_params, 3.131 + anchor = routing_anchor 3.132 + } 3.133 + elseif routing_mode == "forward" then 3.134 + request.forward{ module = routing_module, view = routing_view } 3.135 + else 3.136 + error("Missing or unknown routing mode in request parameters.") 3.137 + end 3.138 + end 3.139 + end 3.140 + else 3.141 + -- no action 3.142 + trace.request{ 3.143 + module = request.get_module(), 3.144 + view = request.get_view() 3.145 + } 3.146 + if 3.147 + request.get_404_route() and 3.148 + not file_exists( 3.149 + encode.view_file_path{ 3.150 + module = request.get_module(), 3.151 + view = request.get_view() 3.152 + } 3.153 + ) 3.154 + then 3.155 + request.set_status("404 Not Found") 3.156 + request.forward(request.get_404_route()) 3.157 + end 3.158 + end 3.159 + 3.160 + if not request.get_redirect_data() then 3.161 + request.process_forward() 3.162 + local view = request.get_view() 3.163 + if string.find(view, "^_") then 3.164 + error("Tried to call a private view (prefixed with underscore).") 3.165 + end 3.166 + execute.filtered_view{ 3.167 + module = request.get_module(), 3.168 + view = view, 3.169 + } 3.170 + end 3.171 + 3.172 + -- force error due to missing absolute base URL until its too late to display error message 3.173 + --if request.get_redirect_data() then 3.174 + -- request.get_absolute_baseurl() 3.175 + --end 3.176 + 3.177 + end, 3.178 + 3.179 + function(errobj) 3.180 + return { 3.181 + errobj = errobj, 3.182 + stacktrace = string.gsub( 3.183 + debug.traceback('', 2), 3.184 + "^\r?\n?stack traceback:\r?\n?", "" 3.185 + ) 3.186 + } 3.187 + end 3.188 + ) 3.189 + 3.190 + if not success then trace.error{} end 3.191 + 3.192 + -- laufzeitermittlung 3.193 + trace.exectime{ real = extos.monotonic_hires_time(), cpu = os.clock() } 3.194 + 3.195 + slot.select('trace', trace.render) -- render trace information 3.196 + 3.197 + local redirect_data = request.get_redirect_data() 3.198 + 3.199 + -- log error and switch to error layout, unless success 3.200 + if not success then 3.201 + local errobj = error_info.errobj 3.202 + local stacktrace = error_info.stacktrace 3.203 + if not request.get_status() and not request.get_json_request_slots() then 3.204 + request.set_status("500 Internal Server Error") 3.205 + end 3.206 + slot.set_layout('system_error') 3.207 + slot.select('system_error', function() 3.208 + if getmetatable(errobj) == mondelefant.errorobject_metatable then 3.209 + slot.put( 3.210 + "<p>Database error of class <b>", 3.211 + encode.html(errobj.code), 3.212 + "</b> occured:<br/><b>", 3.213 + encode.html(errobj.message), 3.214 + "</b></p>" 3.215 + ) 3.216 + else 3.217 + slot.put("<p><b>", encode.html(tostring(errobj)), "</b></p>") 3.218 + end 3.219 + slot.put("<p>Stack trace follows:<br/>") 3.220 + slot.put(encode.html_newlines(encode.html(stacktrace))) 3.221 + slot.put("</p>") 3.222 + end) 3.223 + elseif redirect_data then 3.224 + local redirect_params = {} 3.225 + for key, value in pairs(redirect_data.params) do 3.226 + redirect_params[key] = value 3.227 + end 3.228 + local slot_dump = slot.dump_all() 3.229 + if slot_dump ~= "" then 3.230 + redirect_params.tempstore = tempstore.save(slot_dump) 3.231 + end 3.232 + local json_request_slots = request.get_json_request_slots() 3.233 + if json_request_slots then 3.234 + redirect_params["_webmcp_json_slots[]"] = json_request_slots 3.235 + end 3.236 + cgi.redirect( 3.237 + encode.url{ 3.238 + base = request.get_absolute_baseurl(), 3.239 + module = redirect_data.module, 3.240 + view = redirect_data.view, 3.241 + id = redirect_data.id, 3.242 + params = redirect_params, 3.243 + anchor = redirect_data.anchor 3.244 + } 3.245 + ) 3.246 + cgi.send_data() 3.247 + end 3.248 + 3.249 + if not success or not redirect_data then 3.250 + 3.251 + local http_status = request.get_status() 3.252 + if http_status then 3.253 + cgi.set_status(http_status) 3.254 + end 3.255 + 3.256 + local json_request_slots = request.get_json_request_slots() 3.257 + if json_request_slots then 3.258 + cgi.set_content_type('application/json') 3.259 + local data = {} 3.260 + for idx, slot_ident in ipairs(json_request_slots) do 3.261 + data[slot_ident] = slot.get_content(slot_ident) 3.262 + end 3.263 + cgi.send_data(encode.json(data)) 3.264 + else 3.265 + cgi.set_content_type(slot.get_content_type()) 3.266 + cgi.send_data(slot.render_layout()) 3.267 + end 3.268 + end 3.269 + 3.270 +end
4.1 --- a/framework/env/request/handler.lua Sat Jan 10 10:44:17 2015 +0100 4.2 +++ b/framework/env/request/handler.lua Mon Jan 12 01:48:11 2015 +0100 4.3 @@ -1,228 +1,30 @@ 4.4 --- TODO: function incomplete yet 4.5 +--[[-- 4.6 +request.handler( 4.7 + request -- HTTP request object 4.8 +) 4.9 + 4.10 +Called by mcp.lua to process an HTTP request. Performs some initializations, then calls request.router(). 4.11 + 4.12 +--]]-- 4.13 4.14 function request.handler(http_request) 4.15 request._http_request = http_request 4.16 - 4.17 - local success, error_info = xpcall( 4.18 - function() 4.19 - 4.20 - -- restore slots if coming from http redirect 4.21 - if cgi.params.tempstore then 4.22 - trace.restore_slots{} 4.23 - local blob = tempstore.pop(cgi.params.tempstore) 4.24 - if blob then slot.restore_all(blob) end 4.25 - end 4.26 - 4.27 - local function file_exists(filename) 4.28 - local file = io.open(filename, "r") 4.29 - if file then 4.30 - io.close(file) 4.31 - return true 4.32 - else 4.33 - return false 4.34 - end 4.35 - end 4.36 + local path = http_request.path 4.37 + if path then 4.38 + local elements = {} 4.39 + for match in string.gmatch(path, "/") do 4.40 + elements[#elements+1] = "../" 4.41 + end 4.42 + elements[#elements] = nil 4.43 + if #elements > 0 then 4.44 + request._relative_baseurl = table.concat(elements) 4.45 + else 4.46 + request._relative_baseurl = "./" 4.47 + end 4.48 + else 4.49 + request._relative_baseurl = nil 4.50 + end 4.51 + request.router() 4.52 +end 4.53 4.54 - if request.is_404() then 4.55 - request.set_status("404 Not Found") 4.56 - if request.get_404_route() then 4.57 - request.forward(request.get_404_route()) 4.58 - else 4.59 - error("No 404 page set.") 4.60 - end 4.61 - elseif request.get_action() then 4.62 - trace.request{ 4.63 - module = request.get_module(), 4.64 - action = request.get_action() 4.65 - } 4.66 - if 4.67 - request.get_404_route() and 4.68 - not file_exists( 4.69 - encode.action_file_path{ 4.70 - module = request.get_module(), 4.71 - action = request.get_action() 4.72 - } 4.73 - ) 4.74 - then 4.75 - request.set_status("404 Not Found") 4.76 - request.forward(request.get_404_route()) 4.77 - else 4.78 - if cgi.method ~= "POST" then 4.79 - request.set_status("405 Method Not Allowed") 4.80 - cgi.add_header("Allow: POST") 4.81 - error("Tried to invoke an action with a GET request.") 4.82 - end 4.83 - local action_status = execute.filtered_action{ 4.84 - module = request.get_module(), 4.85 - action = request.get_action(), 4.86 - } 4.87 - if not request.is_rerouted() then 4.88 - local routing_mode, routing_module, routing_view 4.89 - routing_mode = cgi.params["_webmcp_routing." .. action_status .. ".mode"] 4.90 - routing_module = cgi.params["_webmcp_routing." .. action_status .. ".module"] 4.91 - routing_view = cgi.params["_webmcp_routing." .. action_status .. ".view"] 4.92 - routing_anchor = cgi.params["_webmcp_routing." .. action_status .. ".anchor"] 4.93 - if not (routing_mode or routing_module or routing_view) then 4.94 - action_status = "default" 4.95 - routing_mode = cgi.params["_webmcp_routing.default.mode"] 4.96 - routing_module = cgi.params["_webmcp_routing.default.module"] 4.97 - routing_view = cgi.params["_webmcp_routing.default.view"] 4.98 - routing_anchor = cgi.params["_webmcp_routing.default.anchor"] 4.99 - end 4.100 - assert(routing_module, "Routing information has no module.") 4.101 - assert(routing_view, "Routing information has no view.") 4.102 - if routing_mode == "redirect" then 4.103 - local routing_params = {} 4.104 - for key, value in pairs(cgi.params) do 4.105 - local status, stripped_key = string.match( 4.106 - key, "^_webmcp_routing%.([^%.]*)%.params%.(.*)$" 4.107 - ) 4.108 - if status == action_status then 4.109 - routing_params[stripped_key] = value 4.110 - end 4.111 - end 4.112 - request.redirect{ 4.113 - module = routing_module, 4.114 - view = routing_view, 4.115 - id = cgi.params["_webmcp_routing." .. action_status .. ".id"], 4.116 - params = routing_params, 4.117 - anchor = routing_anchor 4.118 - } 4.119 - elseif routing_mode == "forward" then 4.120 - request.forward{ module = routing_module, view = routing_view } 4.121 - else 4.122 - error("Missing or unknown routing mode in request parameters.") 4.123 - end 4.124 - end 4.125 - end 4.126 - else 4.127 - -- no action 4.128 - trace.request{ 4.129 - module = request.get_module(), 4.130 - view = request.get_view() 4.131 - } 4.132 - if 4.133 - request.get_404_route() and 4.134 - not file_exists( 4.135 - encode.view_file_path{ 4.136 - module = request.get_module(), 4.137 - view = request.get_view() 4.138 - } 4.139 - ) 4.140 - then 4.141 - request.set_status("404 Not Found") 4.142 - request.forward(request.get_404_route()) 4.143 - end 4.144 - end 4.145 - 4.146 - if not request.get_redirect_data() then 4.147 - request.process_forward() 4.148 - local view = request.get_view() 4.149 - if string.find(view, "^_") then 4.150 - error("Tried to call a private view (prefixed with underscore).") 4.151 - end 4.152 - execute.filtered_view{ 4.153 - module = request.get_module(), 4.154 - view = view, 4.155 - } 4.156 - end 4.157 - 4.158 - -- force error due to missing absolute base URL until its too late to display error message 4.159 - --if request.get_redirect_data() then 4.160 - -- request.get_absolute_baseurl() 4.161 - --end 4.162 - 4.163 - end, 4.164 - 4.165 - function(errobj) 4.166 - return { 4.167 - errobj = errobj, 4.168 - stacktrace = string.gsub( 4.169 - debug.traceback('', 2), 4.170 - "^\r?\n?stack traceback:\r?\n?", "" 4.171 - ) 4.172 - } 4.173 - end 4.174 - ) 4.175 - 4.176 - if not success then trace.error{} end 4.177 - 4.178 - -- laufzeitermittlung 4.179 - trace.exectime{ real = extos.monotonic_hires_time(), cpu = os.clock() } 4.180 - 4.181 - slot.select('trace', trace.render) -- render trace information 4.182 - 4.183 - local redirect_data = request.get_redirect_data() 4.184 - 4.185 - -- log error and switch to error layout, unless success 4.186 - if not success then 4.187 - local errobj = error_info.errobj 4.188 - local stacktrace = error_info.stacktrace 4.189 - if not request.get_status() and not request.get_json_request_slots() then 4.190 - request.set_status("500 Internal Server Error") 4.191 - end 4.192 - slot.set_layout('system_error') 4.193 - slot.select('system_error', function() 4.194 - if getmetatable(errobj) == mondelefant.errorobject_metatable then 4.195 - slot.put( 4.196 - "<p>Database error of class <b>", 4.197 - encode.html(errobj.code), 4.198 - "</b> occured:<br/><b>", 4.199 - encode.html(errobj.message), 4.200 - "</b></p>" 4.201 - ) 4.202 - else 4.203 - slot.put("<p><b>", encode.html(tostring(errobj)), "</b></p>") 4.204 - end 4.205 - slot.put("<p>Stack trace follows:<br/>") 4.206 - slot.put(encode.html_newlines(encode.html(stacktrace))) 4.207 - slot.put("</p>") 4.208 - end) 4.209 - elseif redirect_data then 4.210 - local redirect_params = {} 4.211 - for key, value in pairs(redirect_data.params) do 4.212 - redirect_params[key] = value 4.213 - end 4.214 - local slot_dump = slot.dump_all() 4.215 - if slot_dump ~= "" then 4.216 - redirect_params.tempstore = tempstore.save(slot_dump) 4.217 - end 4.218 - local json_request_slots = request.get_json_request_slots() 4.219 - if json_request_slots then 4.220 - redirect_params["_webmcp_json_slots[]"] = json_request_slots 4.221 - end 4.222 - cgi.redirect( 4.223 - encode.url{ 4.224 - base = request.get_absolute_baseurl(), 4.225 - module = redirect_data.module, 4.226 - view = redirect_data.view, 4.227 - id = redirect_data.id, 4.228 - params = redirect_params, 4.229 - anchor = redirect_data.anchor 4.230 - } 4.231 - ) 4.232 - cgi.send_data() 4.233 - end 4.234 - 4.235 - if not success or not redirect_data then 4.236 - 4.237 - local http_status = request.get_status() 4.238 - if http_status then 4.239 - cgi.set_status(http_status) 4.240 - end 4.241 - 4.242 - local json_request_slots = request.get_json_request_slots() 4.243 - if json_request_slots then 4.244 - cgi.set_content_type('application/json') 4.245 - local data = {} 4.246 - for idx, slot_ident in ipairs(json_request_slots) do 4.247 - data[slot_ident] = slot.get_content(slot_ident) 4.248 - end 4.249 - cgi.send_data(encode.json(data)) 4.250 - else 4.251 - cgi.set_content_type(slot.get_content_type()) 4.252 - cgi.send_data(slot.render_layout()) 4.253 - end 4.254 - end 4.255 - 4.256 -end 4.257 +--//--
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/framework/env/request/router.lua Mon Jan 12 01:48:11 2015 +0100 5.3 @@ -0,0 +1,12 @@ 5.4 +--[[-- 5.5 +request.router() 5.6 + 5.7 +Processes a request. May be overwritten by an application, calls request.default_router() in its default implementation. 5.8 + 5.9 +--]]-- 5.10 + 5.11 +function request.router() 5.12 + request.default_router() 5.13 +end 5.14 + 5.15 +--//--