Skip to content
Snippets Groups Projects

No insecure flag by default

Merged Hahn Axel (hahn) requested to merge no-insecure-flag-by-default into master
2 files
+ 1087
1024
Compare changes
  • Side-by-side
  • Inline
Files
2
http.class.sh 0 → 100644
+ 1084
0
 
#!/bin/bash
 
# ======================================================================
 
#
 
# REST API CLIENT USING CURL
 
#
 
# REQUIREMENTS
 
# - Bash (Linux or MS Windows i.e with Cygwin)
 
# - curl
 
# - sha1sum (optional; for export functionality with AUTOFILE only)
 
# ----------------------------------------------------------------------
 
# License: GPL 3.0
 
# Source: <https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client>
 
# Docs: <https://os-docs.iml.unibe.ch/bash-rest-api-client/>
 
# ----------------------------------------------------------------------
 
# (1) source this script
 
# (2) enter "http.help" to get a list of available commands
 
# ----------------------------------------------------------------------
 
# 2020-02-07 v0.2 axel.hahn@iml.unibe.ch BETABETA
 
# 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
 
# 2024-10-09 v0.8 axel.hahn@unibe.ch add setAuthorization; customize accept header, add custom request headers
 
# 2024-10-10 v0.9 axel.hahn@unibe.ch update docs
 
# 2024-10-23 v0.10 axel.hahn@unibe.ch update help
 
# 2024-11-20 v0.11 axel.hahn@unibe.ch no insecure requests by default; add setInsecure, setCA, addCurlparam
 
# ======================================================================
 
 
http_cfg__about="Bash REST API client v0.11"
 
typeset -i http_cfg__debug=0
 
typeset -i http_cfg__cacheTtl=0
 
http_cfg__cacheDir=/var/tmp/http-cache
 
http_cfg__UA="${http_cfg__about}"
 
http_cfg__prjurl="https://git-repo.iml.unibe.ch/iml-open-source/bash-rest-api-client"
 
http_cfg__docsurl="https://os-docs.iml.unibe.ch/bash-rest-api-client/"
 
 
# --- curl meta infos to collect
 
# see variables in man curl --write-out param
 
curlMeta="\
 
http_code \
 
http_connect \
 
local_ip \
 
local_port \
 
num_connects \
 
num_redirects \
 
redirect_url \
 
remote_ip \
 
remote_port \
 
size_download \
 
size_header \
 
size_request \
 
size_upload \
 
speed_download \
 
speed_upload \
 
ssl_verify_result \
 
time_appconnect \
 
time_connect \
 
time_namelookup \
 
time_pretransfer \
 
time_redirect \
 
time_starttransfer \
 
time_total \
 
url_effective \
 
"
 
 
 
# ----------------------------------------------------------------------
 
#
 
# functions
 
#
 
# ----------------------------------------------------------------------
 
 
# ......................................................................
 
#
 
# Write a debug message to STDERR
 
# Do no not change the prefix - is is read in inc_functions
 
#
 
# params strings output message
 
#
 
function http._wd(){
 
if [ $http_cfg__debug -gt 0 ]; then
 
echo -e "\e[33m# RESTAPI::DEBUG $*\e[0m" >&2
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Write an error message to STDERR
 
# Do no not change the prefix - is is read in inc_functions
 
#
 
# params strings output message
 
#
 
function http._we(){
 
echo -e "\e[31m# RESTAPI::ERROR $*\e[0m" >&2
 
}
 
 
function http(){
 
cat <<EOH
 
 
$http_cfg__about
 
 
A REST API Client with curl
 
 
Enter http.help to show all commands.
 
 
EOH
 
# $0 is not the current file if we source a script
 
# grep "function http.[a-z]" $0 | sort
 
}
 
 
# ......................................................................
 
#
 
# Initialize the client
 
#
 
# Initialize the client for a new request. Call this before any other
 
# function. It will reset all variables.
 
#
 
function http.init(){
 
http._wd "${FUNCNAME[0]}()"
 
which curl >/dev/null || http.quit
 
 
# request vars
 
 
http_req__auth=
 
http_req__authorization=
 
http_req__accept="application/json"
 
http_req__headers=()
 
http_req__curlparams=()
 
 
http_req__body=
 
http_req__method=GET
 
http_req__url=
 
http_req__fullurl=
 
http_req__docs=
 
http_req__cafile=
 
http_req__insecure=
 
 
http_req__dataprefix="RESTAPICLIENTMETADATA_$(date +%s)_$$"
 
local writevar=
 
for myvar in $curlMeta
 
do
 
writevar="${writevar}|${myvar}:%{${myvar}}"
 
done
 
http_curl__writeout="\\n${http_req__dataprefix}${writevar}\\n"
 
 
# cache
 
http_cfg__cacheTtl=0
 
http_cfg__cacheFile=
 
 
# response
 
http_resp__all=
 
http_resp__neutral=
 
mkdir ${http_cfg__cacheDir} 2>/dev/null
 
chmod 777 ${http_cfg__cacheDir} 2>/dev/null
 
}
 
 
# ......................................................................
 
#
 
# Execute the request
 
#
 
# param string optional: method; GET|POST|PUT|DELETE|...
 
# param string optional: full url
 
# param string optional: request body
 
#
 
# description:
 
#
 
# This function does the following:
 
#
 
# 1. Check if to use a cache
 
# 2. If not cached, make the request
 
# 3. If cached, use the cached result
 
#
 
function http.makeRequest(){
 
http._wd "${FUNCNAME[0]}()"
 
 
# --- handle optional prams
 
if [ $# -ne 0 ]; then
 
if echo "$1" | grep -q "^[A-Z]*$"; then
 
http.setMethod "$1"
 
shift 1
 
fi
 
http.setUrl "$1"
 
http.setBody "$2"
 
fi
 
# test -z "$1" || http.setFullUrl "$1"
 
 
# --- detect caching
 
local useCache=0
 
local makeRequest=1
 
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")
 
if [ -f "${http_cfg__cacheFile}" ]; then
 
http.responseImport "${http_cfg__cacheFile}"
 
local iAge; typeset -i 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 ] && [ $iAge -lt $http_cfg__cacheTtl ]; then
 
http._wd "INFO: Using cache"
 
makeRequest=0
 
else
 
http._wd "INFO: Cache file will be updated after making the request"
 
rm -f "${http_cfg__cacheFile}" 2>/dev/null
 
fi
 
fi
 
fi
 
 
 
# --- make the request
 
if [ $makeRequest -eq 1 ]; then
 
 
# build curl parameters
 
local curl_params=(
 
-s
 
-i "${http_req__fullurl}"
 
-X "${http_req__method}"
 
-A "${http_cfg__UA}"
 
)
 
test -n "$http_req__auth" && curl_params+=( -u "$http_req__auth" )
 
test -n "$http_req__authorization" && curl_params+=( -H "Authorization: $http_req__authorization" )
 
test -n "$http_req__accept" && curl_params+=( -H "Accept: $http_req__accept" )
 
test -n "$http_req__body" && curl_params+=( -d "${http_req__body}" )
 
test -n "$http_req__insecure" && curl_params+=( -k )
 
test -n "$http_req__cafile" && curl_params+=( --cacert "$http_req__cafile" )
 
curl_params+=( "${http_req__headers[@]}" )
 
curl_params+=( "${http_req__curlparams[@]}" )
 
 
http._wd "${FUNCNAME[0]}($1) ${http_req__method} ${http_req__fullurl}"
 
http._wd "${FUNCNAME[0]}($1) ${curl_params[@]}"
 
curl_params+=( -w "${http_curl__writeout}" )
 
 
http_resp__all=$( curl "${curl_params[@]}") || http.quit
 
 
http._wd "OK - Curl finished the http request ... processing data"
 
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)"
 
}
 
 
# ......................................................................
 
#
 
# Show error message with last return code and quit with this exitcode
 
#
 
# This function is used to quit the script with a meaningful error message
 
# and the exit code of the last command.
 
#
 
# The message is printed to STDERR and contains the return code.
 
# If a documentation URL is known, it is printed as a hint.
 
#
 
# The exit code is the one of the last command.
 
# To prevent the script from exiting when this function is called from a
 
# sourced file, the exit is commented out.
 
#
 
# no params
 
#
 
function http.quit(){
 
rc=$?
 
http._wd "${FUNCNAME[0]}()"
 
echo >&2
 
echo -e "\e[31m# ERROR: command FAILED with rc $rc. \e[0m" >&2
 
if [ ! -z "${RestApiDocs}" ]; then
 
echo "HINT: see ${RestApiDocs}" >&2
 
fi
 
# dont make exit in a sourced file
 
# exit $rc
 
}
 
 
 
# ......................................................................
 
#
 
# Load a config file
 
#
 
# This function is marked as deprecated.
 
# It will be removed in the future.
 
#
 
# param string config file name
 
#
 
# Sourcing that file will set the following vars
 
# - RestApiUser
 
# - RestApiPassword
 
# - RestApiBaseUrl
 
# - RestApiDocs
 
#
 
# The function will then set the "internal" vars
 
# - http_req__auth
 
# - http_req__fullurl
 
# - http_req__docs
 
#
 
function http.loadcfg(){
 
http._wd "${FUNCNAME[0]}($1) !!! DEPRECATED !!!"
 
# reset expected vars from config
 
RestApiUser=
 
RestApiPassword=
 
RestApiBaseUrl=
 
RestApiDocs=
 
 
# source config file
 
. "${1}" || http.quit
 
 
# set "internal" vars
 
if [ -z "$RestApiPassword" ]; then
 
http.setAuth "$RestApiUser:$RestApiPassword"
 
else
 
http.setAuth
 
fi
 
http.setBaseUrl "${RestApiBaseUrl}"
 
http.setDocs "${RestApiDocs}"
 
}
 
 
# ======================================================================
 
# GETTER
 
# ======================================================================
 
 
# ......................................................................
 
#
 
# Get the response header or response body
 
#
 
# param string what to return; one of header|body
 
#
 
# Return the response header or the response body. The output is the same
 
# as that of http.getResponseHeader or http.getResponse. The difference is
 
# the implementation
 
#
 
function http._fetchResponseHeaderOrBody(){
 
http._wd "${FUNCNAME[0]}($1)"
 
local isheader=true
 
 
# keep leading spaces
 
IFS=''
 
 
echo "${http_resp__all}" | grep -v "${http_req__dataprefix}" | while read -r line; do
 
if $isheader; then
 
if [[ $line = $'\r' ]]; then
 
isheader=false
 
else
 
test "$1" = "header" && echo $line
 
fi
 
else
 
# body="$body"$'\n'"$line"
 
test "$1" = "body" && echo $line
 
fi
 
done
 
}
 
 
# ......................................................................
 
#
 
# Get the response data
 
#
 
# Return the curl meta infos like http_code, http_connect, local_ip, ...
 
# as key/ value pairs. Each line is a single key value pair.
 
#
 
# The data is extracted from the response header. The format is:
 
# ${http_req__dataprefix}|key|value|key|value|...
 
#
 
function http._fetchResponseData(){
 
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"
 
done
 
}
 
 
# ......................................................................
 
#
 
# Generate the dump with request and response
 
function http._fetchAllAndReformat(){
 
http._wd "${FUNCNAME[0]}()"
 
IFS=''
 
line="#------------------------------------------------------------"
 
 
echo "#_META_|about:$http_cfg__about"
 
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_|body:$http_req__body"
 
echo "#_REQUEST_|baseurl:$http_req__baseurl"
 
echo "#_REQUEST_|url:$http_req__url"
 
echo "#_REQUEST_|docs:$http_req__docs"
 
echo $line
 
http._fetchResponseHeaderOrBody header | sed "s,^,#_HEADER_|,g"
 
echo $line
 
http._fetchResponseData | sed "s,^,#_DATA_|,g"
 
echo $line
 
http._fetchResponseHeaderOrBody body | sed "s,^,#_BODY_|,g"
 
echo $line END
 
}
 
 
# ......................................................................
 
#
 
# Get a section from dump data
 
#
 
# param string what to return; one of HEADER|DATA|BODY
 
#
 
# returns string the requested part of the response
 
#
 
function http._getFilteredResponse(){
 
http._wd "${FUNCNAME[0]}($1)"
 
echo "${http_resp__neutral}" | grep "^#_${1}_|" | cut -f 2- -d "|"
 
}
 
 
# ---------- PUBLIC REQUEST GETTER
 
 
# ......................................................................
 
#
 
# Get timestamp of the response as a Unix timestamp.
 
#
 
# no param
 
#
 
# returns string the timestamp of the response
 
#
 
function http.getRequestTs(){
 
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
 
#
 
# no param
 
#
 
# returns integer age of the response in sec
 
#
 
function http.getRequestAge(){
 
http._wd "${FUNCNAME[0]}()"
 
local iAge; typeset -i iAge
 
local iTs; typeset -i iTs
 
iTs=$( http.getRequestTs )
 
iAge=$( date +%s )-${iTs}
 
echo "$iAge"
 
}
 
 
# ---------- PUBLIC RESPONSE GETTER
 
 
# ......................................................................
 
#
 
# Get response body
 
#
 
# no param
 
#
 
# returns string the response body
 
#
 
function http.getResponse(){
 
http._wd "${FUNCNAME[0]}()"
 
http._getFilteredResponse BODY
 
}
 
 
# ......................................................................
 
#
 
# Get curl data of this request with status, transferred bytes, speed, ...
 
#
 
# no param
 
#
 
# returns string the response data
 
#
 
function http.getResponseData(){
 
http._wd "${FUNCNAME[0]}()"
 
http._getFilteredResponse DATA
 
}
 
 
# ......................................................................
 
#
 
# Get response header
 
#
 
# no param
 
#
 
# returns string the response header
 
#
 
function http.getResponseHeader(){
 
http._wd "${FUNCNAME[0]}()"
 
http._getFilteredResponse HEADER
 
}
 
 
# ......................................................................
 
#
 
# Get raw response (not available after import)
 
#
 
# no params
 
#
 
# no param
 
#
 
function http.getResponseRaw(){
 
http._wd "${FUNCNAME[0]}()"
 
echo "${http_resp__all}"
 
}
 
 
# ......................................................................
 
#
 
# Get Http status as string OK|Redirect|Error
 
#
 
# no params
 
#
 
function http.getStatus(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http.isOk >/dev/null && echo OK
 
http.isRedirect >/dev/null && echo Redirect
 
http.isError >/dev/null && echo Error
 
}
 
 
# ......................................................................
 
#
 
# Get Http status code of the request as 3 digit number
 
#
 
# no params
 
#
 
function http.getStatuscode(){
 
http._wd "${FUNCNAME[0]}()"
 
http.getResponseData | grep "^http_code:" | cut -f 2 -d ":"
 
}
 
 
# ......................................................................
 
#
 
# Check: was response a 2xx status code?
 
# output is a statuscode if it matches ... or empty
 
# Additionally you can verify the return code
 
#
 
# $? -eq 0 means YES
 
# $? -ne 0 means NO
 
#
 
# no params
 
#
 
function http.isOk(){
 
http._wd "${FUNCNAME[0]}()"
 
http.getStatuscode | grep '2[0-9][0-9]'
 
}
 
 
# ......................................................................
 
#
 
# Was the repsonse a redirect?
 
#
 
# no params
 
#
 
function http.isRedirect(){
 
http._wd "${FUNCNAME[0]}()"
 
http.getStatuscode | grep '3[0-9][0-9]'
 
}
 
 
# ......................................................................
 
#
 
# Was the repsonse a client error (4xx or 5xx)
 
#
 
# no params
 
#
 
function http.isError(){
 
http._wd "${FUNCNAME[0]}()"
 
http.getStatuscode | grep '[45][0-9][0-9]'
 
}
 
 
# ......................................................................
 
#
 
# Was the repsonse a client error (4xx)
 
#
 
# no params
 
#
 
function http.isClientError(){
 
http._wd "${FUNCNAME[0]}()"
 
http.getStatuscode | grep '4[0-9][0-9]'
 
}
 
 
# ......................................................................
 
#
 
# Was the repsonse a client error (5xx)
 
#
 
# no params
 
#
 
function http.isServerError(){
 
http._wd "${FUNCNAME[0]}()"
 
http.getStatuscode | grep '5[0-9][0-9]'
 
}
 
 
# ......................................................................
 
#
 
# Dump information about request and response
 
#
 
# no params
 
#
 
function http.dump(){
 
http._wd "${FUNCNAME[0]}()"
 
http.responseExport
 
}
 
 
# ======================================================================
 
# Import/ Export
 
# ======================================================================
 
 
# ......................................................................
 
#
 
# Helper to replace "AUTOFILE" with something uniq using full url
 
#
 
# param string import or export filename
 
#
 
function http._genOutfilename(){
 
http._wd "${FUNCNAME[0]}($1)"
 
if echo "$1" | grep -q "AUTOFILE"; then
 
echo "$1"
 
else
 
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 response to a file
 
#
 
# param string optional: custom filename
 
#
 
function http.responseExport(){
 
http._wd "${FUNCNAME[0]}($1)"
 
if [ -z "$1" ]; then
 
echo "${http_resp__neutral}"
 
else
 
local outfile
 
outfile=$(http._genOutfilename "$1")
 
http._wd "${FUNCNAME[0]}($1) writing to outfile $outfile"
 
echo "${http_resp__neutral}" >"$outfile"
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Import a former response from a file
 
#
 
# param string filename with stored response
 
#
 
function http.responseImport(){
 
http._wd "${FUNCNAME[0]}($1)"
 
local infile
 
infile=$(http._genOutfilename "$1")
 
if [ -r "${infile}" ]; then
 
if grep -q "^#_META_|about:$http_cfg__about" "${infile}"; then
 
http_resp__neutral=$(cat "${infile}")
 
else
 
echo "ERROR: Ooops [${infile}] does not seem to be an export dump."
 
http.quit
 
fi
 
else
 
echo "ERROR: Ooops the file [${infile}] is not readable."
 
http.quit
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Delete an exported file; this is especially useful if you use
 
# AUTOFILE functionality
 
#
 
# param string filename with stored response
 
#
 
function http.responseDelete(){
 
http._wd "${FUNCNAME[0]}($1)"
 
local infile
 
infile=$(http._genOutfilename "$1")
 
if [ -r "${infile}" ]; then
 
if grep -q "^#_META_|about:$http_cfg__about" "${infile}"; then
 
if rm -f "${infile}"; then
 
http._wd "OK, ${infile} was deleted."
 
else
 
http._wd "ERROR: unable to delete existing ${infile}. Check permissions."
 
fi
 
else
 
http._wd "SKIP: ${infile} is not an export file."
 
fi
 
else
 
http._wd "SKIP: ${infile} is not readable."
 
fi
 
}
 
 
# ======================================================================
 
# SETTER
 
# ======================================================================
 
 
# ......................................................................
 
#
 
# Add a line to the request header
 
#
 
# param string line to add, eg "Connection: keep-alive"
 
#
 
function http.addHeader(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__headers+=( -H "$1")
 
}
 
 
# ......................................................................
 
#
 
# Add an additional curl parameter
 
#
 
# param string line to add, eg "Connection: keep-alive"
 
#
 
function http.addCurlparam(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__curlparams+=( "$1")
 
}
 
 
# ......................................................................
 
#
 
# set Accept request header and override default
 
#
 
# param string accept header value, eg text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
 
#
 
function http.setAccept(){
 
http._wd "${FUNCNAME[0]}($1)"
 
if [ -z "$1" ]; then
 
http_req__accept=
 
else
 
http_req__accept="$1"
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Set basic authentication
 
# Without given parameter, authentication is removed
 
#
 
# param string optional: USER:PASSWORD
 
#
 
function http.setAuth(){
 
http._wd "${FUNCNAME[0]}($1)"
 
if [ -z "$1" ]; then
 
http_req__auth=
 
else
 
http_req__auth="$1"
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Set authentication via Athorization header
 
# Without given parameter, authorization is removed
 
#
 
# param string optional: type, eg. Basic|Bearer|Negotiate
 
# param string optional: token or encoded user + password
 
#
 
function http.setAuthorization(){
 
http._wd "${FUNCNAME[0]}($1 $2)"
 
if [ -z "$1" ]; then
 
http_req__authorization=
 
else
 
http_req__authorization="${1} ${2}"
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Set body to send for PUTs and POSTs
 
#
 
# param string body
 
#
 
function http.setBody(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__body=$1
 
}
 
 
# ......................................................................
 
#
 
# Set a base url of an API
 
# Remark: Then use http.setUrl to complet the url to request
 
#
 
# param string url
 
#
 
function http.setBaseUrl(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__baseurl=$1
 
http.setFullUrl ""
 
}
 
 
# ......................................................................
 
#
 
# set and unset CA cert file to use
 
#
 
# param string optional: filename to use; no value to disable cafile
 
#
 
function http.setCA(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__cafile="$1"
 
}
 
 
# ......................................................................
 
#
 
# Enable or disable debug mode
 
#
 
# param integer 0|1
 
#
 
function http.setDebug(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_cfg__debug=$1
 
}
 
 
 
function http.setDocs(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__docs=$1
 
}
 
# ......................................................................
 
#
 
# Allow and disallow insecure connections
 
#
 
# param string optional: 1 to enable insecure flag; no value to disable insecure flag
 
#
 
function http.setInsecure(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__insecure="$1"
 
}
 
 
# ......................................................................
 
#
 
# Set the method to use; GET|POST|PUT|DELETE|...
 
#
 
# param string name of method
 
#
 
function http.setMethod(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__method=$1
 
}
 
 
# ......................................................................
 
#
 
# Set a full url to request
 
#
 
# param string optional: url
 
#
 
function http.setFullUrl(){
 
http._wd "${FUNCNAME[0]}($1)"
 
if [ -z "$1" ]; then
 
http_req__fullurl=${http_req__baseurl}${http_req__url}
 
else
 
http_req__fullurl=$1
 
fi
 
}
 
 
# ......................................................................
 
#
 
# Complete the base url
 
#
 
# param string url part behind base url
 
#
 
function http.setUrl(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_req__url=$1
 
http.setFullUrl
 
}
 
 
# ----- caching
 
 
# ......................................................................
 
#
 
# Set cache ttl in seconds
 
#
 
# param integer ttl in seconds
 
#
 
function http.setCacheTtl(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_cfg__cacheTtl=$1
 
}
 
 
# ......................................................................
 
#
 
# Set cache file
 
#
 
# param string filename
 
#
 
function http.setCacheFile(){
 
http._wd "${FUNCNAME[0]}($1)"
 
http_cfg__cacheFile="$1"
 
}
 
 
# ......................................................................
 
#
 
# Flush the cache
 
#
 
# no params
 
#
 
function http.flushCache(){
 
http._wd "${FUNCNAME[0]}($1)"
 
rm -f ${http_cfg__cacheDir}/*
 
}
 
 
# ......................................................................
 
#
 
# show a help text
 
#
 
# no params
 
#
 
function http.help(){
 
cat <<EOH
 
 
$http_cfg__about
 
 
This is a bash solution to script REST API calls.
 
 
Source: <$http_cfg__prjurl>
 
Docs: <$http_cfg__docsurl>
 
License: GNU GPL 3
 
 
 
INSTRUCTION:
 
 
- Source the file once
 
- Then you can run functions starting with "http."
 
 
http.init
 
Start a new request. It resets internal vars of the last request
 
(if there was one).
 
 
http.setDebug 0|1
 
Enable or disable debugging infos during processing. It is written
 
to STDERR.
 
 
- initialize a request
 
 
setAccept "<ACCEPTHEADER>"
 
Set authentication with user and password for basic auth
 
Default: $http_req__accept
 
 
setAuth "<USER>:<PASSWORD>"
 
Set authentication with user and password for basic auth
 
Without given parameter, authentication is removed
 
 
setAuthorization "<TYPE>" "<TOKEN|HASH>"
 
Set authentication with Authorization header.
 
As TYPE you can use Basic|Bearer|Negotiate|...
 
2nd param is the token or hashed user+password
 
Without given parameter, authorization is removed
 
 
http.setBody "<DATA>"
 
set a body for POST/ PUT requests.
 
 
http.setBaseUrl "<URL>"
 
Set a base url to an api.
 
renmark:
 
Use http.setUrl to built a complete url.
 
 
http.setCA "<FILE>"
 
Set CA file to verify the server certificate.
 
Default: [empty] = use system defaults
 
Without parameter the cafile is removed
 
 
http.setDocs "<URL>"
 
Set a docs url. If set it will be shown as additional hint when a
 
request fails.
 
 
http.setInsecure 1
 
Set insecure flag by giving any non empty value.
 
Default: [empty] = secure requests
 
Without parameter the insecure flag is removed
 
 
http.setMethod "<METHOD>"
 
Set a http method. Use an uppercase string for GET|POST|PUT|DELETE|...
 
 
http.setFullUrl "<URL>"
 
Set a complete url for a request.
 
 
http.setUrl "<REQUEST?QUERY>"
 
Set a relative url for a request.
 
This requires to use http.setBaseUrl before.
 
 
http.addHeader "<HEADER_LINE>"
 
Add a header line to the request.
 
This command can be repeated multiple times to add multiple headers.
 
 
http.addCurlparam "<CURL_PARAMETER>"
 
Add any missing parameter for curl requestst.
 
This command can be repeated multiple times to add multiple prameters.
 
You also can add multiple parameters with one command.
 
 
- caching functions
 
 
http.setCacheTtl <SECONDS>
 
Enable caching with values > 0
 
Remark: only GET requests will be cached.
 
Default: 0 (no caching)
 
 
http.setCacheFile "<FILENAME>"
 
Set a file where to read/ store a request
 
Default: empty; autogenerated file below $http_cfg__cacheDir
 
 
http.flushCache
 
Delete all files in $http_cfg__cacheDir
 
 
- make the request
 
 
http.makeRequest [[<METHOD>] ["<URL>"] ["<BODY>"]]
 
The parameters are optional. Without parameter the request will be
 
started with given data in http.set* functions described above.
 
If minimum one param is given then they are handled:
 
METHOD optional: set a method (must be uppercase) - see http.setMethod
 
URL set a relative url - see http.setUrl
 
BODY optional: set a body - see http.setBody
 
 
The request will be skipped and uses a cached content if ...
 
- METHOD is GET
 
- http.setCacheTtl set a value > 0
 
- the cache file exists and is younger than the given TTL
 
 
- handle response
 
 
http.getResponse
 
Get the Response Body
 
 
http.getResponseData
 
Get Meta infos from curl
 
 
http.getResponseHeader
 
Get The http reponse header
 
 
- check http status code
 
 
http.getStatus
 
Get the http status as string Ok|Redirect|Error
 
 
http.getStatuscode
 
Get the http status code of a request as 3 digit integer
 
 
http.isOk
 
Check if the http response code is a 2xx
 
 
http.isRedirect
 
Check if the http response code is a 3xx
 
 
http.isError
 
Check if the http response code is a 4xx or 5xx
 
 
http.isClientError
 
Check if the http response code is a 4xx
 
 
http.isServerError
 
Check if the http response code is a 5xx
 
 
http.getRequestAge
 
Get the age of the request in seconds.
 
Remark: This function is useful after an import
 
see http.responseImport.
 
 
http.getRequestTs
 
Get the Unix timestamp of the request
 
 
- import/ export
 
 
http.responseExport ["<FILE>"]
 
dump the response data
 
Without parameter it is written on STDOUT.
 
You can set a filename to write it to a file.
 
The filename can contain "AUTOFILE" this string
 
will be replaced with a uniq string.
 
(requires sha1sum and a set url)
 
Example:
 
http.makeRequest "https://example.com/api/"
 
http.responseExport /tmp/something_AUTOFILE_.txt
 
 
http.responseImport "<FILE>"
 
Import an export file.
 
To use the AUTOFILE mechanism from export set
 
the url first.
 
Example:
 
http.setFullUrl "https://example.com/api/"
 
http.responseImport /tmp/something_AUTOFILE_.txt
 
 
http.responseDelete "<FILE>"
 
Delete a file after http.responseExport.
 
It is useful if you use the AUTOFILE mechanism.
 
 
EOH
 
}
 
 
# ----------------------------------------------------------------------
 
#
 
# main
 
#
 
# ----------------------------------------------------------------------
 
 
http.init
 
 
# ----------------------------------------------------------------------
Loading