diff --git a/lib/http_tools.sh b/lib/http_tools.sh index e935a10..fe946d5 100755 --- a/lib/http_tools.sh +++ b/lib/http_tools.sh @@ -25,7 +25,7 @@ # 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 [-L LOG_FILE] HTTP_LOCATION +# Usage: conditional_get [-v] [-F | -C] [-I] -d CACHE_DIR -T TMP_DIR HTTP_LOCATION # # This function requires two option arguments (CACHE_DIR and TMP_DIR) # and a command-line argument (HTTP_LOCATION). The rest of the command @@ -35,19 +35,30 @@ # -v verbose mode # -F force the return of a fresh resource # -C check the cache only +# -I return headers only # -d the cache directory (REQUIRED) # -T a temporary directory (REQUIRED) # -# Use option -F or -C to alter the default behavior of the function. +# Use option -F, -C, or -I to alter the default behavior of the function. +# Options -F and -C are mutually exclusive of each another. Option -I +# may be used with option -C (but not with option -F). # # Option -F forces the return of a fresh resource, that is, if the # server responds with 304, the function quietly returns with a nonzero # return code. # -# Option -C causes the function to go directly to cache. No GET request +# Option -C causes the function to go directly to cache. No HTTP request # is issued. (This option is useful in offline mode.) If the resource # is not cached, the function quietly returns with a nonzero return code. # +# Option -I issues a HEAD request instead of a GET request. In that case, +# only the response headers are returned in the output. Nothing is written +# when option -I is used. +# +# If options -I and -C are used together, the cached headers are returned +# instead. As with option -C alone, if the resource is not cached, the +# function quietly returns with a nonzero return code. +# # The output of the curl command-line tool is stored in the following # temporary files: # @@ -76,9 +87,6 @@ # 8: copy to cache failed # 9: unexpected HTTP response # -# TODO: -# - follow redirects? -# ####################################################################### conditional_get () { @@ -94,7 +102,7 @@ conditional_get () { return 2 fi - local script_version="0.8" + local script_version="0.9" local user_agent_string="HTTP Conditional GET client $script_version" local hash @@ -117,6 +125,7 @@ conditional_get () { local verbose_mode=false local force_output_mode=false local cache_only_mode=false + local headers_only_mode=false local cache_dir local tmp_dir local location @@ -124,7 +133,7 @@ conditional_get () { local opt local OPTARG local OPTIND - while getopts ":vFCd:T:" opt; do + while getopts ":vFCId:T:" opt; do case $opt in v) verbose_mode=true @@ -137,6 +146,9 @@ conditional_get () { cache_only_mode=true force_output_mode=false ;; + I) + headers_only_mode=true + ;; d) cache_dir="$OPTARG" ;; @@ -154,6 +166,12 @@ conditional_get () { esac done + # + if $force_output_mode && $headers_only_mode; then + echo "ERROR: $FUNCNAME: options -F and -C may not be used together" >&2 + return 2 + fi + # a temporary directory is required if [ -z "$tmp_dir" ]; then echo "ERROR: $FUNCNAME: no temporary directory specified" >&2 @@ -217,9 +235,15 @@ conditional_get () { # check if the resource is cached if [ -f "$cached_header_file" ] && [ -f "$cached_content_file" ]; then + if $cache_only_mode; then - print_log_message "$FUNCNAME reading cached content file: $cached_content_file" - /bin/cat "$cached_content_file" + if $headers_only_mode; then + print_log_message "$FUNCNAME reading cached header file: $cached_header_file" + /bin/cat "$cached_header_file" + else + print_log_message "$FUNCNAME reading cached content file: $cached_content_file" + /bin/cat "$cached_content_file" + fi exit_code=$? if [ $exit_code -ne 0 ]; then print_log_message -E "$FUNCNAME unable to cat output ($exit_code)" @@ -272,8 +296,16 @@ conditional_get () { curl_opts="--silent --show-error" fi curl_opts="${curl_opts} --user-agent '${user_agent_string}'" + + # always capture the header in a file + # capture the output iff the script issues a GET request curl_opts="${curl_opts} --dump-header '${tmp_header_file}'" - curl_opts="${curl_opts} --output '${tmp_content_file}'" + if $headers_only_mode; then + curl_opts="${curl_opts} --head" + curl_opts="${curl_opts} --output '/dev/null'" + else + curl_opts="${curl_opts} --output '${tmp_content_file}'" + fi curl_opts="${curl_opts} --stderr '${tmp_stderr_file}'" # If the resource is cached, add a conditional GET header. @@ -338,6 +370,22 @@ conditional_get () { fi print_log_message "$FUNCNAME received response code: $response_code" + if $headers_only_mode; then + /bin/cat "$tmp_header_file" + exit_code=$? + if [ $exit_code -ne 0 ]; then + print_log_message -E "$FUNCNAME unable to cat output ($exit_code)" + return 3 + fi + return 0 + fi + + ####################################################################### + # + # Update the cache + # + ####################################################################### + if [ "$response_code" = "200" ]; then # sanity check @@ -399,7 +447,7 @@ conditional_get () { ####################################################################### # - # output the resource content + # Return the cached content # #######################################################################