Для начала нужно уточнить, что я настоятельно не рекомендую использовать это решение в боевых условиях. Лучше вовсе так не делать никогда. Всё, что вы делаете, вы делаете на свой страх и риск. Причины, которые заставляют дать такой совет, будут приведены в содержании статьи. Если это предупреждение вас не отпугнуло, то добро пожаловать под кат.
Под «голым Nginx» понимается пакет для Ubuntu 16.04 из mainline ветки официального репозитория, который уже собран с ключом --with-http_dav_module.
Предполагается, что у вас уже есть настроенный nginx в такой же «комплектации», следовательно, ниже будет описываться лишь настройка нескольких location, которые вы добавите в свою секцию server конфига nginx.
В моём случае все временные файлы будут храниться в папке /var/www/upload по пути вида /random_folder_name/filename, где в качестве random_folder_name будет рандомная строка из нужного нам количества байт, потому создаём location вида:
location ~ ^/upload/([\w]+)/([^/]*)?$ {
root /var/www;
if ($request_method !~ ^(PUT|DELETE)$) {
return 444;
}
client_body_buffer_size 2M;
client_max_body_size 1G;
dav_methods PUT DELETE;
dav_access group:rw all:r;
create_full_put_path on;
}
curl -X PUT -T test.txt https://example.com/upload/random_folder_name/
curl -X DELETE https://example.com/upload/random_folder_name/
if ($http_token != "cb110ef4c4165e495001e297feae7092") {
return 444;
}
hexdump -n 16 -e '/4 "%x"' </dev/urandom
curl -X PUT -H "Token: cb110ef4c4165e495001e297feae7092" -T test.txt https://example.com/upload/random_folder_name/
curl -X DELETE -H "Token: cb110ef4c4165e495001e297feae7092" https://example.com/upload/random_folder_name/
location ~ ^/download/(?<folder>[\w]+)/([^/]*)$ {
root /var/www;
if ($request_method != GET) {
return 444;
}
rewrite ^/download/([\w]+)/([^/]*)$ /upload/$1/$2 break;
}
curl https://example.com/download/random_folder_name/test.txt
open_file_cache off;
types { }
default_type application/octet-stream;
add_header Content-Disposition "attachment";
add_header X-Content-Type-Options "nosniff";
location @delete {
proxy_method DELETE;
proxy_set_header Token "cb110ef4c4165e495001e297feae7092";
proxy_pass https://example.com/upload/$folder/;
}
post_action @delete;
location ~ ^/get/(?<folder>[\w]+)/(?<file>[^/]*)$ {
root /var/www;
ssi on;
if ($request_method != GET) {
return 444;
}
rewrite ^(.*)$ /download.html break;
}
<html>
<body>
After downloading this data will be destroyed
<form action='/download/<!--# echo var="folder" -->/<!--# echo var="file" -->' method="get" id="download"></form>
<p><button type="submit" form="download" value="Submit">Download</button></p>
</body>
</html>
if ($http_referer !~ ^https://example\.com/get/([\w]+)/([^/]*)$) {
return 444;
}
location ~ ^/upload/([\w]+)/([^/]*)?$ {
root /var/www;
if ($request_method !~ ^(PUT|DELETE)$) {
return 444;
}
if ($http_token != "cb110ef4c4165e495001e297feae7092") {
return 444;
}
client_body_buffer_size 2M;
client_max_body_size 1G;
dav_methods PUT DELETE;
dav_access group:rw all:r;
create_full_put_path on;
}
location ~ ^/get/(?<folder>[\w]+)/(?<file>[^/]*)$ {
root /var/www;
ssi on;
if ($request_method != GET) {
return 444;
}
rewrite ^(.*)$ /download.html break;
}
location ~ ^/download/(?<folder>[\w]+)/([^/]*)$ {
root /var/www;
open_file_cache off;
types { }
default_type application/octet-stream;
add_header Content-Disposition "attachment";
add_header X-Content-Type-Options "nosniff";
if ($request_method != GET) {
return 444;
}
if ($http_referer !~ ^https://example\.com/get/([\w]+)/([^/]*)$) {
return 444;
}
rewrite ^/download/([\w]+)/([^/]*)$ /upload/$1/$2 break;
post_action @delete;
}
location @delete {
proxy_method DELETE;
proxy_set_header Token "cb110ef4c4165e495001e297feae7092";
proxy_pass https://example.com/upload/$folder/;
}
upload() {
if [ $# -eq 0 ]; then
echo "Usage:
upload [file|folder] [option]
cat file | upload [name] [option]
Options:
gpg - Encrypt file. The folder is pre-packed to tar
gzip - Pack to gzip archive. The folder is pre-packed to tar
"
return 1
fi
uri="https://example.com/upload"
token="cb110ef4c4165e495001e297feae7092"
random=$(hexdump -n 8 -e '/4 "%x"' </dev/urandom)
if tty -s; then
name=$(basename "$1")
if [ "$2" = "gpg" ]; then
passphrase=$(tr -dc "[:graph:]" </dev/urandom | head -c16)
echo "$passphrase"
if [ "$1" = "-" ]; then
name=$(basename $(pwd))
tar cf - `ls -1 $(pwd)` | gpg --passphrase-file <(echo -n "$passphrase") --batch -ac -o- | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.tar.gpg" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ -d "$1" ]; then
tar cf - `ls -1 "$1"` | gpg --passphrase-file <(echo -n "$passphrase") --batch -ac -o- | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.tar.gpg" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ -f "$1" ]; then
gpg --passphrase-file <(echo -n "$passphrase") --batch -ac -o- "$1" | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.gpg" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
fi
elif [ "$2" = "gzip" ]; then
if [ "$1" = "-" ]; then
name=$(basename $(pwd))
tar czf - `ls -1 $(pwd)` | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.tar.gz" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ -d "$1" ]; then
tar czf - `ls -1 "$1"` | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.tar.gz" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ -f "$1" ]; then
gzip -c "$1" | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.gz" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
fi
else
if [ "$1" = "-" ]; then
name=$(basename $(pwd))
tar cf - `ls -1 $(pwd)` | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.tar" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ -d "$1" ]; then
tar cf - `ls -1 "$1"` | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$name.tar" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ -f "$1" ]; then
curl -I --progress-bar -H "Token: $token" -T "$1" "$uri/$random/$name" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
fi
fi
else
if [ "$2" = "gpg" ]; then
passphrase=$(tr -dc "[:graph:]" </dev/urandom | head -c16)
echo "$passphrase"
gpg --passphrase-file <(echo -n "$passphrase") --batch -ac -o- | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$1.gpg" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
elif [ "$2" = "gzip" ]; then
gzip | curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$1.gz" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
else
curl -I --progress-bar -H "Token: $token" -T "-" "$uri/$random/$1" | grep "Location: " | cut -d " " -f2 | sed "s'/upload/'/get/'g"
fi
fi
}
К сожалению, не доступен сервер mySQL