Restconf: Fixed http accept/content-type logic

yang mem-leak
This commit is contained in:
Olof hagsand 2024-09-16 13:47:28 +02:00
parent f1d9e26755
commit 158ea40b59
6 changed files with 63 additions and 58 deletions

View file

@ -282,19 +282,20 @@ api_http_data_file(clixon_handle h,
char *pathname,
int head)
{
int retval = -1;
cbuf *cbfile = NULL;
char *filename = NULL;
cbuf *cbdata = NULL;
FILE *f = NULL;
off_t fsz = 0;
long fsize;
char *www_data_root = NULL;
char *suffix;
char *media;
int ret;
char *buf = NULL;
size_t sz;
int retval = -1;
cbuf *cbfile = NULL;
char *filename = NULL;
cbuf *cbdata = NULL;
FILE *f = NULL;
off_t fsz = 0;
long fsize;
char *www_data_root = NULL;
char *suffix;
char *media;
char *buf = NULL;
size_t sz;
char *media_list = NULL;
int ret;
clixon_debug(CLIXON_DBG_RESTCONF, "");
if ((cbfile = cbuf_new()) == NULL){
@ -305,7 +306,6 @@ api_http_data_file(clixon_handle h,
clixon_err(OE_RESTCONF, ENOENT, "CLICON_HTTP_DATA_ROOT missing");
goto done;
}
cprintf(cbfile, "%s", www_data_root);
if (pathname){
if (strlen(pathname) && pathname[0] != '/'){
@ -331,6 +331,19 @@ api_http_data_file(clixon_handle h,
if ((media = clicon_str2str(mime_map, suffix)) == NULL)
media = "application/octet-stream";
}
/* 5. Accepted media_out: should check text/html, JavaScript, image, and css
*/
if ((media_list = restconf_param_get(h, "HTTP_ACCEPT")) != NULL){
if (restconf_media_in_list(media, media_list) != 1 &&
restconf_media_in_list("*/*", media_list) != 1) {
/* If the server does not support any of the requested
* output encodings for a request, then it MUST return an error response
* with a "406 Not Acceptable" status-line. */
if (restconf_not_acceptable(h, req, 1, HTTP_DATA_TEXT_HTML) < 0)
goto done;
goto ok;
}
}
/* Size could have been taken from stat() but this reduces the race condition interval
* There is still one without flock
*/
@ -416,12 +429,11 @@ api_http_data(clixon_handle h,
{
int retval = -1;
char *request_method = NULL;
char *media_list = NULL;
int head = 0;
int options = 0;
int ret;
cbuf *indata = NULL;
char *path = NULL;
int ret;
clixon_debug(CLIXON_DBG_RESTCONF, "");
if (req == NULL){
@ -467,20 +479,6 @@ api_http_data(clixon_handle h,
goto done;
goto ok;
}
/* 5. Accepted media_out: should check text/html, JavaScript, image, and css
*/
if ((media_list = restconf_param_get(h, "HTTP_ACCEPT")) != NULL){
if (restconf_media_in_list("text/html", media_list) != 1 &&
restconf_media_in_list("*/*", media_list) != 1
&& 0) { /* XXX: not yet */
/* If the server does not support any of the requested
* output encodings for a request, then it MUST return an error response
* with a "406 Not Acceptable" status-line. */
if (restconf_not_acceptable(h, req, 1, HTTP_DATA_TEXT_HTML) < 0)
goto done;
goto ok;
}
}
/* 6. Authenticate
* Note, error handling may need change since it is restconf based
*/

View file

@ -78,7 +78,7 @@ openconfig:
./getopenconfig.sh
docker: clixon yang openconfig $(DOCKERFILE)
sudo docker build -f $(DOCKERFILE) -t $(IMG) $(DOCKERFLAGS) .
sudo docker build --progress plain -f $(DOCKERFILE) -t $(IMG) $(DOCKERFLAGS) .
push:
sudo docker push $(IMG)

View file

@ -912,11 +912,16 @@ ys_free1(yang_stmt *ys,
{
rpc_callback_t *rc;
cg_var *cv;
cvec *cvv;
if ((cv = ys->ys_cv) != NULL){ // To not trigger asserts
if ((cv = ys->ys_cv) != NULL){
ys->ys_cv = NULL;
cv_free(cv);
}
if ((cvv = ys->ys_cvec) != NULL){
ys->ys_cvec = NULL;
cvec_free(cvv);
}
if (ys->ys_argument){
free(ys->ys_argument);
ys->ys_argument = NULL;

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Run valgrind leak test for cli, restconf, netconf or background.
# Run valgrind leak test for backend, restconf, cli, netconf or snmp.
# Stop on first error
# Typical run: ./mem.sh 2>&1 | tee mylog
@ -7,29 +7,19 @@
: ${pattern:=test_*.sh}
# Run valgrindtest once, args:
# what: (cli|netconf|restconf|backend)* # no args means all
# what: (backend|restconf|cli|netconf|snmp)* # no args means all
function memonce(){
what=$1
valgrindfile=$(mktemp)
echo "valgrindfile:$valgrindfile"
clixon_cli=
clixon_netconf=
clixon_backend=
clixon_restconf=
clixon_cli=
clixon_netconf=
clixon_snmp=
case "$what" in
'cli')
valgrindtest=1
: ${DEMWAIT:=5} # valgrind backend needs some time to get up
clixon_cli="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_cli"
;;
'netconf')
valgrindtest=1
: ${DEMWAIT:=5} # valgrind backend needs some time to get up
clixon_netconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_netconf"
;;
'backend')
valgrindtest=2 # This means backend valgrind test
: ${DEMWAIT:=10} # valgrind backend needs some time to get up
@ -43,6 +33,16 @@ function memonce(){
: ${DEMWAIT:=15} # valgrind backend needs some time to get up
clixon_restconf="/usr/bin/valgrind --num-callers=50 --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_restconf"
;;
'cli')
valgrindtest=1
: ${DEMWAIT:=5} # valgrind backend needs some time to get up
clixon_cli="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_cli"
;;
'netconf')
valgrindtest=1
: ${DEMWAIT:=5} # valgrind backend needs some time to get up
clixon_netconf="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_netconf"
;;
'snmp')
valgrindtest=4 # This means snmp valgrind test
@ -50,9 +50,8 @@ function memonce(){
: ${DEMWAIT:=15} # valgrind snmp needs some time to get up
clixon_snmp="/usr/bin/valgrind --num-callers=50 --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --child-silent-after-fork=yes --log-file=$valgrindfile clixon_snmp"
;;
*)
echo "usage: $0 cli|netconf|restconf|backend|snmp" # valgrind memleak checks
echo "usage: $0 backend|restconf|cli|netconf|snmp" # valgrind memleak checks
rm -f $valgrindfile
exit -1
;;
@ -108,9 +107,9 @@ fi
# First run sanity
for c in $cmds; do
if [ $c != cli -a $c != netconf -a $c != restconf -a $c != backend -a $c != snmp ]; then
if [ $c != backend -a $c != restconf -a $c != cli -a $c != netconf -a $c != snmp ]; then
echo "c:$c"
echo "usage: $0 [cli|netconf|restconf|backend|snmp]+"
echo "usage: $0 [backend||restconf|cli|netconf|snmp]+"
echo " with no args run all"
exit -1
fi

View file

@ -213,10 +213,8 @@ EOF
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: wrong/media,*/*' $proto://localhost/data/index.html)" 0 "HT
TP/$HVER 200" "Content-Type: text/html" "<title>Welcome to Clixon!</title>"
if false; then # XXX Se step 5 in api_http_data, unclear which media should be accepted
new "Server does not support list of medias Expect 406"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: wrong/media' $proto://localhost/data/index.html)" 0 "HTTP/$HVER 406" "content-type: text/html" "<error-message>Unacceptable output encoding</error-message>"
fi
new "WWW get dir -> expect index.html"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data)" 0 "HTTP/$HVER 200" "Content-Type: text/html" "<title>Welcome to Clixon!</title>"
@ -231,7 +229,13 @@ fi
mv $dir/www/data/tmp.index.html $dir/www/data/index.html
new "WWW get css"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data/example.css)" 0 "HTTP/$HVER 200" "Content-Type: text/css" "display: inline;" --not-- "Content-Type: text/html"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/css' $proto://localhost/data/example.css)" 0 "HTTP/$HVER 200" "Content-Type: text/css" "display: inline;" --not-- "Content-Type: text/html"
new "WWW get css accept *"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html,*/*' $proto://localhost/data/example.css)" 0 "HTTP/$HVER 200" "Content-Type: text/css" "display: inline;" --not-- "Content-Type: text/html"
new "WWW get css, operation-not-supported"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data/example.css)" 0 "HTTP/$HVER 406" "operation-not-supported"
new "WWW head"
expectpart "$(curl $CURLOPTS --head -H 'Accept: text/html' $proto://localhost/data/index.html)" 0 "HTTP/$HVER 200" "Content-Type: text/html" --not-- "<title>Welcome to Clixon!</title>"

View file

@ -197,9 +197,8 @@ wait_restconf
new "Create album London Calling with PUT"
expectpart "$(curl -u andy:bar $CURLOPTS -X PUT -H 'Content-Type: application/yang-data+json' $RCPROTO://localhost/restconf/data/example-jukebox:jukebox/library/artist=Clash/album=London%20Calling -d '{"example-jukebox:album":{"name":"London Calling"}}')" 0 "HTTP/$HVER 201"
#new "The message-body for a plain patch MUST be present"
# XXX Hangs in SSL 3.3.2
#expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H 'Content-Type: application/yang-data+json' $RCPROTO://localhost/restconf/data/example-jukebox:jukebox/library/artist=Beatles -d '')" 0 "HTTP/$HVER 400" kalle
new "The message-body for a plain patch MUST be present"
expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H 'Content-Type: application/yang-data+json' $RCPROTO://localhost/restconf/data/example-jukebox:jukebox/library/artist=Beatles -d '')" 0 "HTTP/$HVER 400" "The message-body MUST contain exactly one instance of the expected data resource"
# Plain patch can be used to create or update, but not delete, a child
# resource within the target resource.