webmcp
changeset 459:dc6d3719f2e7
Support of HTTP OPTIONS requests; Error handling in router
author | jbe |
---|---|
date | Tue Jul 26 15:35:37 2016 +0200 (2016-07-26) |
parents | 6bbef2933ea5 |
children | ffdfd54ba881 |
files | framework/env/request/__init.lua framework/env/request/handler.lua |
line diff
1.1 --- a/framework/env/request/__init.lua Mon Jul 25 22:49:40 2016 +0200 1.2 +++ b/framework/env/request/__init.lua Tue Jul 26 15:35:37 2016 +0200 1.3 @@ -16,6 +16,7 @@ 1.4 1.5 request.for_each(function() 1.6 1.7 + request._route = nil 1.8 request._absolute_baseurl = nil 1.9 request._response_headers = {} 1.10 request._force_absolute_baseurl = false
2.1 --- a/framework/env/request/handler.lua Mon Jul 25 22:49:40 2016 +0200 2.2 +++ b/framework/env/request/handler.lua Tue Jul 26 15:35:37 2016 +0200 2.3 @@ -9,6 +9,7 @@ 2.4 --]]-- 2.5 2.6 function request.handler(http_request) 2.7 + 2.8 request._http_request = http_request 2.9 local path = http_request.path 2.10 if path then 2.11 @@ -24,17 +25,36 @@ 2.12 else 2.13 request._relative_baseurl = nil 2.14 end 2.15 - request._route = request.router() 2.16 - do 2.17 - local post_id = http_request.post_params["_webmcp_id"] 2.18 - if post_id then 2.19 - request._route.id = post_id 2.20 - end 2.21 - end 2.22 2.23 local success, error_info = xpcall( 2.24 function() 2.25 2.26 + local function require_method(errmsg, ...) 2.27 + for i = 2, select("#", ...) do 2.28 + if http_request.method == select(i, ...) then return end 2.29 + end 2.30 + request.set_status("405 Method Not Allowed") 2.31 + request.add_header("Allow", table.concat({...}, ", ")) 2.32 + error(errmsg) 2.33 + end 2.34 + 2.35 + request._route = request.router() 2.36 + do 2.37 + local post_id = http_request.post_params["_webmcp_id"] 2.38 + if post_id then 2.39 + request._route.id = post_id 2.40 + end 2.41 + end 2.42 + local options_handler = loadcached(encode.file_path( 2.43 + WEBMCP_BASE_PATH, 'app', WEBMCP_APP_NAME, 'http_options.lua' 2.44 + )) 2.45 + if options_handler then 2.46 + options_handler() 2.47 + end 2.48 + if http_request.method == "OPTIONS" then 2.49 + return 2.50 + end 2.51 + 2.52 if not request._route then 2.53 request._route = {} 2.54 if request.get_404_route() then 2.55 @@ -75,6 +95,10 @@ 2.56 error('Could not open static file "' .. subpath .. '": ' .. errmsg) 2.57 end 2.58 else 2.59 + require_method( 2.60 + "Invalid HTTP method for static file", 2.61 + "HEAD", "GET", "POST" 2.62 + ) 2.63 local d = assert(f:read("*a")) 2.64 f:close() 2.65 slot.put_into("data", d) 2.66 @@ -111,11 +135,10 @@ 2.67 request.set_status("404 Not Found") 2.68 request.forward(request.get_404_route()) 2.69 else 2.70 - if http_request.method ~= "POST" then 2.71 - request.set_status("405 Method Not Allowed") 2.72 - request.add_header("Allow", "POST") 2.73 - error("Tried to invoke an action with a GET request.") 2.74 - end 2.75 + require_method( 2.76 + "Invalid HTTP method for action (POST request required)", 2.77 + "POST" 2.78 + ) 2.79 local action_status = execute.filtered_action{ 2.80 module = request.get_module(), 2.81 action = request.get_action(), 2.82 @@ -183,6 +206,10 @@ 2.83 if string.find(view, "^_") then 2.84 error("Tried to call a private view (prefixed with underscore).") 2.85 end 2.86 + require_method( 2.87 + "Invalid HTTP method", 2.88 + "HEAD", "GET", "POST" 2.89 + ) 2.90 execute.filtered_view{ 2.91 module = request.get_module(), 2.92 view = view,