Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
B
bash-rest-api-client
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
IML Open Source
bash-rest-api-client
Commits
e553dea9
Commit
e553dea9
authored
3 years ago
by
Hahn Axel (hahn)
Browse files
Options
Downloads
Patches
Plain Diff
v0.7 fixes using shellcheck
parent
b4e13b0b
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
rest-api-client.sh
+66
-57
66 additions, 57 deletions
rest-api-client.sh
with
66 additions
and
57 deletions
rest-api-client.sh
+
66
−
57
View file @
e553dea9
...
...
@@ -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
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment