op-packages/luci-app-run/root/www/cgi-bin/luci-app-run-upload
github-actions[bot] bd9e30ea67 🌴 Sync 2026-06-17 21:17:50
2026-06-17 21:17:50 +08:00

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"