plugins/mod_http_errors.lua
changeset 8367 f91ab40a3105
parent 8366 e2460edc2a2f
child 9764 88640b3ea6b8
equal deleted inserted replaced
8366:e2460edc2a2f 8367:f91ab40a3105
     1 module:set_global();
     1 module:set_global();
     2 
     2 
     3 local server = require "net.http.server";
     3 local server = require "net.http.server";
     4 local codes = require "net.http.codes";
     4 local codes = require "net.http.codes";
       
     5 local xml_escape = require "util.stanza".xml_escape;
       
     6 local render = require "util.interpolation".new("%b{}", xml_escape);
     5 
     7 
     6 local show_private = module:get_option_boolean("http_errors_detailed", false);
     8 local show_private = module:get_option_boolean("http_errors_detailed", false);
     7 local always_serve = module:get_option_boolean("http_errors_always_show", true);
     9 local always_serve = module:get_option_boolean("http_errors_always_show", true);
     8 local default_message = { module:get_option_string("http_errors_default_message", "That's all I know.") };
    10 local default_message = { module:get_option_string("http_errors_default_message", "That's all I know.") };
     9 local default_messages = {
    11 local default_messages = {
    19 
    21 
    20 local html = [[
    22 local html = [[
    21 <!DOCTYPE html>
    23 <!DOCTYPE html>
    22 <html>
    24 <html>
    23 <head>
    25 <head>
    24 	<meta charset="utf-8">
    26 <meta charset="utf-8">
    25 	<style>
    27 <title>{title}</title>
    26 		body{
    28 <style>
    27 			margin-top:14%;
    29 body{
    28 			text-align:center;
    30 	margin-top:14%;
    29 			background-color:#F8F8F8;
    31 	text-align:center;
    30 			font-family:sans-serif;
    32 	background-color:#F8F8F8;
    31 		}
    33 	font-family:sans-serif;
    32 		h1{
    34 }
    33 			font-size:xx-large;
    35 h1{
    34 		}
    36 	font-size:xx-large;
    35 		p{
    37 }
    36 			font-size:x-large;
    38 p{
    37 		}
    39 	font-size:x-large;
    38 		p+p { font-size: large; font-family: courier }
    40 }
    39         </style>
    41 p+p {
       
    42 	font-size:large;
       
    43 	font-family:courier;
       
    44 }
       
    45 </style>
    40 </head>
    46 </head>
    41 <body>
    47 <body>
    42         <h1>$title</h1>
    48 <h1>{title}</h1>
    43         <p>$message</p>
    49 <p>{message}</p>
    44         <p>$extra</p>
    50 <p>{extra?}</p>
    45 </body>
    51 </body>
    46 </html>
    52 </html>
    47 ]];
    53 ]];
    48 html = html:gsub("%s%s+", "");
       
    49 
       
    50 local entities = {
       
    51 	["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;",
       
    52 	["'"] = "&apos;", ["\""] = "&quot;", ["\n"] = "<br/>",
       
    53 };
       
    54 
       
    55 local function tohtml(plain)
       
    56 	return (plain:gsub("[<>&'\"\n]", entities));
       
    57 
       
    58 end
       
    59 
    54 
    60 local function get_page(code, extra)
    55 local function get_page(code, extra)
    61 	local message = messages[code];
    56 	local message = messages[code];
    62 	if always_serve or message then
    57 	if always_serve or message then
    63 		message = message or default_message;
    58 		message = message or default_message;
    64 		return (html:gsub("$(%a+)", {
    59 		return render(html, {
    65 			title = rawget(codes, code) or ("Code "..tostring(code));
    60 			title = rawget(codes, code) or ("Code "..tostring(code));
    66 			message = message[1]:gsub("%%", function ()
    61 			message = message[1]:gsub("%%", function ()
    67 				return message[math.random(2, math.max(#message,2))];
    62 				return message[math.random(2, math.max(#message,2))];
    68 			end);
    63 			end);
    69 			extra = tohtml(extra or "");
    64 			extra = extra;
    70 		}));
    65 		});
    71 	end
    66 	end
    72 end
    67 end
    73 
    68 
    74 module:hook_object_event(server, "http-error", function (event)
    69 module:hook_object_event(server, "http-error", function (event)
    75 	if event.response then
    70 	if event.response then