Files
2026-07-26 05:15:08 +04:00

161 lines
4.3 KiB
Bash

#!/bin/sh
set -eu
PROXY_HOST="${PROXY_HOST:-proxy}"
PROXY_PORT="${PROXY_PORT:-3128}"
SOCKS_PORT="${SOCKS_PORT:-1080}"
TEST_HTTP_URL="${TEST_HTTP_URL:-http://api.ipify.org}"
TEST_HTTPS_URL="${TEST_HTTPS_URL:-https://api.ipify.org}"
TEST_ATTEMPTS="${TEST_ATTEMPTS:-20}"
TEST_RETRY_DELAY="${TEST_RETRY_DELAY:-1}"
TEST_TIMEOUT="${TEST_TIMEOUT:-15}"
EXPECTED_EXIT_IP="${EXPECTED_EXIT_IP:-}"
ASSERT_SAME_PROXY_EXIT="${ASSERT_SAME_PROXY_EXIT:-true}"
ASSERT_DIFFERENT_FROM_DIRECT="${ASSERT_DIFFERENT_FROM_DIRECT:-true}"
normalize_response() {
printf '%s' "$1" | tr -d '[:space:]'
}
request() {
label="$1"
proxy_url="$2"
target_url="$3"
attempt=1
while [ "$attempt" -le "$TEST_ATTEMPTS" ]; do
printf 'Testing %s, attempt %s/%s...\n' \
"$label" \
"$attempt" \
"$TEST_ATTEMPTS" >&2
if [ -n "$proxy_url" ]; then
if response="$(
curl -q \
--fail \
--silent \
--show-error \
--location \
--connect-timeout 5 \
--max-time "$TEST_TIMEOUT" \
--noproxy "" \
--proxy "$proxy_url" \
"$target_url" \
2>/tmp/curl-error
)"; then
response="$(normalize_response "$response")"
if [ -n "$response" ]; then
printf '%s' "$response"
return 0
fi
fi
else
if response="$(
curl -q \
--fail \
--silent \
--show-error \
--location \
--connect-timeout 5 \
--max-time "$TEST_TIMEOUT" \
--noproxy "*" \
"$target_url" \
2>/tmp/curl-error
)"; then
response="$(normalize_response "$response")"
if [ -n "$response" ]; then
printf '%s' "$response"
return 0
fi
fi
fi
attempt=$((attempt + 1))
if [ "$attempt" -le "$TEST_ATTEMPTS" ]; then
sleep "$TEST_RETRY_DELAY"
fi
done
printf '%s failed after %s attempts.\n' \
"$label" \
"$TEST_ATTEMPTS" >&2
if [ -s /tmp/curl-error ]; then
cat /tmp/curl-error >&2
fi
return 1
}
assert_expected_ip() {
label="$1"
actual="$2"
if [ "$actual" != "$EXPECTED_EXIT_IP" ]; then
printf 'FAIL: %s used an unexpected exit IP.\n' "$label" >&2
printf 'Expected: %s\n' "$EXPECTED_EXIT_IP" >&2
printf 'Actual: %s\n' "$actual" >&2
exit 1
fi
}
printf '%s\n' 'Starting 3proxy smoke tests...'
http_ip="$(
request \
'HTTP listener with an HTTP target' \
"http://${PROXY_HOST}:${PROXY_PORT}" \
"$TEST_HTTP_URL"
)"
https_ip="$(
request \
'HTTP listener with an HTTPS target' \
"http://${PROXY_HOST}:${PROXY_PORT}" \
"$TEST_HTTPS_URL"
)"
socks_ip="$(
request \
'SOCKS listener with remote DNS' \
"socks5h://${PROXY_HOST}:${SOCKS_PORT}" \
"$TEST_HTTPS_URL"
)"
printf 'HTTP target exit IP: %s\n' "$http_ip"
printf 'HTTPS target exit IP: %s\n' "$https_ip"
printf 'SOCKS exit IP: %s\n' "$socks_ip"
if [ -n "$EXPECTED_EXIT_IP" ]; then
assert_expected_ip 'HTTP target' "$http_ip"
assert_expected_ip 'HTTPS target' "$https_ip"
assert_expected_ip 'SOCKS target' "$socks_ip"
elif [ "$ASSERT_SAME_PROXY_EXIT" = 'true' ]; then
if [ "$http_ip" != "$https_ip" ] || [ "$http_ip" != "$socks_ip" ]; then
printf '%s\n' \
'FAIL: proxy listeners returned different exit IPs.' >&2
exit 1
fi
fi
if [ "$ASSERT_DIFFERENT_FROM_DIRECT" = 'true' ]; then
direct_ip="$(request 'direct connection' '' "$TEST_HTTPS_URL")"
printf 'Direct exit IP: %s\n' "$direct_ip"
if [ "$http_ip" = "$direct_ip" ] || \
[ "$https_ip" = "$direct_ip" ] || \
[ "$socks_ip" = "$direct_ip" ]; then
printf '%s\n' \
'FAIL: at least one proxied request used the direct exit IP.' >&2
exit 1
fi
fi
printf '%s\n' 'PASS: all proxy smoke tests succeeded.'