plugins/mod_http_files.lua
author Kim Alvefur <zash@zash.se>
Sat, 23 Mar 2024 20:48:19 +0100
changeset 13465 c673ff1075bd
parent 13217 50324f66ca2a
permissions -rw-r--r--
mod_posix: Move everything to util.startup This allows greater control over the order of events. Notably, the internal ordering between daemonization, initialization of libunbound and setup of signal handling is sensitive. libunbound starts a separate thread for processing DNS requests. If this thread is started before signal handling has been set up, it will not inherit the signal handlers and instead behave as it would have before signal handlers were set up, i.e. cause the whole process to immediately exit. libunbound is usually initialized on the first DNS request, usually triggered by an outgoing s2s connection attempt. If daemonization happens before signals have been set up, signals may not be processed at all.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1384
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2785
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2785
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5718
diff changeset
     4
--
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1384
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1384
diff changeset
     6
-- COPYING file in the source package for more information.
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1384
diff changeset
     7
--
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1384
diff changeset
     8
4670
bd5e5e23942a mod_httpserver: Adapt to use the new HTTP API
Kim Alvefur <zash@zash.se>
parents: 3353
diff changeset
     9
module:depends("http");
635
25f1117d7886 Add initial mod_httpserver for serving static content
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
25f1117d7886 Add initial mod_httpserver for serving static content
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
local open = io.open;
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12601
diff changeset
    12
local fileserver = require"prosody.net.http.files";
635
25f1117d7886 Add initial mod_httpserver for serving static content
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
7994
35a02ba83af2 mod_http_files: Use path variant of config option API for http_files_dir
Kim Alvefur <zash@zash.se>
parents: 7988
diff changeset
    14
local base_path = module:get_option_path("http_files_dir", module:get_option_path("http_path"));
13217
50324f66ca2a plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents: 12981
diff changeset
    15
local cache_size = module:get_option_integer("http_files_cache_size", 128, 1);
50324f66ca2a plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents: 12981
diff changeset
    16
local cache_max_file_size = module:get_option_integer("http_files_cache_max_file_size", 4096, 1);
7980
01d6298de991 plugins/various: Use type-specific config API
Kim Alvefur <zash@zash.se>
parents: 7494
diff changeset
    17
local dir_indices = module:get_option_array("http_index_files", { "index.html", "index.htm" });
5261
b14f02671439 mod_http_files: Rename config options and variable names
Kim Alvefur <zash@zash.se>
parents: 5260
diff changeset
    18
local directory_index = module:get_option_boolean("http_dir_listing");
635
25f1117d7886 Add initial mod_httpserver for serving static content
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
5716
8a0465de172e mod_http_files: Put the MIME type map in a global shared table instead of per-host
Kim Alvefur <zash@zash.se>
parents: 5269
diff changeset
    20
local mime_map = module:shared("/*/http_files/mime").types;
5237
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    21
if not mime_map then
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    22
	mime_map = {
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    23
		html = "text/html", htm = "text/html",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    24
		xml = "application/xml",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    25
		txt = "text/plain",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    26
		css = "text/css",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    27
		js = "application/javascript",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    28
		png = "image/png",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    29
		gif = "image/gif",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    30
		jpeg = "image/jpeg", jpg = "image/jpeg",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    31
		svg = "image/svg+xml",
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    32
	};
5716
8a0465de172e mod_http_files: Put the MIME type map in a global shared table instead of per-host
Kim Alvefur <zash@zash.se>
parents: 5269
diff changeset
    33
	module:shared("/*/http_files/mime").types = mime_map;
5237
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    34
7988
6521a51bb718 mod_http_files: Pass only the name of the path, get_option_path knows how to deal with it
Kim Alvefur <zash@zash.se>
parents: 7981
diff changeset
    35
	local mime_types, err = open(module:get_option_path("mime_types_file", "/etc/mime.types", "config"), "r");
10552
c88f979946c4 mod_http_files: Log something if unable to load MIME database
Kim Alvefur <zash@zash.se>
parents: 9955
diff changeset
    36
	if not mime_types then
c88f979946c4 mod_http_files: Log something if unable to load MIME database
Kim Alvefur <zash@zash.se>
parents: 9955
diff changeset
    37
		module:log("debug", "Could not open MIME database: %s", err);
c88f979946c4 mod_http_files: Log something if unable to load MIME database
Kim Alvefur <zash@zash.se>
parents: 9955
diff changeset
    38
	else
5237
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    39
		local mime_data = mime_types:read("*a");
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    40
		mime_types:close();
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    41
		setmetatable(mime_map, {
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    42
			__index = function(t, ext)
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    43
				local typ = mime_data:match("\n(%S+)[^\n]*%s"..(ext:lower()).."%s") or "application/octet-stream";
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    44
				t[ext] = typ;
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    45
				return typ;
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    46
			end
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    47
		});
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    48
	end
b1038f449e15 mod_http_files: Have mimetypes in a shared table. Get mimetypes from /etc/mime.types if exists.
Kim Alvefur <zash@zash.se>
parents: 5236
diff changeset
    49
end
2771
c9834f338a4e mod_httpserver: Return Content-Type header based on file extension.
Waqas Hussain <waqas20@gmail.com>
parents: 1870
diff changeset
    50
9955
f1594893998f mod_http_files: Try to determine which module using serve() needs updating
Kim Alvefur <zash@zash.se>
parents: 9954
diff changeset
    51
local function get_calling_module()
f1594893998f mod_http_files: Try to determine which module using serve() needs updating
Kim Alvefur <zash@zash.se>
parents: 9954
diff changeset
    52
	local info = debug.getinfo(3, "S");
f1594893998f mod_http_files: Try to determine which module using serve() needs updating
Kim Alvefur <zash@zash.se>
parents: 9954
diff changeset
    53
	if not info then return "An unknown module"; end
f1594893998f mod_http_files: Try to determine which module using serve() needs updating
Kim Alvefur <zash@zash.se>
parents: 9954
diff changeset
    54
	return info.source:match"mod_[^/\\.]+" or info.short_src;
7061
e9f07febafb3 mod_http_files: Santize the path relative to our base URL before translating it to a filesystem path, fixes a relative path traversal vulnerability
Matthew Wild <mwild1@gmail.com>
parents: 6876
diff changeset
    55
end
e9f07febafb3 mod_http_files: Santize the path relative to our base URL before translating it to a filesystem path, fixes a relative path traversal vulnerability
Matthew Wild <mwild1@gmail.com>
parents: 6876
diff changeset
    56
9954
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    57
-- COMPAT -- TODO deprecate
5262
4e58fde55594 mod_http_files: Export function can be used by other modules to serve files. Don't serve files by default unless http_files_dir is set
Kim Alvefur <zash@zash.se>
parents: 5261
diff changeset
    58
function serve(opts)
5268
69964d1cbe66 mod_http_files: Allow passing a string to serve()
Kim Alvefur <zash@zash.se>
parents: 5265
diff changeset
    59
	if type(opts) ~= "table" then -- assume path string
69964d1cbe66 mod_http_files: Allow passing a string to serve()
Kim Alvefur <zash@zash.se>
parents: 5265
diff changeset
    60
		opts = { path = opts };
69964d1cbe66 mod_http_files: Allow passing a string to serve()
Kim Alvefur <zash@zash.se>
parents: 5265
diff changeset
    61
	end
9954
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    62
	if opts.directory_index == nil then
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    63
		opts.directory_index = directory_index;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    64
	end
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    65
	if opts.mime_map == nil then
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    66
		opts.mime_map = mime_map;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    67
	end
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    68
	if opts.cache_size == nil then
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    69
		opts.cache_size = cache_size;
3353
cd3cbf361f8f mod_httpserver: Serve index.html if a request is made for a directory and it contains one (thanks Brian Cully)
Matthew Wild <mwild1@gmail.com>
parents: 2925
diff changeset
    70
	end
9954
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    71
	if opts.cache_max_file_size == nil then
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    72
		opts.cache_max_file_size = cache_max_file_size;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    73
	end
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    74
	if opts.index_files == nil then
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    75
		opts.index_files = dir_indices;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    76
	end
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12601
diff changeset
    77
	module:log("warn", "%s should be updated to use 'prosody.net.http.files' instead of mod_http_files", get_calling_module());
9954
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    78
	return fileserver.serve(opts);
1667
c7bb2264e3b8 mod_httpserver: Set default file handler (you can now request static files as /*) and restructure code a bit
Matthew Wild <mwild1@gmail.com>
parents: 1552
diff changeset
    79
end
1770
3e17002221eb mod_httpserver: Backport from trunk more thorough validation of URLs prior to processing
Matthew Wild <mwild1@gmail.com>
parents: 1552
diff changeset
    80
5265
cc2aed452a62 mod_http_files: Expose function other modules can use to combine their routes with file paths to serve
Kim Alvefur <zash@zash.se>
parents: 5264
diff changeset
    81
function wrap_route(routes)
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12601
diff changeset
    82
	module:log("debug", "%s should be updated to use 'prosody.net.http.files' instead of mod_http_files", get_calling_module());
5265
cc2aed452a62 mod_http_files: Expose function other modules can use to combine their routes with file paths to serve
Kim Alvefur <zash@zash.se>
parents: 5264
diff changeset
    83
	for route,handler in pairs(routes) do
5268
69964d1cbe66 mod_http_files: Allow passing a string to serve()
Kim Alvefur <zash@zash.se>
parents: 5265
diff changeset
    84
		if type(handler) ~= "function" then
9954
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    85
			routes[route] = fileserver.serve(handler);
5265
cc2aed452a62 mod_http_files: Expose function other modules can use to combine their routes with file paths to serve
Kim Alvefur <zash@zash.se>
parents: 5264
diff changeset
    86
		end
cc2aed452a62 mod_http_files: Expose function other modules can use to combine their routes with file paths to serve
Kim Alvefur <zash@zash.se>
parents: 5264
diff changeset
    87
	end
cc2aed452a62 mod_http_files: Expose function other modules can use to combine their routes with file paths to serve
Kim Alvefur <zash@zash.se>
parents: 5264
diff changeset
    88
	return routes;
cc2aed452a62 mod_http_files: Expose function other modules can use to combine their routes with file paths to serve
Kim Alvefur <zash@zash.se>
parents: 5264
diff changeset
    89
end
1667
c7bb2264e3b8 mod_httpserver: Set default file handler (you can now request static files as /*) and restructure code a bit
Matthew Wild <mwild1@gmail.com>
parents: 1552
diff changeset
    90
9954
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    91
module:provides("http", {
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    92
	route = {
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    93
		["GET /*"] = fileserver.serve({
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    94
			path = base_path;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    95
			directory_index = directory_index;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    96
			mime_map = mime_map;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    97
			cache_size = cache_size;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    98
			cache_max_file_size = cache_max_file_size;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
    99
			index_files = dir_indices;
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
   100
		});
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
   101
	};
afc48785f738 mod_http_files: Use net.http.files
Kim Alvefur <zash@zash.se>
parents: 9466
diff changeset
   102
});