Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Commit new executable script
Tom Scavo committed Jun 9, 2017
1 parent e0d5adf commit 1ad281a
Showing 2 changed files with 400 additions and 0 deletions.
399 changes: 399 additions & 0 deletions bin/request_http_resource.sh
@@ -0,0 +1,399 @@
#!/bin/bash

#######################################################################
# Copyright 2017 Internet2
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#######################################################################

#######################################################################
# Help message
#######################################################################

display_help () {
/bin/cat <<- HELP_MSG
This script parses one or more SAML metadata aggregates and
produces a JSON file of vital statistics (such as validUntil,
creationInstant, etc.)
The script depends on cached metadata. It will not fetch
a metadata file from the server.
Usage: ${0##*/} [-hv] -d OUT_DIR MD_LOCATION ...
The script takes one or more metadata locations on the
command line. For each location, the corresponding metadata
is read from cache and parsed. The script produces a JSON
array, with one array element for each metadata location.
If successful, the resulting JSON file is finally moved
to the output directory specified on the command line.
Options:
-h Display this help message
-v Enable DEBUG mode
-d Specify the output directory
Option -h is mutually exclusive of all other options.
Option -d specifies the ultimate output directory, which is
usually a web directory. This option is REQUIRED.
ENVIRONMENT
This script leverages a handful of environment variables:
LIB_DIR A source library directory
TMPDIR A temporary directory
LOG_FILE A persistent log file
LOG_LEVEL The global log level [0..5]
All of the above environment variables are REQUIRED
except LOG_LEVEL, which defaults to LOG_LEVEL=3.
The following environment variables are REQUIRED:
$( printf " %s\n" ${env_vars[*]} )
The following directories will be used:
$( printf " %s\n" ${dir_paths[*]} )
The following log file will be used:
$( printf " %s\n" $LOG_FILE )
INSTALLATION
At least the following source library files MUST be installed
in LIB_DIR:
$( printf " %s\n" ${lib_filenames[*]} )
Also, the following XSLT file MUST be installed in LIB_DIR:
$xsl_filename
OUTPUT
The script outputs a JSON file containing a single array.
Each array element is a JavaScript object with the following
fields:
location: location
currentTime: dateTime
validUntil: dateTime
creationInstant: dateTime
validityInterval: duration
untilInvalid: duration
sinceCreation: duration
For example:
{
"location": "http://md.incommon.org/InCommon/InCommon-metadata.xml",
"currentTime": "2017-06-06T23:57:54Z",
"validUntil": "2017-06-16T18:41:12Z",
"creationInstant": "2017-06-02T18:41:12Z",
"validityInterval": "P14DT0H0M0S",
"untilInvalid": "P9DT18H43M18S",
"sinceCreation": "P4DT5H16M42S"
}
EXAMPLES
\$ ${0##*/} -h
\$ locations="http://md.incommon.org/InCommon/InCommon-metadata.xml
> http://md.incommon.org/InCommon/InCommon-metadata-export.xml"
\$ out_dir=/home/htdocs/www.incommonfederation.org/federation/metadata/
\$ ${0##*/} -d \$out_dir \$locations
HELP_MSG
}

#######################################################################
# Bootstrap
#######################################################################

script_name=${0##*/} # equivalent to basename $0

# required environment variables
env_vars[1]="LIB_DIR"
env_vars[2]="TMPDIR"
env_vars[3]="LOG_FILE"

# check environment variables
for env_var in ${env_vars[*]}; do
eval "env_var_val=\${$env_var}"
if [ -z "$env_var_val" ]; then
echo "ERROR: $script_name requires env var $env_var" >&2
exit 2
fi
done

# required directories
dir_paths[1]="$LIB_DIR"
dir_paths[2]="$CACHE_DIR"
dir_paths[3]="$TMPDIR"

# check required directories
for dir_path in ${dir_paths[*]}; do
if [ ! -d "$dir_path" ]; then
echo "ERROR: $script_name: directory does not exist: $dir_path" >&2
exit 2
fi
done

# check the log file
# devices such as /dev/tty and /dev/null are allowed
if [ ! -f "$LOG_FILE" ] && [[ $LOG_FILE != /dev/* ]]; then
echo "ERROR: $script_name: file does not exist: $LOG_FILE" >&2
exit 2
fi

# default to INFO logging
if [ -z "$LOG_LEVEL" ]; then
LOG_LEVEL=3
fi

# library filenames
lib_filenames[1]="core_lib.sh"
lib_filenames[2]="http_tools.sh"

# check lib files
for lib_filename in ${lib_filenames[*]}; do
lib_file="$LIB_DIR/$lib_filename"
if [ ! -f "$lib_file" ]; then
echo "ERROR: $script_name: file does not exist: $lib_file" >&2
exit 2
fi
done

#######################################################################
# Process command-line options and arguments
#######################################################################

help_mode=false; local_opts=
while getopts ":hvd:" opt; do
case $opt in
h)
help_mode=true
;;
v)
LOG_LEVEL=4
local_opts="$local_opts -$opt"
;;
d)
out_dir="$OPTARG"
;;
\?)
echo "ERROR: $script_name: Unrecognized option: -$OPTARG" >&2
exit 2
;;
:)
echo "ERROR: $script_name: Option -$OPTARG requires an argument" >&2
exit 2
;;
esac
done

if $help_mode; then
display_help
exit 0
fi

# check the output directory
if [ -z "$out_dir" ]; then
echo "ERROR: $script_name: no output directory specified (option -d)" >&2
exit 2
fi
if [ ! -d "$out_dir" ]; then
echo "ERROR: $script_name: directory does not exist: $out_dir" >&2
exit 2
fi

# at least one metadata location is required
shift $(( OPTIND - 1 ))
if [ $# -lt 1 ]; then
echo "ERROR: $script_name: wrong number of arguments: $# (at least 1 required)" >&2
exit 2
fi

#######################################################################
# Initialization
#######################################################################

# source lib files
for lib_filename in ${lib_filenames[*]}; do
lib_file="$LIB_DIR/$lib_filename"
source "$lib_file"
status_code=$?
if [ $status_code -ne 0 ]; then
echo "ERROR: $script_name failed ($status_code) to source lib file $lib_file" >&2
exit 2
fi
done

# create a temporary subdirectory
tmp_dir="${TMPDIR%%/}/${script_name%%.*}_$$"
/bin/mkdir "$tmp_dir"
status_code=$?
if [ $status_code -ne 0 ]; then
echo "ERROR: $script_name failed ($status_code) to create tmp dir $tmp_dir" >&2
exit 2
fi

# specify temporary files
out_filename=http_response_headers.json
out_file="${tmp_dir}/$out_filename"
header_file="${tmp_dir}/resource-header.txt"

#######################################################################
# Functions
#######################################################################

escape_special_json_chars () {
local str="$1"

# backslash (\) and double quote (") are special
echo "$str" | $_SED -e 's/\\/\\\\/g' -e 's/"/\\"/g'
}

append_json_object () {
local location=$( escape_special_json_chars "$location" )
local response_code=$( escape_special_json_chars "$response_code" )
local date=$( escape_special_json_chars "$date" )
local last_modified=$( escape_special_json_chars "$last_modified" )
local e_tag=$( escape_special_json_chars "$e_tag" )
local content_length=$( escape_special_json_chars "$content_length" )
local content_type=$( escape_special_json_chars "$content_type" )

/bin/cat <<- JSON_OBJECT
{
"location": "$location",
"ResponseCode": "$response_code",
"Date": "$date",
"LastModified": "$last_modified",
"ETag": "$e_tag",
"ContentLength": "$content_length",
"ContentType": "$content_type"
}
JSON_OBJECT
}

parse_metadata () {

location="$1"

# get resource headers
print_log_message -I "$script_name requesting resource: $location"
/usr/bin/curl $curl_opts --silent --head $location > $header_file
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: curl failed ($status_code) on resource: $location"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

# get the HTTP response code
response_code=$( get_response_code $header_file )
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: get_response_code failed ($status_code) to parse response header: $header_file"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

# get the Date response header
header_name=Date
date=$( get_header_value $header_file $header_name )
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: get_header_value failed ($status_code) to parse response header: $header_file"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

# get the Last-Modified response header
header_name=Last-Modified
last_modified=$( get_header_value $header_file $header_name )
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: get_header_value failed ($status_code) to parse response header: $header_file"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

# get the ETag response header
header_name=ETag
e_tag=$( get_header_value $header_file $header_name )
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: get_header_value failed ($status_code) to parse response header: $header_file"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

# get the Content-Length response header
header_name=Content-Length
content_length=$( get_header_value $header_file $header_name )
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: get_header_value failed ($status_code) to parse response header: $header_file"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

# get the Content-Type response header
header_name=Content-Type
content_type=$( get_header_value $header_file $header_name )
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: get_header_value failed ($status_code) to parse response header: $header_file"
clean_up_and_exit -d "$tmp_dir" $status_code
fi
}

print_response_headers () {

# begin output list
printf "[\n"

while true; do

parse_metadata "$1"
append_json_object

shift; (( "$#" )) || break

# print comma separator
printf " ,\n"
done

# end output list
printf "]\n"
}

#######################################################################
# Main processing
#######################################################################

print_log_message -I "$script_name BEGIN"

# create the JSON output
print_response_headers "$@" > "$out_file"
print_log_message -I "$script_name writing output file: $out_filename"

# move the output file to the web directory
print_log_message -I "$script_name moving output file to dir: $out_dir"
/bin/mv "$out_file" $out_dir
status_code=$?
if [ $status_code -ne 0 ]; then
print_log_message -E "$script_name: mv failed ($status_code) to dir: $out_dir"
clean_up_and_exit -d "$tmp_dir" $status_code
fi

print_log_message -I "$script_name END"
clean_up_and_exit -d "$tmp_dir" 0
1 change: 1 addition & 0 deletions install.sh
@@ -94,6 +94,7 @@ while read script_file; do
done <<SCRIPTS
$script_bin/bin/cget.sh
$script_bin/bin/compute_vital_statistics.sh
$script_bin/bin/request_http_resource.sh
SCRIPTS

# initialize lib dir

0 comments on commit 1ad281a

Please sign in to comment.