Difference between revisions of "Remote media"
m (cat) |
ROllerozxa (talk | contribs) (elaborate) |
||
Line 1: | Line 1: | ||
− | + | When connecting to a server, Minetest allows for media to be received over a remote HTTP server, as opposed to "traditionally" over the UDP server connection (assuming Minetest is compiled with cURL support and <code>enable_remote_media_server</code> is enabled. | |
+ | Usually this is a more efficient means of transferring for servers with large amounts of media, even if you host the HTTP server on the same computer as the Minetest server it should still be able to download faster. It is also useful for Minetest servers hosted on a low speed residential internet connection, where the media downloading can be offloaded to make it significantly faster and dedicate more of the connection to communication with the Minetest server. | ||
+ | |||
+ | If a media file required on the server doesn't exist on the remote server or the media server can't be connected to for some reason, it will fall back to the traditional transfer method. This also applies if cURL support or the <code>enable_remote_media_server</code> setting is disabled. | ||
+ | |||
+ | == Technical info == | ||
+ | At first, the client will POST request <code>[remote_media]index.mth</code>, which contains the list of (SHA1) hashes that are available on the server. The client will then check what hashes it wants, but does not currently have cached, and requests <code>[remote_media][SHA1 hash]</code> for each one if it exists in the hash index. If it doesn't exist, it will fall back to traditional transfer. | ||
+ | |||
+ | Preferrably the server should support HTTP/2, though unfortunately the official Android and Windows builds do not come with a cURL linked against libnghttp2 currently. Linux however will usually be linked against a cURL system library that is linked against libnghttp2. | ||
+ | |||
+ | == Setting a remote media server == | ||
+ | Set the <code>remote_media</code> setting to the URL of the media server. Restart. | ||
+ | |||
+ | == Hosting a remote media server == | ||
+ | This section goes over hosting a remote media server statically, using nginx as the HTTP server. | ||
+ | |||
+ | First of all you need to populate the list of media and create an <code>index.mth</code> file, which contains a list of hashes that exist on the media server. This is a script you could run e.g. inside of a game's folder or a folder of mods: | ||
+ | |||
+ | <pre> | ||
+ | collect_from () { | ||
+ | echo "Processing media from: $1" | ||
+ | find -L "$1" -type f -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" -o -name "*.ogg" -o -name "*.x" -o -name "*.b3d" | while read f; do | ||
+ | basename "$f" | ||
+ | hash=`openssl dgst -sha1 <"$f" | cut -d " " -f 2` | ||
+ | cp "$f" media/$hash | ||
+ | done | ||
+ | } | ||
+ | |||
+ | mkdir -p media/ | ||
+ | # Change this 'collect_from' or add more lines of 'collect_from', the script will recursively | ||
+ | # search for files with extensions of Minetest media in this folder. | ||
+ | # This is an example to be run in a game folder, but you can change this to anything to catch | ||
+ | # all textures that a server uses. | ||
+ | collect_from mods/ | ||
+ | # Example for MineClone2 (they put textures in textures/ now) | ||
+ | #collect_from mods/ | ||
+ | #collect_from textures/ | ||
+ | |||
+ | printf "Creating index.mth... " | ||
+ | printf "MTHS\x00\x01" > media/index.mth | ||
+ | find media/ -type f -not -name index.mth | while read f; do | ||
+ | openssl dgst -binary -sha1 <$f >> media/index.mth | ||
+ | done | ||
+ | </pre> | ||
+ | |||
+ | You should now have a folder called <code>media</code> with a bunch of hashed filenames and an <code>index.mth</code> file. This can then be moved into a folder for nginx to host. | ||
+ | |||
+ | Unfortunately nginx does not allow POST requests on static files, so to make nginx able to send back the <code>index.mth</code> file which gets requested with POST you need to add this to the configuration for the site: | ||
+ | |||
+ | <pre> | ||
+ | error_page 405 =200 $uri; | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | == See Also == | ||
* [https://gist.github.com/sfan5/6351560 sfan5's remote media build script] | * [https://gist.github.com/sfan5/6351560 sfan5's remote media build script] | ||
* [https://forum.minetest.net/viewtopic.php?f=3&t=9260 Forum topic with comments] | * [https://forum.minetest.net/viewtopic.php?f=3&t=9260 Forum topic with comments] |
Revision as of 19:59, 15 February 2023
When connecting to a server, Minetest allows for media to be received over a remote HTTP server, as opposed to "traditionally" over the UDP server connection (assuming Minetest is compiled with cURL support and enable_remote_media_server
is enabled.
Usually this is a more efficient means of transferring for servers with large amounts of media, even if you host the HTTP server on the same computer as the Minetest server it should still be able to download faster. It is also useful for Minetest servers hosted on a low speed residential internet connection, where the media downloading can be offloaded to make it significantly faster and dedicate more of the connection to communication with the Minetest server.
If a media file required on the server doesn't exist on the remote server or the media server can't be connected to for some reason, it will fall back to the traditional transfer method. This also applies if cURL support or the enable_remote_media_server
setting is disabled.
Technical info
At first, the client will POST request [remote_media]index.mth
, which contains the list of (SHA1) hashes that are available on the server. The client will then check what hashes it wants, but does not currently have cached, and requests [remote_media][SHA1 hash]
for each one if it exists in the hash index. If it doesn't exist, it will fall back to traditional transfer.
Preferrably the server should support HTTP/2, though unfortunately the official Android and Windows builds do not come with a cURL linked against libnghttp2 currently. Linux however will usually be linked against a cURL system library that is linked against libnghttp2.
Setting a remote media server
Set the remote_media
setting to the URL of the media server. Restart.
Hosting a remote media server
This section goes over hosting a remote media server statically, using nginx as the HTTP server.
First of all you need to populate the list of media and create an index.mth
file, which contains a list of hashes that exist on the media server. This is a script you could run e.g. inside of a game's folder or a folder of mods:
collect_from () { echo "Processing media from: $1" find -L "$1" -type f -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" -o -name "*.ogg" -o -name "*.x" -o -name "*.b3d" | while read f; do basename "$f" hash=`openssl dgst -sha1 <"$f" | cut -d " " -f 2` cp "$f" media/$hash done } mkdir -p media/ # Change this 'collect_from' or add more lines of 'collect_from', the script will recursively # search for files with extensions of Minetest media in this folder. # This is an example to be run in a game folder, but you can change this to anything to catch # all textures that a server uses. collect_from mods/ # Example for MineClone2 (they put textures in textures/ now) #collect_from mods/ #collect_from textures/ printf "Creating index.mth... " printf "MTHS\x00\x01" > media/index.mth find media/ -type f -not -name index.mth | while read f; do openssl dgst -binary -sha1 <$f >> media/index.mth done
You should now have a folder called media
with a bunch of hashed filenames and an index.mth
file. This can then be moved into a folder for nginx to host.
Unfortunately nginx does not allow POST requests on static files, so to make nginx able to send back the index.mth
file which gets requested with POST you need to add this to the configuration for the site:
error_page 405 =200 $uri;