mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 10:31:38 +08:00
102 lines
1.9 KiB
Bash
Executable File
102 lines
1.9 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
BASE_DIR="/tmp/luci-app-run"
|
|
UPLOAD_DIR="$BASE_DIR/uploads"
|
|
MAX_SIZE=$((256 * 1024 * 1024))
|
|
|
|
umask 077
|
|
|
|
header() {
|
|
printf 'Status: %s\r\n' "$1"
|
|
printf 'Content-Type: application/json\r\n'
|
|
printf 'Cache-Control: no-store\r\n'
|
|
printf '\r\n'
|
|
}
|
|
|
|
json_escape() {
|
|
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
|
|
}
|
|
|
|
fail() {
|
|
header "${2:-400 Bad Request}"
|
|
printf '{"code":1,"error":"%s"}\n' "$(json_escape "$1")"
|
|
exit 0
|
|
}
|
|
|
|
ok() {
|
|
header '200 OK'
|
|
printf '{"code":0,"size":%s}\n' "$1"
|
|
exit 0
|
|
}
|
|
|
|
urldecode() {
|
|
local value="${1//+/ }"
|
|
printf '%b' "${value//%/\\x}"
|
|
}
|
|
|
|
query_value() {
|
|
local key="$1" pair name value oldifs
|
|
oldifs="$IFS"
|
|
IFS='&'
|
|
for pair in $QUERY_STRING; do
|
|
name="${pair%%=*}"
|
|
value="${pair#*=}"
|
|
if [ "$name" = "$key" ]; then
|
|
IFS="$oldifs"
|
|
urldecode "$value"
|
|
return
|
|
fi
|
|
done
|
|
IFS="$oldifs"
|
|
}
|
|
|
|
valid_id() {
|
|
case "$1" in
|
|
""|*[!A-Za-z0-9_-]*) return 1 ;;
|
|
esac
|
|
return 0
|
|
}
|
|
|
|
[ "$REQUEST_METHOD" = "POST" ] || fail "POST required" "405 Method Not Allowed"
|
|
|
|
id="$(query_value id)"
|
|
token="$(query_value token)"
|
|
valid_id "$id" || fail "Invalid upload id"
|
|
[ -n "$token" ] || fail "Missing upload token"
|
|
|
|
dir="$UPLOAD_DIR/$id"
|
|
[ -d "$dir" ] || fail "Unknown upload id" "404 Not Found"
|
|
|
|
saved_token="$(cat "$dir/token" 2>/dev/null)"
|
|
[ "$token" = "$saved_token" ] || fail "Invalid upload token" "403 Forbidden"
|
|
|
|
name="$(cat "$dir/name" 2>/dev/null)"
|
|
case "$name" in
|
|
*.run)
|
|
;;
|
|
*.sh)
|
|
;;
|
|
*)
|
|
fail "Invalid filename"
|
|
;;
|
|
esac
|
|
|
|
length="${CONTENT_LENGTH:-0}"
|
|
[ "$length" -gt 0 ] 2>/dev/null || fail "Empty upload"
|
|
[ "$length" -le "$MAX_SIZE" ] 2>/dev/null || fail "File is larger than 256 MiB"
|
|
|
|
file="$dir/$name"
|
|
tmp="$file.upload"
|
|
|
|
cat > "$tmp" || fail "Unable to receive upload"
|
|
actual="$(wc -c < "$tmp" 2>/dev/null)"
|
|
[ "$actual" -eq "$length" ] 2>/dev/null || {
|
|
rm -f "$tmp"
|
|
fail "Upload size mismatch"
|
|
}
|
|
|
|
mv "$tmp" "$file" || fail "Unable to save upload"
|
|
chmod 700 "$file" || fail "Unable to chmod uploaded file"
|
|
|
|
ok "$actual"
|