plugins/mod_http_errors.lua
author Kim Alvefur <zash@zash.se>
Wed, 27 Mar 2024 19:33:11 +0100
changeset 13471 c2a476f4712a
parent 13397 f72ca74de456
permissions -rw-r--r--
util.startup: Fix exiting on pidfile trouble prosody.shutdown() relies on prosody.main_thread, which has not been set yet at this point. Doing a clean shutdown might actually be harmful in case it tears down things set up by the conflicting Prosody, such as the very pidfile we were looking at. Thanks again SigmaTel71 for noticing
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:set_global();
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11824
diff changeset
     3
local server = require "prosody.net.http.server";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11824
diff changeset
     4
local codes = require "prosody.net.http.codes";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11824
diff changeset
     5
local xml_escape = require "prosody.util.stanza".xml_escape;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 11824
diff changeset
     6
local render = require "prosody.util.interpolation".new("%b{}", xml_escape);
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local show_private = module:get_option_boolean("http_errors_detailed", false);
4737
7b9e2a8c4710 mod_http_errors: Add two new config options, http_errors_always_show (show even for unknown errors) and http_errors_default_message (message for unknown errors)
Matthew Wild <mwild1@gmail.com>
parents: 4711
diff changeset
     9
local always_serve = module:get_option_boolean("http_errors_always_show", true);
7b9e2a8c4710 mod_http_errors: Add two new config options, http_errors_always_show (show even for unknown errors) and http_errors_default_message (message for unknown errors)
Matthew Wild <mwild1@gmail.com>
parents: 4711
diff changeset
    10
local default_message = { module:get_option_string("http_errors_default_message", "That's all I know.") };
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
local default_messages = {
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
	[400] = { "What kind of request do you call that??" };
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
	[403] = { "You're not allowed to do that." };
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
	[404] = { "Whatever you were looking for is not here. %";
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
		"Where did you put it?", "It's behind you.", "Keep looking." };
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	[500] = { "% Check your error log for more info.";
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
		"Gremlins.", "It broke.", "Don't look at me." };
11407
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    18
	["/"] = {
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    19
		"A study in simplicity.";
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    20
		"Better catch it!";
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    21
		"Don't just stand there, go after it!";
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    22
		"Well, say something, before it runs too far!";
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    23
		"Welcome to the world of XMPP!";
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    24
		"You can do anything in XMPP!"; -- "The only limit is XML.";
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    25
		"You can do anything with Prosody!"; -- the only limit is memory?
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
    26
	};
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
};
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
local messages = setmetatable(module:get_option("http_errors_messages", {}), { __index = default_messages });
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
local html = [[
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
<!DOCTYPE html>
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
<html>
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
<head>
8367
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    35
<meta charset="utf-8">
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    36
<title>{title}</title>
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    37
<style>
13397
f72ca74de456 mod_http_errors: Simplify CSS via built-in dark mode
Kim Alvefur <zash@zash.se>
parents: 12981
diff changeset
    38
:root{color-scheme:light dark}
f72ca74de456 mod_http_errors: Simplify CSS via built-in dark mode
Kim Alvefur <zash@zash.se>
parents: 12981
diff changeset
    39
body{margin-top:14%;text-align:center;font-family:sans-serif}
11392
60a61c509d87 mod_http_errors: Minify CSS
Kim Alvefur <zash@zash.se>
parents: 11159
diff changeset
    40
h1{font-size:xx-large}
60a61c509d87 mod_http_errors: Minify CSS
Kim Alvefur <zash@zash.se>
parents: 11159
diff changeset
    41
p{font-size:x-large}
11399
d336b28b4002 mod_http_errors: Style tweak
Kim Alvefur <zash@zash.se>
parents: 11394
diff changeset
    42
p.warning>span{font-size:large;background-color:yellow}
11392
60a61c509d87 mod_http_errors: Minify CSS
Kim Alvefur <zash@zash.se>
parents: 11159
diff changeset
    43
p.extra{font-size:large;font-family:courier}
60a61c509d87 mod_http_errors: Minify CSS
Kim Alvefur <zash@zash.se>
parents: 11159
diff changeset
    44
@media(prefers-color-scheme:dark){
11399
d336b28b4002 mod_http_errors: Style tweak
Kim Alvefur <zash@zash.se>
parents: 11394
diff changeset
    45
p.warning>span{background-color:inherit;color:yellow}
11158
dd81a318a794 mod_http_errors: Dark theme!
Kim Alvefur <zash@zash.se>
parents: 11157
diff changeset
    46
}
8367
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    47
</style>
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
</head>
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
<body>
11666
a8798e04b5c8 mod_http_errors: Allow adding icons on error pages
Kim Alvefur <zash@zash.se>
parents: 11408
diff changeset
    50
<h1>{icon?{icon_raw!?}} {title}</h1>
8367
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    51
<p>{message}</p>
11399
d336b28b4002 mod_http_errors: Style tweak
Kim Alvefur <zash@zash.se>
parents: 11394
diff changeset
    52
{warning&<p class="warning"><span>&#9888; {warning?} &#9888;</span></p>}
11159
8d692a8a8f48 mod_http_errors: Remove 'extra' element when empty
Kim Alvefur <zash@zash.se>
parents: 11158
diff changeset
    53
{extra&<p class="extra">{extra?}</p>}
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
</body>
7495
9a749cf8c1ba mod_http_errors: Add a newline after end of HTML
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
    55
</html>
9a749cf8c1ba mod_http_errors: Add a newline after end of HTML
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
    56
]];
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
local function get_page(code, extra)
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	local message = messages[code];
4737
7b9e2a8c4710 mod_http_errors: Add two new config options, http_errors_always_show (show even for unknown errors) and http_errors_default_message (message for unknown errors)
Matthew Wild <mwild1@gmail.com>
parents: 4711
diff changeset
    60
	if always_serve or message then
7b9e2a8c4710 mod_http_errors: Add two new config options, http_errors_always_show (show even for unknown errors) and http_errors_default_message (message for unknown errors)
Matthew Wild <mwild1@gmail.com>
parents: 4711
diff changeset
    61
		message = message or default_message;
8367
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    62
		return render(html, {
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
			title = rawget(codes, code) or ("Code "..tostring(code));
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
			message = message[1]:gsub("%%", function ()
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
				return message[math.random(2, math.max(#message,2))];
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
			end);
8367
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    67
			extra = extra;
f91ab40a3105 mod_http_errors: Use util.interpolation to render HTML template
Kim Alvefur <zash@zash.se>
parents: 8366
diff changeset
    68
		});
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	end
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
end
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
11408
f7704f987439 mod_http_errors: Add some comments
Kim Alvefur <zash@zash.se>
parents: 11407
diff changeset
    72
-- Main error page handler
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
module:hook_object_event(server, "http-error", function (event)
8366
e2460edc2a2f mod_http_errors: Set Content-Type header to HTML (fixes #1030)
Kim Alvefur <zash@zash.se>
parents: 7495
diff changeset
    74
	if event.response then
e2460edc2a2f mod_http_errors: Set Content-Type header to HTML (fixes #1030)
Kim Alvefur <zash@zash.se>
parents: 7495
diff changeset
    75
		event.response.headers.content_type = "text/html; charset=utf-8";
e2460edc2a2f mod_http_errors: Set Content-Type header to HTML (fixes #1030)
Kim Alvefur <zash@zash.se>
parents: 7495
diff changeset
    76
	end
10578
f70c874b7936 mod_http_errors: Use text from util.errror object if included
Kim Alvefur <zash@zash.se>
parents: 10434
diff changeset
    77
	return get_page(event.code, (show_private and event.private_message) or event.message or (event.error and event.error.text));
4711
4ddf3ba0c749 mod_http_errors: Module to handle HTTP errors with a HTML page
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
end);
10434
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
    79
11408
f7704f987439 mod_http_errors: Add some comments
Kim Alvefur <zash@zash.se>
parents: 11407
diff changeset
    80
-- Way to use the template for other things so to give a consistent appearance
11393
29e7ed75ed3f mod_http_errors: Add way to reuse the error page template
Kim Alvefur <zash@zash.se>
parents: 11392
diff changeset
    81
module:hook("http-message", function (event)
29e7ed75ed3f mod_http_errors: Add way to reuse the error page template
Kim Alvefur <zash@zash.se>
parents: 11392
diff changeset
    82
	if event.response then
29e7ed75ed3f mod_http_errors: Add way to reuse the error page template
Kim Alvefur <zash@zash.se>
parents: 11392
diff changeset
    83
		event.response.headers.content_type = "text/html; charset=utf-8";
29e7ed75ed3f mod_http_errors: Add way to reuse the error page template
Kim Alvefur <zash@zash.se>
parents: 11392
diff changeset
    84
	end
29e7ed75ed3f mod_http_errors: Add way to reuse the error page template
Kim Alvefur <zash@zash.se>
parents: 11392
diff changeset
    85
	return render(html, event);
11824
0375ef78ed64 mod_http_errors: Make it easier to override 'http-message' handler
Kim Alvefur <zash@zash.se>
parents: 11668
diff changeset
    86
end, -1);
11393
29e7ed75ed3f mod_http_errors: Add way to reuse the error page template
Kim Alvefur <zash@zash.se>
parents: 11392
diff changeset
    87
11667
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    88
local icon = [[
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    89
<svg xmlns="http://www.w3.org/2000/svg" height="0.7em" viewBox="0 0 480 480" width="0.7em">
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    90
<rect fill="#6197df" height="220" rx="60" ry="60" width="220" x="10" y="10"></rect>
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    91
<rect fill="#f29b00" height="220" rx="60" ry="60" width="220" x="10" y="240"></rect>
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    92
<rect fill="#f29b00" height="220" rx="60" ry="60" width="220" x="240" y="10"></rect>
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    93
<rect fill="#6197df" height="220" rx="60" ry="60" width="220" x="240" y="240"></rect>
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    94
</svg>
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    95
]];
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
    96
11408
f7704f987439 mod_http_errors: Add some comments
Kim Alvefur <zash@zash.se>
parents: 11407
diff changeset
    97
-- Something nicer shown instead of 404 at the root path, if nothing else handles this path
10434
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
    98
module:hook_object_event(server, "http-error", function (event)
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
    99
	local request, response = event.request, event.response;
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   100
	if request and response and request.path == "/" and response.status_code == 404 then
11668
d83f8f44caea mod_http_errors: Set status code 200 from root page
Kim Alvefur <zash@zash.se>
parents: 11667
diff changeset
   101
		response.status_code = 200;
10434
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   102
		response.headers.content_type = "text/html; charset=utf-8";
11407
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
   103
		local message = messages["/"];
10434
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   104
		return render(html, {
11667
04fa947784bc mod_http_errors: Add a Prosody logo to root page
Kim Alvefur <zash@zash.se>
parents: 11666
diff changeset
   105
				icon_raw = icon,
10434
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   106
				title = "Prosody is running!";
11407
747e8245f180 mod_http_errors: Add some silly variations for the '/' page
Kim Alvefur <zash@zash.se>
parents: 11399
diff changeset
   107
				message = message[math.random(#message)];
10434
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   108
			});
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   109
	end
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   110
end, 1);
46dd9df2db0c mod_http_errors: Show a friendly page instead of 404 on top level
Kim Alvefur <zash@zash.se>
parents: 9764
diff changeset
   111