--
-local socket = require "socket"
local server = require "net.server"
local url_parse = require "socket.url".parse;
local httpstream_new = require "util.httpstream".new;
local listener;
local t_insert, t_concat = table.insert, table.concat;
-local s_match, s_gmatch = string.match, string.gmatch;
local tonumber, tostring, pairs, ipairs, type = tonumber, tostring, pairs, ipairs, type;
+local xpcall = xpcall;
+local debug_traceback = debug.traceback;
-local urlencode = function (s) return s and (s:gsub("%W", function (c) return string.format("%%%02x", c:byte()); end)); end
+local urlencode = function (s) return s and (s:gsub("%W", function (c) return ("%%%02x"):format(c:byte()); end)); end
local log = require "util.logger".init("httpserver");
local default_handler;
-local function expectbody(reqt)
- return reqt.method == "POST";
-end
-
local function send_response(request, response)
-- Write status line
local resp;
callback = (request.server and request.server.handlers[base]) or default_handler;
end
if callback then
+ local _callback = callback;
+ function callback(method, body, request)
+ local ok, result = xpcall(function() return _callback(method, body, request) end, debug_traceback);
+ if ok then return result; end
+ log("error", "Error in HTTP server handler: %s", result);
+ -- TODO: When we support pipelining, request.destroyed
+ -- won't be the right flag - we just want to see if there
+ -- has been a response to this request yet.
+ if not request.destroyed then
+ return {
+ status = "500 Internal Server Error";
+ headers = { ["Content-Type"] = "text/plain" };
+ body = "There was an error processing your request. See the error log for more details.";
+ };
+ end
+ end
if err then
log("debug", "Request error: "..err);
if not callback(nil, err, request) then
call_callback(request);
end
local function error_cb(r)
+ log("error", "Error in HTTP server handler: %s", r or "connection-closed");
call_callback(request, r or "connection-closed");
destroy_request(request);
end