Check HTTP page rendering, log an error if it does not render.
#!/usr/bin/ksh93.att
#################################################################
#### !!! Download the latest version of ksh93 to run this script.
#################################################################
function usagemsg_ckhttp_k93 {
print -u 2 -- "
Program: ckhttp_k93
Determine if a Web page is accessible by specifying a host name,
port number, and web page location.
Usage: ${1##*/} [-?] [-vV] [-u url]
[-t type] [-c class] [-l logFile]
Where:
-u url = http://nodeName:port/path/to/page
-t type = Log Message type: ERROR, WARN (Default:ERROR)
-c class = Log Message class: O, S, U (Default:O)
-l logFile = Log file name (Default:/var/log/ckhttp.log)
-s = Log successful responses (Default:only log errors)
-v = Verbose Mode
-V = Very Verbose Mode
Author: Dana French (dfrench@mtxia.com)
Copyright 2009 by Dana French: All Rights Reserved
\"AutoContent\" enabled
"
}
################################################################
####
#### Description:
####
#### Determine if a Web page is accessible by specifying a host name,
#### port number, and web page location.
####
#### Assumptions:
####
#### The user specified URL must be in one of the following format:
####
#### http://hostname.domain:PortNumber/web/page/location/index.html
#### https://hostname.domain:PortNumber/web/page/location/index.html
####
#### Example URLs:
####
#### http://www.mtxia.com:80/js/index.shtml
#### https://www.mtxia.com:443/secure/index.php
####
#### The URL must begin with "http://" or "https://".
#### Only "http" and "https" protocols are currently supported.
#### The hostname must be resolvable to an IP address.
#### The port number must be one or more digits.
#### If no port number is specified, port number "80" is assumed.
####
#### Dependencies:
####
#### This function requires a recent version of ksh93. The version
#### shipped with AIX is INSUFFICIENT to run this script. Download
#### the latest ksh93 AIX binary from http://www.kornshell.com
####
#### If you download the latest ksh93 AIX binary, place it on your
#### system at the location /usr/bin/ksh93.att. Do not overwrite
#### the existing /usr/bin/ksh93. Then modify the shebang line
#### to use #!/usr/bin/ksh93.att
####
#### Products:
####
#### This function records error messages to a default or
#### user specified log file. The return code from this
#### function can be used to indicate success or failure to
#### resolve the user specified hostname.
####
#### Configured Usage:
####
#### This function may be executed from the command line or
#### included in a script function library.
####
#### Details:
####
################################################################
function ckhttp_k93 {
typeset VERSION="1.1"
typeset TRUE="0"
typeset FALSE="1"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset PORTNUM="80"
typeset PORTCHK="${PORTNUM}"
typeset NODENAME=""
typeset TORF=""
typeset DATETIME=$( date +"%m/%d/%Y %H:%M:%S" )
typeset SYSTEM="$( hostname )"
typeset TYPE="${TYPE:-ERROR}"
typeset CLASS="${CLASS:-O}"
typeset SOURCE
typeset DESCRIPTION
typeset MSG
typeset LINE
typeset RESPONSE
typeset LOGFILE="/var/log/ckhttp.log"
typeset HTTPVER="HTTP/1.1"
typeset HTTPOK
typeset PROTOCOL="http"
typeset URL=""
typeset LOGSUCCESS="${FALSE}"
#### HTTP HEAD Success codes, any other HEAD response is considered unsuccessful.
HTTPOK=( 200 301 302 )
while getopts ":vVu:t:c:l:s" OPTION
do
case "${OPTION}" in
'u') URL="${OPTARG}";;
't') TYPE="${OPTARG}";;
'c') CLASS="${OPTARG}";;
'l') LOGFILE="${OPTARG}";;
's') LOGSUCCESS="${TRUE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
[?:#]) usagemsg_ckhttp_k93 "${0}" && return 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
(( VERYVERB == TRUE )) && set -x
#### Extract the protocol from the URL specified by the user.
PROTOCOL="${URL%%://*}"
#### Extract the full path file name to the web page specified by the user.
PAGE="${URL#${PROTOCOL}://}"
PAGE="/${PAGE#*/}"
#### Extract the node name from the URL specified by the user.
NODENAME="${URL#${PROTOCOL}://}"
NODENAME="${NODENAME%%/*}"
#### Extract the network port number from the URL specified by the user.
[[ "_${NODENAME}" == _*:+([0-9]) ]] && PORTNUM="${NODENAME##*:}"
[[ "_${NODENAME}" == _*:* ]] && PORTCHK="${NODENAME##*:}"
#### Remove the network port number from the nodename specified by the user.
NODENAME="${NODENAME%%:*}"
(( VERBOSE == TRUE )) && print -u 2 -- "#\n# Function Name..........................: ${0}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Version................................: ${VERSION}"
################################################################
trap "usagemsg_ckhttp_k93 ${0}" EXIT
if [[ "_${NODENAME}" == "_" ]] || [[ "_${PORTNUM}" == "_" ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: specify node name and port......: ${PROTOCOL}://${NODENAME}:${PORTNUM}"
return 2
fi
if [[ "_${PORTCHK}" != _+([0-9]) ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: Invalid port number.............: ${PORTCHK}"
return 3
fi
if ! [[ "_${TYPE}" == _@(ERROR|WARN) ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: Invalid log message type........: ${TYPE}"
return 4
fi
if ! [[ "_${CLASS}" == _@(O|S|U) ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: Invalid log message class.......: ${CLASS}"
return 5
fi
if ! [[ -d "${LOGFILE%/*}" ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: Invalid log file directory......: ${LOGFILE%/*}"
return 6
fi
if [[ "_${PROTOCOL}" != _@(http|https) ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: Invalid protocol specified......: ${PROTOCOL}"
return 7
fi
trap "-" EXIT
################################################################
####
#### If verbose mode was specified by the user on the command
#### line, output the configuration information to the
#### standard error stream STDERR.
(( VERBOSE == TRUE )) && print -u 2 -- "# HTTP Protocol..........................: ${PROTOCOL}"
[[ "_${NODENAME}" == "_" ]] && TORF="Not Specified" || TORF="${NODENAME}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Network Service Name...................: ${TORF}"
[[ "_${PORTNUM}" == "_" ]] && TORF="Not Specified" || TORF="${PORTNUM}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Network Port Number....................: ${TORF}"
(( VERBOSE == TRUE )) && print -u 2 -- "# HTTP Page location.....................: ${PAGE}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Log file...............................: ${LOGFILE}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Log message class......................: ${CLASS}"
(( VERBOSE == TRUE )) && print -u 2 -- "# Log message type.......................: ${TYPE}"
(( LOGSUCCESS == TRUE )) && TORF="TRUE" || TORF="FALSE"
(( VERBOSE == TRUE )) && print -u 2 -- "# Log successful requests................: ${TORF}"
################################################################
SOURCE="${NODENAME}"
DESCRIPTION="${PROTOCOL} test failed for page rendering ${NODENAME}:${PORTNUM}${PAGE}"
MSG="${DATETIME} ${SYSTEM} ${SOURCE} ${TYPE} ${CLASS} ${DESCRIPTION}"
####
#### Open a network connection to the remote node on the user
#### specified network port. If the connection is successful,
#### send an HTTP HEAD request, and read the first line of the
#### response into an array, then close the network connection.
####
if exec 3<>/dev/tcp/${NODENAME}/${PORTNUM}
then
print -u 3 -- "HEAD ${PAGE} ${HTTPVER}\r"
print -u 3 -- "Host:${NODENAME}\r"
print -u 3 -- "\r\n\r"
IFS=$' \t\n'
read -u 3 -A -- RESPONSE
# while read -u 3 -- LINE
# do
# [[ "_${LINE}" == _HTTP* ]] && RESPONSE=( ${LINE} ) && continue
# [[ "_${LINE}" == _Location:* ]] && LOCATION=( "${LINE#*:}" ) && break
# done
exec 3>&-
exec 3<&-
####
#### Determine if the response received from the HTTP HEAD
#### request contains a successful return code.
#### The successful return codes are contained in an array
#### called HTTPOK.
####
(( VERBOSE == TRUE )) && print -u 2 -- "# Response from http server..............: ${RESPONSE[@]}"
IFS="|"
if [[ "_${RESPONSE[1]}" == _@(${HTTPOK[*]}) ]]
then
(( VERBOSE == TRUE )) && print -u 2 -- "# Success: HTTP return code..............: ${RESPONSE[1]}"
####
#### If the "-s" command line option was specifed by the
#### user, then create a log message consistent with normal
#### Unix log formats, and append the SUCCESSFUL message to the
#### log file.
####
if (( LOGSUCCESS == TRUE ))
then
DESCRIPTION="Successful response received: ${RESPONSE[1]} : ${PROTOCOL}://${NODENAME}:${PORTNUM}${PAGE}"
TYPE="SUCCESS"
MSG="${DATETIME} ${SYSTEM} ${SOURCE} ${TYPE} ${CLASS} ${DESCRIPTION}"
print -- "${MSG}" >> "${LOGFILE}"
fi
return 0
####
#### If the HTTP HEAD return code is unsuccessful, create a
#### log message consistent with normal Unix log formats, and
#### append the error message to the log file.
####
else
DESCRIPTION="Invalid HTTP return code:${RESPONSE[1]} : ${PROTOCOL}://${NODENAME}:${PORTNUM}${PAGE}"
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: ${DESCRIPTION}"
MSG="${DATETIME} ${SYSTEM} ${SOURCE} ${TYPE} ${CLASS} ${DESCRIPTION}"
print -- "${MSG}" >> "${LOGFILE}"
return 8
fi
IFS=$' \t\n'
####
#### If network connection attempt fails, create a log
#### message consistent with normal Unix log formats, and
#### append the error message to the log file.
####
else
DESCRIPTION="Unable to open ${PROTOCOL} connection..: ${PROTOCOL}://${NODENAME}:${PORTNUM}${PAGE}"
(( VERBOSE == TRUE )) && print -u 2 -- "# ERROR: ${DESCRIPTION}"
MSG="${DATETIME} ${SYSTEM} ${SOURCE} ${TYPE} ${CLASS} ${DESCRIPTION}"
print -- "${MSG}" >> "${LOGFILE}"
return 9
fi
exec 3>&-
exec 3<&-
return 10
}
################################################################
ckhttp_k93 "${@}"