Skip to content
Snippets Groups Projects
Commit e553dea9 authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

v0.7 fixes using shellcheck

parent b4e13b0b
No related branches found
No related tags found
No related merge requests found
......@@ -15,15 +15,10 @@
# 2020-02-12 v0.4 axel.hahn@iml.unibe.ch Caching
# 2020-03-02 v0.5 axel.hahn@iml.unibe.ch a few more response check functions
# 2021-01-21 v0.6 axel.hahn@iml.unibe.ch add Content-type in request header
# 2022-01-11 v0.7 axel.hahn@iml.unibe.ch fixes using shellcheck
# ======================================================================
# --- fetch incoming params
RestApiCfg=$1
RestApiMethod=$2
ApiUrl=$3
Body="$4"
http_cfg__about="Bash REST API client v0.6"
http_cfg__about="Bash REST API client v0.7"
typeset -i http_cfg__debug=0
typeset -i http_cfg__cacheTtl=0
http_cfg__cacheDir=/var/tmp/http-cache
......@@ -103,7 +98,7 @@ EOH
}
function http.init(){
http._wd "${FUNCNAME[0]}()"
which curl >/dev/null || http.quit
# request vars
......@@ -116,7 +111,7 @@ EOH
http_req__fullurl=
http_req__docs=
http_req__dataprefix="RESTAPICLIENTMETADATA_`date +%s`_$$"
http_req__dataprefix="RESTAPICLIENTMETADATA_$(date +%s)_$$"
local writevar=
for myvar in $curlMeta
do
......@@ -137,13 +132,15 @@ EOH
}
# execute the request
# param string optional: method; GET|POST|PUT|DELETE|...
# param string optional: full url
# param string optional: request body
function http.makeRequest(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
# --- handle optional prams
if [ $# -ne 0 ]; then
echo $1 | grep "^[A-Z]*$" >/dev/null
echo "$1" | grep "^[A-Z]*$" >/dev/null
if [ $? -eq 0 ]; then
http.setMethod "$1"
shift 1
......@@ -157,14 +154,15 @@ EOH
http_req__mode=REQUEST
useCache=0
makeRequest=1
if [ $http_cfg__cacheTtl -gt 0 -a "${http_req__method}" = "GET" ]; then
if [ $http_cfg__cacheTtl -gt 0 ] && [ "${http_req__method}" = "GET" ]; then
useCache=1
test -z "${http_cfg__cacheFile}" && http_cfg__cacheFile=`http._genOutfilename "${http_cfg__cacheDir}/AUTOFILE"`
test -z "${http_cfg__cacheFile}" && http_cfg__cacheFile=$(http._genOutfilename "${http_cfg__cacheDir}/AUTOFILE")
if [ -f "${http_cfg__cacheFile}" ]; then
http.responseImport "${http_cfg__cacheFile}"
typeset -i local iAge=`http.getRequestAge`
typeset -i local iAge
iAge=$(http.getRequestAge)
http._wd "INFO: Age of cache is $iAge sec - vs TTL $http_cfg__cacheTtl sec - file $http_cfg__cacheFile"
if [ $iAge -gt 0 -a $iAge -lt $http_cfg__cacheTtl ]; then
if [ $iAge -gt 0 ] && [ $iAge -lt $http_cfg__cacheTtl ]; then
http._wd "INFO: Using cache"
makeRequest=0
http_req__mode=CACHE
......@@ -178,7 +176,6 @@ EOH
# --- make the request
if [ $makeRequest -eq 1 ]; then
http_req__start=`date +%s`
http._wd "${FUNCNAME[0]}($1) ${http_req__method} ${http_req__fullurl}"
http_resp__all=$(
if [ -z "${http_req__body}" ]; then
......@@ -203,13 +200,13 @@ EOH
fi
) || http.quit
http._wd "OK - Curl finished the http request ... processing data"
http_resp__neutral=`http._fetchAllAndReformat`
http_resp__neutral=$(http._fetchAllAndReformat)
if [ $useCache -eq 1 ]; then
http._wd "INFO: writing cache ..."
http.responseExport "${http_cfg__cacheFile}"
fi
fi
http._wd "Request function finished; Code `http.getStatuscode`"
http._wd "Request function finished; Code $(http.getStatuscode)"
}
# ......................................................................
......@@ -217,8 +214,8 @@ EOH
# show error message with last return code and quit with this exitcode
# no params
function http.quit(){
http._wd "${FUNCNAME[0]}($1)"
rc=$?
http._wd "${FUNCNAME[0]}()"
echo >&2
echo -e "\e[31m# ERROR: command FAILED with rc $rc. \e[0m" >&2
if [ ! -z "${RestApiDocs}" ]; then
......@@ -254,6 +251,9 @@ EOH
# ======================================================================
# GETTER
# ======================================================================
# get the response header or response body
# param string what to return; one of header|body
function http._fetchResponseHeaderOrBody(){
http._wd "${FUNCNAME[0]}($1)"
local isheader=true
......@@ -275,24 +275,25 @@ EOH
done
}
function http._fetchResponseData(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
echo "${http_resp__all}" | sed "s#${http_req__dataprefix}#\n${http_req__dataprefix}#" | grep "${http_req__dataprefix}" | tail -1 | cut -f 2- -d "|" | sed "s#|#\n#g" | grep -v "${http_req__dataprefix}" | while read -r line; do
echo $line
echo "$line"
done
}
function http._fetchAllAndReformat(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
IFS=''
line="#------------------------------------------------------------"
echo "#_META_|about:$http_cfg__about"
echo "#_META_|host:`hostname -f`"
echo "#_META_|host:$(hostname -f)"
echo $line
echo "#_REQUEST_|fullurl:$http_req__fullurl"
echo "#_REQUEST_|method:$http_req__method"
echo "#_REQUEST_|time:`date`"
echo "#_REQUEST_|timestamp:`date +%s`"
echo "#_REQUEST_|auth:`echo $http_req__auth | sed 's#:.*#:xxxxxxxx#'`"
echo "#_REQUEST_|time:$(date)"
echo "#_REQUEST_|timestamp:$(date +%s)"
echo "#_REQUEST_|auth:$(echo $http_req__auth | sed 's#:.*#:xxxxxxxx#')"
echo "#_REQUEST_|body:$http_req__body"
echo "#_REQUEST_|baseurl:$http_req__baseurl"
echo "#_REQUEST_|url:$http_req__url"
......@@ -314,39 +315,42 @@ EOH
# ---------- PUBLIC REQUEST GETTER
function http.getRequestTs(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http._getFilteredResponse REQUEST | grep "^timestamp" | cut -f 2 -d ":"
}
# get age of the response in sec.
# It is especially useful after responseImport
function http.getRequestAge(){
http._wd "${FUNCNAME[0]}($1)"
typeset -i local iAge=`date +%s`-`http.getRequestTs`
echo $iAge
http._wd "${FUNCNAME[0]}()"
typeset -i local iAge
typeset -i local iTs
iTs=$( http.getRequestTs )
iAge=$( date +%s )-${iTs}
echo "$iAge"
}
# ---------- PUBLIC RESPONSE GETTER
# get response body
function http.getResponse(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http._getFilteredResponse BODY
}
# get curl data of this request with status, transferred bytes, speed, ...
function http.getResponseData(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http._getFilteredResponse DATA
}
# get response header
function http.getResponseHeader(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http._getFilteredResponse HEADER
}
# get raw response (not available after import)
function http.getResponseRaw(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
echo "${http_resp__all}"
}
......@@ -360,8 +364,7 @@ EOH
# get Http status code of the request as 3 digit number
function http.getStatuscode(){
http._wd "${FUNCNAME[0]}($1)"
local _filter=$1
http._wd "${FUNCNAME[0]}()"
http.getResponseData | grep "^http_code:" | cut -f 2 -d ":"
}
......@@ -371,35 +374,35 @@ EOH
# $? -eq 0 means YES
# $? -ne 0 means NO
function http.isOk(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http.getStatuscode | grep '2[0-9][0-9]'
}
# was the repsonse a redirect?
function http.isRedirect(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http.getStatuscode | grep '3[0-9][0-9]'
}
# was the repsonse a client error (4xx or 5xx)
function http.isError(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http.getStatuscode | grep '[45][0-9][0-9]'
}
# was the repsonse a client error (4xx)
function http.isClientError(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http.getStatuscode | grep '4[0-9][0-9]'
}
# was the repsonse a client error (5xx)
function http.isServerError(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http.getStatuscode | grep '5[0-9][0-9]'
}
# dump information about request and response
function http.dump(){
http._wd "${FUNCNAME[0]}($1)"
http._wd "${FUNCNAME[0]}()"
http.responseExport
}
......@@ -411,37 +414,42 @@ EOH
# param string import or export filename
function http._genOutfilename(){
http._wd "${FUNCNAME[0]}($1)"
echo $1 | grep "AUTOFILE" >/dev/null
echo "$1" | grep "AUTOFILE" >/dev/null
if [ $? -ne 0 ]; then
echo $1
else
local sum=`echo ${http_req__fullurl} | sha1sum `
local autofile=`echo "${sum}__${http_req__fullurl}" | sed "s#[^a-z0-9]#_#g"`
echo $1 | sed "s#AUTOFILE#${autofile}#"
local sum
sum=$(echo ${http_req__fullurl} | sha1sum )
local autofile
autofile=$(echo "${sum}__${http_req__fullurl}" | sed "s#[^a-z0-9]#_#g")
echo "$1" | sed "s#AUTOFILE#${autofile}#"
fi
}
# export to a file
# export response to a file
# param string optional: custom filename
function http.responseExport(){
http._wd "${FUNCNAME[0]}($1)"
if [ -z $1 ]; then
if [ -z "$1" ]; then
echo "${http_resp__neutral}"
else
local outfile=`http._genOutfilename "$1"`
local outfile
outfile=$(http._genOutfilename "$1")
http._wd "${FUNCNAME[0]}($1) writing to outfile $outfile"
echo "${http_resp__neutral}" >$outfile
echo "${http_resp__neutral}" >"$outfile"
fi
}
# import a former response from a file
function http.responseImport(){
http._wd "${FUNCNAME[0]}($1)"
local infile=`http._genOutfilename "$1"`
local infile
infile=$(http._genOutfilename "$1")
if [ -r "${infile}" ]; then
grep "^#_META_|about:$http_cfg__about" "${infile}" >/dev/null
if [ $? -eq 0 ]; then
http_resp__neutral=`cat "${infile}"`
http_resp__neutral=$(cat "${infile}")
else
echo "ERROR: Ooops [${infile}] does not seem to be an export dump."
http.quit
......@@ -455,7 +463,8 @@ EOH
# AUTOFILE functionality
function http.responseDelete(){
http._wd "${FUNCNAME[0]}($1)"
local infile=`http._genOutfilename "$1"`
local infile
infile=$(http._genOutfilename "$1")
if [ -r "${infile}" ]; then
grep "^#_META_|about:$http_cfg__about" "${infile}" >/dev/null
if [ $? -eq 0 ]; then
......@@ -499,7 +508,7 @@ EOH
function http.setBaseUrl(){
http._wd "${FUNCNAME[0]}($1)"
http_req__baseurl=$1
http.setFullUrl
http.setFullUrl ""
}
# Enable or disable debug mode
# param integer 0|1
......@@ -520,7 +529,7 @@ EOH
}
# set a full url to request
# param string url
# param string optional: url
function http.setFullUrl(){
http._wd "${FUNCNAME[0]}($1)"
if [ -z "$1" ]; then
......@@ -653,7 +662,7 @@ INSTRUCTION:
Get the http status as string Ok|Redirect|Error
http.getStatuscode
Get the http status code of a request as integer
Get the http status code of a request as 3 digit integer
http.isOk
Check if the http response code is a 2xx
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment