# HG changeset patch # User jbe # Date 1469540137 -7200 # Node ID dc6d3719f2e79b7a6605e110ffb3022f821ce011 # Parent 6bbef2933ea525fc341db448286c72c825d6c0e1 Support of HTTP OPTIONS requests; Error handling in router diff -r 6bbef2933ea5 -r dc6d3719f2e7 framework/env/request/__init.lua --- a/framework/env/request/__init.lua Mon Jul 25 22:49:40 2016 +0200 +++ b/framework/env/request/__init.lua Tue Jul 26 15:35:37 2016 +0200 @@ -16,6 +16,7 @@ request.for_each(function() + request._route = nil request._absolute_baseurl = nil request._response_headers = {} request._force_absolute_baseurl = false diff -r 6bbef2933ea5 -r dc6d3719f2e7 framework/env/request/handler.lua --- a/framework/env/request/handler.lua Mon Jul 25 22:49:40 2016 +0200 +++ b/framework/env/request/handler.lua Tue Jul 26 15:35:37 2016 +0200 @@ -9,6 +9,7 @@ --]]-- function request.handler(http_request) + request._http_request = http_request local path = http_request.path if path then @@ -24,17 +25,36 @@ else request._relative_baseurl = nil end - request._route = request.router() - do - local post_id = http_request.post_params["_webmcp_id"] - if post_id then - request._route.id = post_id - end - end local success, error_info = xpcall( function() + local function require_method(errmsg, ...) + for i = 2, select("#", ...) do + if http_request.method == select(i, ...) then return end + end + request.set_status("405 Method Not Allowed") + request.add_header("Allow", table.concat({...}, ", ")) + error(errmsg) + end + + request._route = request.router() + do + local post_id = http_request.post_params["_webmcp_id"] + if post_id then + request._route.id = post_id + end + end + local options_handler = loadcached(encode.file_path( + WEBMCP_BASE_PATH, 'app', WEBMCP_APP_NAME, 'http_options.lua' + )) + if options_handler then + options_handler() + end + if http_request.method == "OPTIONS" then + return + end + if not request._route then request._route = {} if request.get_404_route() then @@ -75,6 +95,10 @@ error('Could not open static file "' .. subpath .. '": ' .. errmsg) end else + require_method( + "Invalid HTTP method for static file", + "HEAD", "GET", "POST" + ) local d = assert(f:read("*a")) f:close() slot.put_into("data", d) @@ -111,11 +135,10 @@ request.set_status("404 Not Found") request.forward(request.get_404_route()) else - if http_request.method ~= "POST" then - request.set_status("405 Method Not Allowed") - request.add_header("Allow", "POST") - error("Tried to invoke an action with a GET request.") - end + require_method( + "Invalid HTTP method for action (POST request required)", + "POST" + ) local action_status = execute.filtered_action{ module = request.get_module(), action = request.get_action(), @@ -183,6 +206,10 @@ if string.find(view, "^_") then error("Tried to call a private view (prefixed with underscore).") end + require_method( + "Invalid HTTP method", + "HEAD", "GET", "POST" + ) execute.filtered_view{ module = request.get_module(), view = view,