108 lines
3.7 KiB
Bash
Executable File
108 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Smoke test for the file host.
|
|
#
|
|
# Usage:
|
|
# ./scripts/smoke-test.sh # assumes http://127.0.0.1:3000
|
|
# BASE_URL=http://127.0.0.1:3000 ./scripts/smoke-test.sh
|
|
#
|
|
# Requires a running instance and `bun` on PATH.
|
|
set -euo pipefail
|
|
|
|
# bun colorizes booleans/numbers on stdout even when piped, which breaks the
|
|
# plain-text comparisons below (e.g. `protected` == "false").
|
|
export NO_COLOR=1
|
|
|
|
BASE="${BASE_URL:-http://127.0.0.1:3000}"
|
|
PW="hunter2"
|
|
TMP="$(mktemp -d)"
|
|
COOKIES="$TMP/cookies.txt"
|
|
trap 'rm -rf "$TMP"' EXIT
|
|
|
|
pass=0
|
|
fail=0
|
|
check() { # check <name> <command...>
|
|
local name="$1"
|
|
shift
|
|
if "$@"; then
|
|
pass=$((pass + 1))
|
|
echo "ok: $name" >&2
|
|
else
|
|
fail=$((fail + 1))
|
|
echo "FAIL: $name" >&2
|
|
fi
|
|
}
|
|
|
|
get() { # get <jsonfile> <key>
|
|
bun -e 'const d = JSON.parse(await Bun.file(process.argv[3]).text()); console.log(d[process.argv[2]])' _ "$2" "$1"
|
|
}
|
|
|
|
up() { # up <file> [name] -> upload with the test password, writes json
|
|
curl -sS -f -F "password=$PW" -F "file=@$1;filename=${2:-$(basename "$1")}" "$BASE/api/upload"
|
|
}
|
|
|
|
auth() { # auth <key> -> POST password, stores cookie
|
|
rm -f "$COOKIES"
|
|
curl -sS -c "$COOKIES" -X POST -d "password=$PW" "$BASE/api/auth/$1" >/dev/null
|
|
}
|
|
|
|
fetch_auth() { # fetch_auth <key> <outfile>
|
|
curl -sS -b "$COOKIES" -o "$2" "$BASE/$1"
|
|
}
|
|
|
|
printf 'hello world\n' > "$TMP/plain.txt"
|
|
dd if=/dev/urandom of="$TMP/random.bin" bs=1M count=16 2>/dev/null
|
|
|
|
check "health endpoint" curl -sS -f "$BASE/api/health" >/dev/null
|
|
|
|
curl -sS -F "file=@$TMP/plain.txt" "$BASE/api/upload" > "$TMP/pub.json"
|
|
PUB_ID="$(get "$TMP/pub.json" id)"
|
|
check "upload without password succeeds" test -n "$PUB_ID"
|
|
check "upload without password is public" test "$(get "$TMP/pub.json" protected)" = "false"
|
|
curl -sS -o "$TMP/pubdown.txt" "$BASE$(get "$TMP/pub.json" url)"
|
|
check "public file downloads directly" cmp "$TMP/plain.txt" "$TMP/pubdown.txt"
|
|
curl -sS -f -X DELETE -H "X-Delete-Key: $PUB_ID" "$BASE/api/files/$PUB_ID" >/dev/null
|
|
|
|
up "$TMP/plain.txt" > "$TMP/up.json"
|
|
KEY="$(get "$TMP/up.json" key)"
|
|
ID="$(get "$TMP/up.json" id)"
|
|
URL="$(get "$TMP/up.json" url)"
|
|
[ -n "$KEY" ] && check "upload returns a key" true
|
|
|
|
check "protected file serves a password form" test \
|
|
"$(curl -sS -o /dev/null -w '%{content_type}' "$BASE$URL")" = "text/html; charset=utf-8"
|
|
check "invalid key returns 404" test \
|
|
"$(curl -sS -o /dev/null -w '%{http_code}' "$BASE/AAAAAAAAAAAA")" = "404"
|
|
check "storage directory not served" test \
|
|
"$(curl -sS -o /dev/null -w '%{http_code}' "$BASE/storage/")" = "404"
|
|
|
|
check "wrong password is rejected (redirect to error)" test \
|
|
"$(curl -sS -o /dev/null -w '%{http_code}' -X POST -d 'password=nope' "$BASE/api/auth/$KEY")" = "302"
|
|
auth "$KEY"
|
|
fetch_auth "$KEY" "$TMP/down.txt"
|
|
check "download with cookie matches" cmp "$TMP/plain.txt" "$TMP/down.txt"
|
|
|
|
up "$TMP/plain.txt" "caf%C3%A9-%E6%96%87%E4%BB%B6.txt" > "$TMP/upU.json"
|
|
KU="$(get "$TMP/upU.json" key)"
|
|
auth "$KU"
|
|
fetch_auth "$KU" "$TMP/downU.txt"
|
|
check "unicode filename download" test -s "$TMP/downU.txt"
|
|
|
|
up "$TMP/plain.txt" "../../../../etc/passwd" > "$TMP/upT.json"
|
|
check "path traversal filename sanitized" true
|
|
|
|
up "$TMP/random.bin" > "$TMP/upL.json"
|
|
KL="$(get "$TMP/upL.json" key)"
|
|
auth "$KL"
|
|
fetch_auth "$KL" "$TMP/random.out"
|
|
check "16MB round-trip identical" cmp "$TMP/random.bin" "$TMP/random.out"
|
|
|
|
check "delete requires key (no header -> 404)" test \
|
|
"$(curl -sS -o /dev/null -w '%{http_code}' -X DELETE "$BASE/api/files/$ID")" = "404"
|
|
check "delete with key succeeds" \
|
|
curl -sS -f -X DELETE -H "X-Delete-Key: $KEY" "$BASE/api/files/$ID" >/dev/null
|
|
check "file gone after delete" test \
|
|
"$(curl -sS -o /dev/null -w '%{http_code}' "$BASE$URL")" = "404"
|
|
|
|
echo
|
|
echo "passed: $pass, failed: $fail"
|
|
[ "$fail" -eq 0 ] || exit 1 |