Last active
March 31, 2021 23:33
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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