Skip to content

Commit

Permalink
Adjust return codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Scavo committed Oct 22, 2016
1 parent 7c871e0 commit 3f257e5
Showing 1 changed file with 65 additions and 48 deletions.
113 changes: 65 additions & 48 deletions lib/http_tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ fi

#######################################################################
#
# Given a web resource and a cache, if the resource is cached, request
# the resource using HTTP Conditional GET [RFC 7232], otherwise issue
# an ordinary GET request. In either case, if the server responds with
# 200, cache the resource and return the response body. If the server
# responds with 304, return the cached resource instead.
# Given a web resource and a local cache, if the resource is cached,
# request the resource using HTTP Conditional GET [RFC 7232], otherwise
# issue an ordinary GET request for the resource. In either case, if
# the server responds with 200, cache the resource and return the
# response body. If the server responds with 304, return the cached
# resource instead.
#
# Usage: conditional_get [-v] [-F | -C] -d CACHE_DIR -t TMP_DIR HTTP_LOCATION
#
Expand All @@ -45,11 +46,12 @@ fi
# Use option -F or -C to alter the default behavior of the function.
#
# Option -F forces the return of a fresh resource, that is, if the
# server responds with 304, an error occurs and the function returns
# with a nonzero return code.
# server responds with 304, the function returns with a nonzero return
# code.
#
# Option -C causes the function to go directly to cache. No GET request
# is issued. This option is useful in offline mode.
# is issued. (This option is useful in offline mode.) If the resource
# is not cached, the function returns with a nonzero return code.
#
# The output of the curl command-line tool is stored in the following
# temporary files:
Expand All @@ -62,7 +64,22 @@ fi
#
# command_paths.sh
#
# This library file must be sourced BEFORE calling this function.
# The library file must be sourced BEFORE calling this function.
#
# RETURN CODES
#
# 0: success
# 1: quiet failure mode:
# option -F but no fresh resource available OR
# option -C but no cached resource available
# 2: initialization failure
# 3: unspecified failure
# 4: hash operation failed
# 5: curl failed
# 6: call to get_header_value failed
# 7: call to get_response_code failed
# 8: copy to cache failed
# 9: unexpected HTTP response
#
# TODO:
# - follow redirects?
Expand All @@ -72,15 +89,16 @@ fi
conditional_get () {

if ! $COMMAND_PATHS; then
echo "ERROR: global command paths not found" >&2
echo "ERROR: $FUNCNAME: global command paths not found" >&2
return 2
fi

local script_version="0.6"
local script_version="0.7"
local user_agent_string="HTTP Conditional GET client $script_version"

local hash
local exit_code
local return_code
local cached_header_file
local cached_content_file
local conditional_get_mode
Expand Down Expand Up @@ -188,8 +206,8 @@ conditional_get () {
)
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $FUNCNAME failed to hash the location URL" >&2
return $exit_code
echo "ERROR: $FUNCNAME failed to hash the location URL (exit code: $exit_code)" >&2
return 4
fi

cached_header_file="$cache_dir/${hash}_headers"
Expand All @@ -206,14 +224,15 @@ conditional_get () {
/bin/cat "$cached_content_file"
return 0
fi

conditional_get_mode=true
else
# ensure cache integrity
/bin/rm -f "$cached_header_file" "$cached_content_file" >&2
if $cache_only_mode; then
echo "ERROR: $FUNCNAME failed to find cached resource: $location" >&2
return 1
fi

# quiet failure mode
$cache_only_mode && return 1

conditional_get_mode=false
fi

Expand Down Expand Up @@ -260,20 +279,20 @@ conditional_get () {
do_conditional_get=false
if $conditional_get_mode; then
header_value=$( get_header_value "$cached_header_file" 'ETag' )
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_header_value failed to initialize" >&2
return $exit_code
return_code=$?
if [ $return_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_header_value (return code: $return_code)" >&2
return 6
fi
if [ -n "$header_value" ]; then
do_conditional_get=true
curl_opts="${curl_opts} --header 'If-None-Match: $header_value'"
else
header_value=$( get_header_value "$cached_header_file" 'Last-Modified' )
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_header_value failed to initialize" >&2
return $exit_code
return_code=$?
if [ $return_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_header_value (return code: $return_code)" >&2
return 6
fi
if [ -n "$header_value" ]; then
do_conditional_get=true
Expand All @@ -288,8 +307,8 @@ conditional_get () {
eval $cmd
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: curl failed ($exit_code)" >&2
return $exit_code
echo "ERROR: $FUNCNAME: curl failed (exit code: $exit_code)" >&2
return 5
fi

#######################################################################
Expand All @@ -304,25 +323,25 @@ conditional_get () {
# sanity check
if [ ! -f "$tmp_header_file" ]; then
echo "ERROR: $FUNCNAME unable to find header file $tmp_header_file" >&2
return 1
return 3
fi

response_code=$( get_response_code "$tmp_header_file" )
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_response_code failed to initialize" >&2
return $exit_code
return_code=$?
if [ $return_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_response_code failed (return code: $return_code)" >&2
return 7
fi
$verbose_mode && printf "$FUNCNAME received response code: %d\n" "$response_code" >> "$tmp_log_file"

if [ "$response_code" = "200" ]; then

# sanity check
declared_content_length=$( get_header_value "$tmp_header_file" 'Content-Length' )
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_header_value failed to initialize" >&2
return $exit_code
return_code=$?
if [ $return_code -ne 0 ]; then
echo "ERROR: $FUNCNAME: get_header_value failed (return code: $return_code)" >&2
return 6
fi
actual_content_length=$( /bin/cat "$tmp_content_file" \
| /usr/bin/wc -c \
Expand All @@ -331,7 +350,7 @@ conditional_get () {
if [ -n "$declared_content_length" ]; then
if [ "$declared_content_length" != "$actual_content_length" ]; then
echo "ERROR: $FUNCNAME failed content length check" >&2
return 1
return 3
fi
else
echo "WARNING: Content-Length response header missing" >&2
Expand All @@ -351,36 +370,34 @@ conditional_get () {
exit_code=$?
if [ $exit_code -ne 0 ]; then
/bin/rm -f "$cached_header_file" "$cached_content_file" >&2
echo "ERROR: $FUNCNAME failed copy to file $cached_header_file" >&2
return $exit_code
echo "ERROR: $FUNCNAME failed copy to file $cached_header_file (exit code: $exit_code)" >&2
return 8
fi
/bin/cp -f "$tmp_content_file" "$cached_content_file" >&2
exit_code=$?
if [ $exit_code -ne 0 ]; then
/bin/rm -f "$cached_header_file" "$cached_content_file" >&2
echo "ERROR: $FUNCNAME failed copy to file $cached_content_file" >&2
return $exit_code
echo "ERROR: $FUNCNAME failed copy to file $cached_content_file (exit code: $exit_code)" >&2
return 8
fi

elif [ "$response_code" = "304" ]; then
# quiet failure mode
$force_output_mode && return 1

$verbose_mode && echo "$FUNCNAME downloaded 0 bytes (cache is up-to-date)" >> "$tmp_log_file"
else
echo "ERROR: $FUNCNAME failed with HTTP response code $response_code" >&2
return 1
return 9
fi

#######################################################################
#
# output the resource content
#
#######################################################################

if $force_output_mode && [ "$response_code" = "304" ]; then
echo "ERROR: $FUNCNAME failed to get fresh resource: $location" >&2
return 1
fi

/bin/cat "${cached_content_file}"
/bin/cat "$cached_content_file"
return 0
}

Expand Down

0 comments on commit 3f257e5

Please sign in to comment.