Skip to content

Instantly share code, notes, and snippets.

@efrecon
Last active March 31, 2021 23:33
Show Gist options
  • Save efrecon/b39eebb1e7f33eec0980db50aa6d54ec to your computer and use it in GitHub Desktop.
Save efrecon/b39eebb1e7f33eec0980db50aa6d54ec to your computer and use it in GitHub Desktop.
Check URL return code against set of possible answers, defaults to 2XX. Good for internal Docker healthcheck.
#!/bin/sh
# Check if the URL passed as a first argument maches some of the HTTP codes that
# are passed in the following arguments as regular expressions. The list of
# error codes can be omitted, in which case this will be the whole "OK" range,
# from 200 to 299. When the remote site answers one of the matching code an
# exit code of 0 is returned, otherwise an error is returned.
#
# Additional options can be passed:
# -v to increase verbosity.
# -T to specify a timeout (in seconds) to wait for an answer.
# -c to print back the code instead (see below)
#
# When -c is specified, the behaviour will change so that a status report is
# returned instead. The report consists of the string OK or ERR, followed by a
# colon sign, followed by the actual HTTP code.
#
# URL checking is performed either by wget or curl, if present and in order. The
# code is written so that it will also work with the limited wget that is part
# of busybox-based environments.
VERBOSE=0
TIMEOUT=30
CODE_PRINT=0
while [ $# -gt 0 ]
do
case "$1" in
-v | --verbose)
VERBOSE=1
shift 1
;;
-c | --code)
CODE_PRINT=1
shift 1
;;
-T | --timeout)
TIMEOUT=$2
shift 2
;;
*)
break
;;
esac
done
log() {
if [ "$VERBOSE" -ne 0 ]; then echo "$1" 1>&2; fi
}
# First argument is the URL
URL=$1
shift
if [ "$#" -eq 0 ]; then
log "No code specified, assuming 2XX"
EXPRESSIONS="2[0-9]+"
else
EXPRESSIONS=$*
fi
CURL=$(command -v curl || true)
WGET=$(command -v wget || true)
if [ -n "$WGET" ]; then
log "Testing access to $URL with $WGET"
CODE=$( "$WGET" -O- -S --spider -q -T "$TIMEOUT" "$URL" 2>&1 |
grep -E 'HTTP/[0-9.]+ ([0-9]+) ' |
sed -E 's/.*([0-9]{3}).*/\1/' |
tail -1 )
elif [ -n "$CURL" ]; then
log "Testing access to $URL with $CURL"
CODE=$( "$CURL" -qLsIS -m "$TIMEOUT" "$URL" 2>&1 |
grep -E 'HTTP/[0-9.]+ ([0-9]+) ' |
sed -E 's/.*([0-9]{3}).*/\1/' |
tail -1 )
else
log "CANNOT test access to $URL, neither curl, nor wget found!"
exit 1
fi
log "Access to $URL responded $CODE"
for xpr in ${EXPRESSIONS}; do
match=$(echo "$CODE" | grep -E "${xpr}")
if [ -n "$match" ]; then
log "Success: $CODE matched $xpr"
if [ "$CODE_PRINT" -ne 0 ]; then echo "OK:$CODE"; fi
exit 0
fi
done
if [ -z "$CODE" ]; then
CODE=499
fi
# Either we print the HTTP code and exit cleanly, or exit with the code for a
# failure.
log "Failure: $CODE did not match any of ${EXPRESSIONS}"
if [ "$CODE_PRINT" -ne 0 ]; then
echo "ERR:$CODE"
exit 0
else
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment