diff --git a/http.class.sh b/http.class.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1061a0e59f27209066848d8f313a7e3071445b4a
--- /dev/null
+++ b/http.class.sh
@@ -0,0 +1,1084 @@
+#!/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
+
+# ----------------------------------------------------------------------
diff --git a/rest-api-client.sh b/rest-api-client.sh
index 0ac9e9d0a66aedb0a7ea3eb973d33e90988245ae..b07340cae95f7208920d12545800d1e8188e9f4c 100644
--- a/rest-api-client.sh
+++ b/rest-api-client.sh
@@ -1,1027 +1,6 @@
 #!/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
-# ======================================================================
 
-  http_cfg__about="Bash REST API client v0.10"
-  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/"
+>&2 echo "DEPRECATED: Source 'http.class.sh' instead of 'rest-api-client.sh'"
 
-# --- 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__body=
-    http_req__method=GET
-    http_req__url=
-    http_req__fullurl=
-    http_req__docs=
-
-    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=(
-        -k 
-        -s
-        -i "${http_req__fullurl}"
-        -X "${http_req__method}"
-        -w "${http_curl__writeout}"
-        -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}" )
-      curl_params+=( "${http_req__headers[@]}" )
-
-      http._wd "${FUNCNAME[0]}($1) ${http_req__method} ${http_req__fullurl}"      
-      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")
-  }
-
-  # ......................................................................
-  #
-  # 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 ""
-  }
-
-  # ......................................................................
-  #
-  # 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
-  }
-
-  # ......................................................................
-  #
-  # 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.setDocs "<URL>"
-      Set a docs url. If set it will be shown as additional hint when a 
-      request fails.
-
-    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.
-
-- 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
-
-# ----------------------------------------------------------------------
+script_dir=$(dirname "$BASH_SOURCE[0]")
+. "$script_dir/http.class.sh" $*