Added restconf handle specialization to implement restconf parameters

This commit is contained in:
Olof hagsand 2020-06-22 12:47:43 +02:00
parent 1597bd303c
commit 73bbcded87
22 changed files with 351 additions and 162 deletions

View file

@ -2,7 +2,8 @@
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
This file is part of CLIXON.

View file

@ -2,7 +2,8 @@
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
This file is part of CLIXON.

View file

@ -104,6 +104,7 @@ APPOBJ = $(APPSRC:.c=.o)
# (eg restconf_method_notallowed) that uses symbols in restconf_api that
# are not in the lib.
LIBSRC = restconf_lib.c
LIBSRC += restconf_handle.c
LIBOBJ = $(LIBSRC:.c=.o)

View file

@ -60,7 +60,8 @@ int get_user_cookie(char *cookiestr, char *attribute, char **val);
int restconf_terminate(clicon_handle h);
int restconf_insert_attributes(cxobj *xdata, cvec *qvec);
int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys);
char *clixon_restconf_param_get(clicon_handle h, char *param);
int clixon_restconf_param_set(clicon_handle h, char *param, char *val);
/* also in restconf_handle.h */
char *restconf_param_get(clicon_handle h, char *param);
int restconf_param_set(clicon_handle h, char *param, char *val);
#endif /* _CLIXON_RESTCONF_H_ */

View file

@ -98,7 +98,7 @@ restconf_badrequest(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
path = restconf_param_get("REQUEST_URI", r->envp);
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
goto done;
cprintf(cb, "The requested URL %s or data is in some way badly formed.\n", path);
@ -137,7 +137,7 @@ restconf_unauthorized(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
path = restconf_param_get("REQUEST_URI", r->envp);
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
goto done;
cprintf(cb, "<error-tag>access-denied</error-tag>\n");
@ -175,7 +175,7 @@ restconf_forbidden(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
path = restconf_param_get("REQUEST_URI", r->envp);
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
goto done;
cprintf(cb, "The requested URL %s was forbidden.\n", path);
@ -213,7 +213,7 @@ restconf_notfound(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
path = restconf_param_get("REQUEST_URI", r->envp);
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
goto done;
cprintf(cb, "The requested URL %s was not found on this server.\n", path);
@ -270,7 +270,7 @@ restconf_notacceptable(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
path = restconf_param_get("REQUEST_URI", r->envp);
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
goto done;
cprintf(cb, "The target resource does not have a current representation that would be acceptable to the user agent.\n", path);
@ -338,7 +338,7 @@ restconf_internal_server_error(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
path = clixon_restconf_param_get("REQUEST_URI", r->envp);
path = restconf_param_get("REQUEST_URI", r->envp);
if (restconf_reply_header(req, "Content-Type", "text/html") < 0)
goto done;
cprintf(cb, "Internal server error when accessing %s</h1>\n", path);

View file

@ -0,0 +1,174 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
This file is part of CLIXON.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the "GPL"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
*/
#ifdef HAVE_CONFIG_H
#include "clixon_config.h" /* generated by config & autoconf */
#endif
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/time.h>
#include <regex.h>
#include <syslog.h>
#include <netinet/in.h>
#include <limits.h>
/* cligen */
#include <cligen/cligen.h>
/* clicon */
#include <clixon/clixon.h>
#include "restconf_handle.h"
/* header part is copied from struct clicon_handle in lib/src/clixon_handle.c */
#define CLICON_MAGIC 0x99aafabe
#define handle(h) (assert(clicon_handle_check(h)==0),(struct restconf_handle *)(h))
/* Clicon_handle for backends.
* First part of this is header, same for clicon_handle and cli_handle.
* Access functions for common fields are found in clicon lib: clicon_options.[ch]
* This file should only contain access functions for the _specific_
* entries in the struct below.
*/
/*! Backend specific handle added to header CLICON handle
* This file should only contain access functions for the _specific_
* entries in the struct below.
* @note The top part must be equivalent to struct clicon_handle in clixon_handle.c
* @see struct clicon_handle, struct cli_handle
*/
struct restconf_handle {
int rh_magic; /* magic (HDR)*/
clicon_hash_t *rh_copt; /* clicon option list (HDR) */
clicon_hash_t *rh_data; /* internal clicon data (HDR) */
clicon_hash_t *rh_db_elmnt; /* xml datastore element cache data */
event_stream_t *rh_stream; /* notification streams, see clixon_stream.[ch] */
/* ------ end of common handle ------ */
clicon_hash_t *rh_params; /* restconf parameters, including http headers */
};
/*! Creates and returns a clicon config handle for other CLICON API calls
*/
clicon_handle
restconf_handle_init(void)
{
return clicon_handle_init0(sizeof(struct restconf_handle));
}
/*! Deallocates a backend handle, including all client structs
* @note: handle 'h' cannot be used in calls after this
* @see backend_client_rm
*/
int
restconf_handle_exit(clicon_handle h)
{
clicon_handle_exit(h); /* frees h and options (and streams) */
return 0;
}
/*! Get restconf http parameter
* @param[in] h Clicon handle
* @param[in] name Data name
* @retval val Data value as string
* Currently using clixon runtime data but there is risk for colliding names
*/
char *
restconf_param_get(clicon_handle h,
char *param)
{
struct restconf_handle *rh = handle(h);
if (rh->rh_params == NULL)
return NULL;
return (char*)clicon_hash_value(rh->rh_params, param, NULL);
}
/*! Set restconf http parameter
* @param[in] h Clicon handle
* @param[in] name Data name
* @param[in] val Data value as null-terminated string
* @retval 0 OK
* @retval -1 Error
* Currently using clixon runtime data but there is risk for colliding names
*/
int
restconf_param_set(clicon_handle h,
char *param,
char *val)
{
struct restconf_handle *rh = handle(h);
clicon_debug(1, "%s=%s", param, val);
if (rh->rh_params == NULL)
if ((rh->rh_params = clicon_hash_init()) == NULL)
return -1;
return clicon_hash_add(rh->rh_params, param, val, strlen(val)+1)==NULL?-1:0;
}
/*! Delete all restconf http parameter
* @param[in] h Clicon handle
* @param[in] name Data name
* @retval 0 OK
* @retval -1 Error
* Currently using clixon runtime data but there is risk for colliding names
*/
int
restconf_param_del_all(clicon_handle h)
{
int retval = -1;
struct restconf_handle *rh = handle(h);
if (rh->rh_params != NULL){
if (clicon_hash_free(rh->rh_params) < 0)
goto done;
rh->rh_params = NULL;
}
retval = 0;
done:
return retval;
}

View file

@ -0,0 +1,51 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
This file is part of CLIXON.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the "GPL"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
*
*/
#ifndef _RESTCONF_HANDLE_H_
#define _RESCTONF_HANDLE_H_
/*
* Prototypes
*/
clicon_handle restconf_handle_init(void);
int restconf_handle_exit(clicon_handle h);
char *restconf_param_get(clicon_handle h, char *param);
int restconf_param_set(clicon_handle h, char *param, char *val);
int restconf_param_del_all(clicon_handle h);
#endif /* _RESTCONF_HANDLE_H_ */

View file

@ -60,6 +60,7 @@
#include <clixon/clixon.h>
#include "restconf_api.h"
#include "restconf_handle.h"
#include "restconf_lib.h"
/* See RFC 8040 Section 7: Mapping from NETCONF<error-tag> to Status Code
@ -188,10 +189,10 @@ restconf_media_int2str(restconf_media media)
restconf_media
restconf_content_type(clicon_handle h)
{
char *str;
char *str = NULL;
restconf_media m;
if ((str = clixon_restconf_param_get(h, "HTTP_CONTENT_TYPE")) == NULL)
if ((str = restconf_param_get(h, "HTTP_CONTENT_TYPE")) == NULL)
return -1;
if ((int)(m = restconf_media_str2int(str)) == -1)
return -1;
@ -252,7 +253,7 @@ restconf_terminate(clicon_handle h)
if ((x = clicon_conf_xml(h)) != NULL)
xml_free(x);
xpath_optimize_exit();
clicon_handle_exit(h);
restconf_handle_exit(h);
clicon_log_exit();
return 0;
}
@ -412,53 +413,6 @@ restconf_main_extension_cb(clicon_handle h,
return retval;
}
/*! Get restconf http parameter
* @param[in] h Clicon handle
* @param[in] name Data name
* @retval val Data value as string
* Currently using clixon runtime data but there is risk for colliding names
*/
char *
clixon_restconf_param_get(clicon_handle h,
char *param)
{
char *val;
if (clicon_data_get(h, param, &val) < 0)
return NULL;
return val;
}
/*! Set restconf http parameter
* @param[in] h Clicon handle
* @param[in] name Data name
* @param[in] val Data value as null-terminated string
* @retval 0 OK
* @retval -1 Error
* Currently using clixon runtime data but there is risk for colliding names
*/
int
clixon_restconf_param_set(clicon_handle h,
char *param,
char *val)
{
clicon_debug(1, "%s=%s", param, val);
return clicon_data_set(h, param, val);
}
/*! Delete restconf http parameter
* @param[in] h Clicon handle
* @param[in] name Data name
* @retval 0 OK
* @retval -1 Error
* Currently using clixon runtime data but there is risk for colliding names
*/
int
clixon_restconf_param_del(clicon_handle h,
char *param)
{
return clicon_data_del(h, param);
}
/*! Extract uri-encoded uri-path from fastcgi parameters
* Use REQUEST_URI parameter and strip ?args
* REQUEST_URI have args and is encoded
@ -473,7 +427,7 @@ restconf_uripath(clicon_handle h)
char *path;
char *q;
path = clixon_restconf_param_get(h, "REQUEST_URI");
path = restconf_param_get(h, "REQUEST_URI");
if ((q = index(path, '?')) != NULL)
*q = '\0';
return path;

View file

@ -64,9 +64,6 @@ int get_user_cookie(char *cookiestr, char *attribute, char **val);
int restconf_terminate(clicon_handle h);
int restconf_insert_attributes(cxobj *xdata, cvec *qvec);
int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys);
char *clixon_restconf_param_get(clicon_handle h, char *param);
int clixon_restconf_param_set(clicon_handle h, char *param, char *val);
int clixon_restconf_param_del(clicon_handle h, char *param);
char *restconf_uripath(clicon_handle h);
int restconf_drop_privileges(clicon_handle h, char *user);

View file

@ -54,6 +54,7 @@
#include <signal.h>
#include <syslog.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include <limits.h>
#include <signal.h>
@ -75,6 +76,7 @@
/* restconf */
#include "restconf_lib.h" /* generic shared with plugins */
#include "restconf_handle.h"
#include "restconf_api.h" /* generic not shared with plugins */
#include "restconf_root.h"
@ -202,6 +204,43 @@ query_iterator(evhtp_header_t *hdr,
return 0;
}
/*! Translate http header by capitalizing, prepend w HTTP_ and - -> _
* Example: Host -> HTTP_HOST
*/
static int
convert_fcgi(evhtp_header_t *hdr,
void *arg)
{
int retval = -1;
clicon_handle h = (clicon_handle)arg;
cbuf *cb = NULL;
int i;
char c;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
/* convert key name */
cprintf(cb, "HTTP_");
for (i=0; i<strlen(hdr->key); i++){
c = hdr->key[i] & 0xff;
if (islower(c))
cprintf(cb, "%c", toupper(c));
else if (c == '-')
cprintf(cb, "_");
else
cprintf(cb, "%c", c);
}
if (restconf_param_set(h, cbuf_get(cb), hdr->val) < 0)
goto done;
retval = 0;
done:
if (cb)
cbuf_free(cb);
return retval;
}
/*! Map from evhtp information to "fcgi" type parameters used in clixon code
*
* While all these params come via one call in fcgi, the information must be taken from
@ -230,7 +269,6 @@ evhtp_params_set(clicon_handle h,
htp_method meth;
evhtp_uri_t *uri;
evhtp_path_t *path;
evhtp_header_t *hdr;
if ((uri = req->uri) == NULL){
clicon_err(OE_DAEMON, EFAULT, "No uri");
@ -251,41 +289,17 @@ evhtp_params_set(clicon_handle h,
clicon_err(OE_CFG, errno, "evhtp_kvs_for_each");
goto done;
}
if (clixon_restconf_param_set(h, "REQUEST_METHOD", evhtp_method2str(meth)) < 0)
if (restconf_param_set(h, "REQUEST_METHOD", evhtp_method2str(meth)) < 0)
goto done;
if (clixon_restconf_param_set(h, "REQUEST_URI", path->full) < 0)
if (restconf_param_set(h, "REQUEST_URI", path->full) < 0)
goto done;
if (clixon_restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */
if (restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */
goto done;
/* Translate all http headers by capitalizing, prepend w HTTP_ and - -> _
* Example: Host -> HTTP_HOST
*/
if (evhtp_headers_for_each(req->headers_in, convert_fcgi, h) < 0)
goto done;
if ((hdr = evhtp_headers_find_header(req->headers_in, "Host")) != NULL){
if (clixon_restconf_param_set(h, "HTTP_HOST", hdr->val) < 0)
goto done;
}
if ((hdr = evhtp_headers_find_header(req->headers_in, "Accept")) != NULL){
if (clixon_restconf_param_set(h, "HTTP_ACCEPT", hdr->val) < 0)
goto done;
}
if ((hdr = evhtp_headers_find_header(req->headers_in, "Content-Type")) != NULL){
if (clixon_restconf_param_set(h, "HTTP_CONTENT_TYPE", hdr->val) < 0)
goto done;
}
retval = 0;
done:
return retval;
}
static int
evhtp_params_clear(clicon_handle h)
{
int retval = -1;
char *params[] = {"QUERY_STRING", "REQUEST_METHOD", "REQUEST_URI",
"HTTPS", "HTTP_HOST", "HTTP_ACCEPT", "HTTP_CONTENT_TYPE", NULL};
char *param;
int i=0;
while((param=params[i]) != NULL)
if (clixon_restconf_param_del(h, param) < 0)
goto done;
retval = 0;
done:
return retval;
@ -370,7 +384,7 @@ cx_path_wellknown(evhtp_request_t *req,
goto done;
/* Clear (fcgi) paramaters from this request */
if (evhtp_params_clear(h) < 0)
if (restconf_param_del_all(h) < 0)
goto done;
done:
return; /* void */
@ -404,7 +418,7 @@ cx_path_restconf(evhtp_request_t *req,
goto done;
/* Clear (fcgi) paramaters from this request */
if (evhtp_params_clear(h) < 0)
if (restconf_param_del_all(h) < 0)
goto done;
done:
return; /* void */
@ -473,7 +487,7 @@ main(int argc,
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
/* Create handle */
if ((h = clicon_handle_init()) == NULL)
if ((h = restconf_handle_init()) == NULL)
goto done;
_CLICON_HANDLE = h; /* for termination handling */

View file

@ -78,6 +78,7 @@
/* restconf */
#include "restconf_lib.h" /* generic shared with plugins */
#include "restconf_handle.h"
#include "restconf_api.h" /* generic not shared with plugins */
#include "restconf_err.h"
#include "restconf_root.h" /* generic not shared with plugins */
@ -107,7 +108,7 @@ fcgi_params_set(clicon_handle h,
for (i = 0; envp[i] != NULL; i++){ /* on the form <param>=<value> */
if (clixon_strsplit(envp[i], '=', &param, &val) < 0)
goto done;
if (clixon_restconf_param_set(h, param, val) < 0)
if (restconf_param_set(h, param, val) < 0)
goto done;
if (param){
free(param);
@ -124,35 +125,6 @@ fcgi_params_set(clicon_handle h,
return retval;
}
/*! Clear all FCGI parameters in an environment
* @param[in] h Clixon handle
* @param[in] envp Fastcgi request handle parameter array on the format "<param>=<value>"
* @see https://nginx.org/en/docs/http/ngx_http_core_module.html#var_https
*/
static int
fcgi_params_clear(clicon_handle h,
char **envp)
{
int retval = -1;
int i;
char *param = NULL;
clicon_debug(1, "%s", __FUNCTION__);
for (i = 0; envp[i] != NULL; i++){ /* on the form <param>=<value> */
if (clixon_strsplit(envp[i], '=', &param, NULL) < 0)
goto done;
if (clixon_restconf_param_del(h, param) < 0)
goto done;
if (param){
free(param);
param = NULL;
}
}
retval = 0;
done:
return retval;
}
/* Need global variable to for signal handler XXX */
static clicon_handle _CLICON_HANDLE = NULL;
@ -246,7 +218,7 @@ main(int argc,
clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
/* Create handle */
if ((h = clicon_handle_init()) == NULL)
if ((h = restconf_handle_init()) == NULL)
goto done;
_CLICON_HANDLE = h; /* for termination handling */
@ -504,12 +476,12 @@ main(int argc,
*/
if (fcgi_params_set(h, req->envp) < 0)
goto done;
if ((path = clixon_restconf_param_get(h, "REQUEST_URI")) != NULL){
if ((path = restconf_param_get(h, "REQUEST_URI")) != NULL){
clicon_debug(1, "path: %s", path);
if (strncmp(path, "/" RESTCONF_API, strlen("/" RESTCONF_API)) == 0){
char *query = NULL;
cvec *qvec = NULL;
query = clixon_restconf_param_get(h, "QUERY_STRING");
query = restconf_param_get(h, "QUERY_STRING");
if (query != NULL && strlen(query))
if (str2cvec(query, '&', '=', &qvec) < 0)
goto done;
@ -532,7 +504,7 @@ main(int argc,
}
else
clicon_debug(1, "NULL URI");
if (fcgi_params_clear(h, req->envp) < 0)
if (restconf_param_del_all(h) < 0)
goto done;
if (finish)
FCGX_Finish_r(req);

View file

@ -120,6 +120,7 @@ Mapping netconf error-tag -> status code
#include <clixon/clixon.h>
#include "restconf_lib.h"
#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_methods.h"

View file

@ -58,6 +58,7 @@
#include <clixon/clixon.h>
#include "restconf_lib.h"
#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_methods_get.h"

View file

@ -60,6 +60,7 @@
#include <clixon/clixon.h>
#include "restconf_lib.h"
#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_methods_post.h"
@ -81,9 +82,9 @@ http_location_header(clicon_handle h,
char *request_uri;
cbuf *cb = NULL;
https = clixon_restconf_param_get(h, "HTTPS");
host = clixon_restconf_param_get(h, "HTTP_HOST");
request_uri = clixon_restconf_param_get(h, "REQUEST_URI");
https = restconf_param_get(h, "HTTPS");
host = restconf_param_get(h, "HTTP_HOST");
request_uri = restconf_param_get(h, "REQUEST_URI");
if (xobj != NULL){
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, 0, "cbuf_new");

View file

@ -62,6 +62,7 @@
/* restconf */
#include "restconf_lib.h"
#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_root.h"
@ -89,7 +90,7 @@ api_well_known(clicon_handle h,
errno = EINVAL;
goto done;
}
request_method = clixon_restconf_param_get(h, "REQUEST_METHOD");
request_method = restconf_param_get(h, "REQUEST_METHOD");
if (strcmp(request_method, "GET") != 0){
restconf_method_notallowed(req, "GET");
goto ok;
@ -265,7 +266,7 @@ api_data(clicon_handle h,
char *request_method;
clicon_debug(1, "%s", __FUNCTION__);
request_method = clixon_restconf_param_get(h, "REQUEST_METHOD");
request_method = restconf_param_get(h, "REQUEST_METHOD");
clicon_debug(1, "%s method:%s", __FUNCTION__, request_method);
if (strcmp(request_method, "OPTIONS")==0)
retval = api_data_options(h, req);
@ -355,7 +356,7 @@ api_root_restconf(clicon_handle h,
errno = EINVAL;
goto done;
}
request_method = clixon_restconf_param_get(h, "REQUEST_METHOD");
request_method = restconf_param_get(h, "REQUEST_METHOD");
path = restconf_uripath(h);
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
/* Get media for output (proactive negotiation) RFC7231 by using
@ -363,7 +364,7 @@ api_root_restconf(clicon_handle h,
* operation POST, etc
* If accept is * default is yang-json
*/
if ((media_str = clixon_restconf_param_get(h, "HTTP_ACCEPT")) == NULL){
if ((media_str = restconf_param_get(h, "HTTP_ACCEPT")) == NULL){
// retval = restconf_unsupported_media(r);
// goto done;
}

View file

@ -86,6 +86,7 @@
#include <fcgiapp.h> /* Need to be after clixon_xml.h due to attribute format */
#include "restconf_lib.h"
#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_stream.h"
@ -376,7 +377,7 @@ api_stream(clicon_handle h,
clicon_debug(1, "%s", __FUNCTION__);
path = restconf_uripath(h);
query = clixon_restconf_param_get(h, "QUERY_STRING");
query = restconf_param_get(h, "QUERY_STRING");
pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY");
if ((pvec = clicon_strsep(path, "/", &pn)) == NULL)
goto done;

View file

@ -214,7 +214,7 @@ example_restconf_credentials(clicon_handle h,
if (basic_auth==0)
goto ok;
/* At this point in the code we must use HTTP basic authentication */
if ((auth = clixon_restconf_param_get(h, "HTTP_AUTHORIZATION")) == NULL)
if ((auth = restconf_param_get(h, "HTTP_AUTHORIZATION")) == NULL)
goto fail;
if (strlen(auth) < strlen("Basic "))
goto fail;

View file

@ -2,7 +2,9 @@
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
This file is part of CLIXON.

View file

@ -45,13 +45,13 @@ struct clicon_hash {
typedef struct clicon_hash *clicon_hash_t;
clicon_hash_t *clicon_hash_init (void);
void clicon_hash_free (clicon_hash_t *);
clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key);
void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen);
clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen);
int clicon_hash_del (clicon_hash_t *head, const char *key);
int clicon_hash_dump(clicon_hash_t *head, FILE *f);
int clicon_hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys);
int clicon_hash_free (clicon_hash_t *);
clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key);
void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen);
clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen);
int clicon_hash_del (clicon_hash_t *head, const char *key);
int clicon_hash_dump(clicon_hash_t *head, FILE *f);
int clicon_hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys);
/*
* Macros to iterate over hash contents.

View file

@ -93,13 +93,10 @@ clicon_data_get(clicon_handle h,
{
clicon_hash_t *cdat = clicon_data(h);
if (val == NULL){
clicon_err(OE_CFG, EINVAL, "%s val is NULL", __FUNCTION__);
return -1;
}
if (clicon_hash_lookup(cdat, (char*)name) == NULL)
return -1;
*val = clicon_hash_value(cdat, (char*)name, NULL);
if (val)
*val = clicon_hash_value(cdat, (char*)name, NULL);
return 0;
}
@ -716,4 +713,3 @@ clicon_session_id_set(clicon_handle h,
clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t));
return 0;
}

View file

@ -2,7 +2,9 @@
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
Copyright (C) 2017-2019 Olof Hagsand
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
This file is part of CLIXON.
@ -81,6 +83,7 @@
* XXX: put ch_stream under ch_data
* @see struct cli_handle
* @see struct backend_handle
* @see struct restconf_handle
*/
struct clicon_handle {
int ch_magic; /* magic (HDR) */
@ -157,7 +160,6 @@ clicon_handle_exit(clicon_handle h)
clicon_hash_free(ha);
if ((ha = clicon_data(h)) != NULL)
clicon_hash_free(ha);
if ((ha = clicon_db_elmnt(h)) != NULL)
clicon_hash_free(ha);
stream_delete_all(h, 1);

View file

@ -129,10 +129,11 @@ clicon_hash_init(void)
/*! Free hash table.
*
* @param[in] hash Hash table
* @retval void
* @param[in] hash Hash table
* @retval 0 OK
* @retval -1 Error
*/
void
int
clicon_hash_free(clicon_hash_t *hash)
{
int i;
@ -147,6 +148,7 @@ clicon_hash_free(clicon_hash_t *hash)
}
}
free(hash);
return 0;
}
/*! Find hash key.
@ -189,6 +191,10 @@ clicon_hash_value(clicon_hash_t *hash,
{
clicon_hash_t h;
if (hash == NULL){
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
return NULL;
}
h = clicon_hash_lookup(hash, key);
if (h == NULL)
return NULL; /* OK, key not found */
@ -218,6 +224,10 @@ clicon_hash_add(clicon_hash_t *hash,
clicon_hash_t h;
clicon_hash_t new = NULL;
if (hash == NULL){
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
return NULL;
}
/* Check NULL case */
if ((val == NULL && vlen != 0) ||
(val != NULL && vlen == 0)){
@ -288,6 +298,10 @@ clicon_hash_del(clicon_hash_t *hash,
{
clicon_hash_t h;
if (hash == NULL){
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
return -1;
}
h = clicon_hash_lookup(hash, key);
if (h == NULL)
return -1;
@ -321,6 +335,10 @@ clicon_hash_keys(clicon_hash_t *hash,
char **tmp;
char **keys = NULL;
if (hash == NULL){
clicon_err(OE_UNIX, EINVAL, "hash is NULL");
return -1;
}
*nkeys = 0;
for (bkt = 0; bkt < HASH_SIZE; bkt++) {
h = hash[bkt];