#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

# Simple script to fetch a URL through one proxy, and then PUSH that response (headers
# and body) to a set of hosts. The host:port defaults to localhost:80 for fetching
# the URL, but can be overridden with -h/-p.


# Default values for command line options
HOST="localhost"
PORT="80"

DEBUG=0
FORCE=0
MD5=0

#
# Print some help text
#
usage() {
    echo 'Usage: traffic_primer [-cfd] [-u <url>] [-U <filename with URLs>] [-h Host] [-p port] host1 host2 ...'
    exit 2
}


#
# push(url, host ...)
#   fetch the URL storing header + body in a tmp file, and then replay it to the hosts
#
push() {
    u=$1; shift

    echo "---> ${u}"
    # First make sure the "source" proxy is alive
    nc -z $HOST $PORT > /dev/null
    if [ $? -gt 0 ]; then
        echo "  Error: source ${HOST}:${PORT} is down"
        return
    fi

    f=$(mktemp /tmp/pusher-XXXXXX)
    trap "rm -f ${f} ${f}.hdrs ${f}.body; exit 0" 0 1 2 3 15 # Just in case we left it around

    # Fetch the "source" object first
    # [ $FORCE -gt 0 ] && curl -x ${HOST}:${PORT} -s -o /dev/null -X PURGE $u
    echo -en "\tFetching source body ..."
    curl -x ${HOST}:${PORT} -s -D ${f}.hdrs -o ${f}.body $u
    s_md5=$(cat ${f}.body | md5sum)
    echo "done"
    echo -e "\tSource MD5=${s_md5}"

    cat ${f}.hdrs ${f}.body > ${f}

    for h in $*; do
        # Make sure the destination host:port is up
        nc -z $h $PORT > /dev/null
        if [ $? -gt 0 ]; then
            echo -e "\tError: ${h}:${PORT} is down"
        else
            echo -en "\tProcessing ${h}:${PORT}..."
            # PURGE the object first if we -f (force) it
            if [ $FORCE -gt 0 ]; then
                echo -n " purged..."
                curl -x ${h}:${PORT} -s -o /dev/null -X PURGE $u
            fi

            # If it's not in cache now, PUSH it
            curl -f -I -x ${h}:${PORT} -s -o /dev/null -H "Cache-Control: only-if-cached" $u
            if [ $? -gt 0 ]; then
                echo -n " pushing..."
                curl -x ${h}:${PORT} -s -o /dev/null -X PUSH --data-binary @${f} $u
            fi
            echo " done."

            # Now, verify the content MD5 if enabled
            if [ $MD5 -gt 0 ]; then
                n_md5=$(curl -x ${h}:${PORT} -s $u | md5sum)
                if [ "$n_md5" != "$s_md5" ]; then
                    # This is bad, MD5's don't match, error and PURGE it
                    echo -en "\t\t Error! MD5 incorrect! Purging the object."
                    curl -x ${h}:${PORT} -s -o /dev/null -X PURGE $u
                else
                    echo -e "\t\tMD5 checksum is good."
                fi
            fi
        fi
    done

    rm -f ${f} ${f}.hdrs ${f}.body
}


# Parse command line arguments
PARGS=$(getopt u:U:h:p:dfc $@)
[ $? != 0 ] && usage

url=""
urlfile=""
set -- $PARGS
while true; do
    case "$1" in
        -c)
            MD5=1
            shift ;;
        -d)
            DEBUG=1
            shift ;;
        -f) FORCE=1
            shift ;;
        -u)
            url="$2"
            shift 2 ;;
        -U)
            urlfile="$2"
            shift 2 ;;
        -h)
            HOST="$2"
            shift 2 ;;
        -p)
            PORT="$2"
            shift 2 ;;
        --)
            shift
            break ;;
        *)
            usage
            break
            ;;
    esac
done

#
# Now process the URL or URL file list
#
if [ "" != "$urlfile" ]; then
    while read line; do
        push $line $@
        echo
    done < $urlfile
elif ["" != "$url" ]; then
    push $url $@
else
    usage
fi
