#!/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 "${@}"