Comparison

net/http/server.lua @ 4710:54ca6511e699

net.http.server: Make error handling overrideable via 'http-error' event
author Matthew Wild <mwild1@gmail.com>
date Thu, 26 Apr 2012 15:14:19 +0100
parent 4709:98bfebb38705
child 4713:9c15fa5192d3
comparison
equal deleted inserted replaced
4709:98bfebb38705 4710:54ca6511e699
74 }); 74 });
75 75
76 local handle_request; 76 local handle_request;
77 local _1, _2, _3; 77 local _1, _2, _3;
78 local function _handle_request() return handle_request(_1, _2, _3); end 78 local function _handle_request() return handle_request(_1, _2, _3); end
79 local function _traceback_handler(err) log("error", "Traceback[http]: %s: %s", tostring(err), debug.traceback()); end 79
80 local last_err;
81 local function _traceback_handler(err) last_err = err; log("error", "Traceback[http]: %s: %s", tostring(err), debug.traceback()); end
82 events.add_handler("http-error", function (error)
83 return "Error processing request: "..codes[error.code]..". Check your error log for more information.";
84 end, -1);
80 85
81 function listener.onconnect(conn) 86 function listener.onconnect(conn)
82 local secure = conn:ssl() and true or nil; 87 local secure = conn:ssl() and true or nil;
83 local pending = {}; 88 local pending = {};
84 local waiting = false; 89 local waiting = false;
89 --log("debug", "process_next: %s", request.path); 94 --log("debug", "process_next: %s", request.path);
90 waiting = true; 95 waiting = true;
91 --handle_request(conn, request, process_next); 96 --handle_request(conn, request, process_next);
92 _1, _2, _3 = conn, request, process_next; 97 _1, _2, _3 = conn, request, process_next;
93 if not xpcall(_handle_request, _traceback_handler) then 98 if not xpcall(_handle_request, _traceback_handler) then
94 conn:write("HTTP/1.0 503 Internal Server Error\r\n\r\nAn error occured during the processing of this request."); 99 conn:write("HTTP/1.0 500 Internal Server Error\r\n\r\n"..events.fire_event("http-error", { code = 500, private_message = last_err }));
95 conn:close(); 100 conn:close();
96 end 101 end
97 else 102 else
98 --log("debug", "ready for more"); 103 --log("debug", "ready for more");
99 waiting = false; 104 waiting = false;
166 conn._http_open_response = response; 171 conn._http_open_response = response;
167 172
168 if not request.headers.host then 173 if not request.headers.host then
169 response.status_code = 400; 174 response.status_code = 400;
170 response.headers.content_type = "text/html"; 175 response.headers.content_type = "text/html";
171 response:send("<html><head>400 Bad Request</head><body>400 Bad Request: No Host header.</body></html>"); 176 response:send(events.fire_event("http-error", { code = 400, message = "No 'Host' header" }));
172 else 177 else
173 local host = request.headers.host; 178 local host = request.headers.host;
174 if host then 179 if host then
175 host = host:match("[^:]*"):lower(); 180 host = host:match("[^:]*"):lower();
176 local event = request.method.." "..host..request.path:match("[^?]*"); 181 local event = request.method.." "..host..request.path:match("[^?]*");
181 if result ~= true then 186 if result ~= true then
182 local code, body = 200, ""; 187 local code, body = 200, "";
183 local result_type = type(result); 188 local result_type = type(result);
184 if result_type == "number" then 189 if result_type == "number" then
185 response.status_code = result; 190 response.status_code = result;
191 if result >= 400 then
192 body = events.fire_event("http-error", { code = result });
193 end
186 elseif result_type == "string" then 194 elseif result_type == "string" then
187 body = result; 195 body = result;
188 elseif result_type == "table" then 196 elseif result_type == "table" then
189 body = result.body; 197 body = result.body;
190 result.body = nil; 198 result.body = nil;
199 end 207 end
200 208
201 -- if handler not called, return 404 209 -- if handler not called, return 404
202 response.status_code = 404; 210 response.status_code = 404;
203 response.headers.content_type = "text/html"; 211 response.headers.content_type = "text/html";
204 response:send("<html><head><title>404 Not Found</title></head><body>404 Not Found: No such page.</body></html>"); 212 response:send(events.fire_event("http-error", { code = 404 }));
205 end 213 end
206 end 214 end
207 function _M.send_response(response, body) 215 function _M.send_response(response, body)
208 if response.finished then return; end 216 if response.finished then return; end
209 response.finished = true; 217 response.finished = true;