plugins/mod_http_files.lua
author Kim Alvefur <zash@zash.se>
Sun, 24 Mar 2024 21:32:00 +0100
changeset 13468 2dbc169aae6a
parent 13217 50324f66ca2a
permissions -rw-r--r--
util.startup: Abort before initialization of logging when started as root Prevents creation of log files owned by the root user which could be inaccessible once started correctly.
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
});