diff --git a/apps/backend/backend_handle.h b/apps/backend/backend_handle.h
index f2acea6f..42c6c04d 100644
--- a/apps/backend/backend_handle.h
+++ b/apps/backend/backend_handle.h
@@ -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.
diff --git a/apps/backend/clixon_backend_handle.c b/apps/backend/clixon_backend_handle.c
index 6f5ca55e..19a936ed 100644
--- a/apps/backend/clixon_backend_handle.c
+++ b/apps/backend/clixon_backend_handle.c
@@ -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.
diff --git a/apps/restconf/Makefile.in b/apps/restconf/Makefile.in
index bd73ae91..3388b5a9 100644
--- a/apps/restconf/Makefile.in
+++ b/apps/restconf/Makefile.in
@@ -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)
diff --git a/apps/restconf/clixon_restconf.h b/apps/restconf/clixon_restconf.h
index 8cf332d0..62cdf758 100644
--- a/apps/restconf/clixon_restconf.h
+++ b/apps/restconf/clixon_restconf.h
@@ -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_ */
diff --git a/apps/restconf/restconf_err.c b/apps/restconf/restconf_err.c
index ff8c034c..6e38891a 100644
--- a/apps/restconf/restconf_err.c
+++ b/apps/restconf/restconf_err.c
@@ -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, "access-denied\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\n", path);
diff --git a/apps/restconf/restconf_handle.c b/apps/restconf/restconf_handle.c
new file mode 100644
index 00000000..53348b67
--- /dev/null
+++ b/apps/restconf/restconf_handle.c
@@ -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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* cligen */
+#include
+
+/* clicon */
+#include
+
+#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;
+}
diff --git a/apps/restconf/restconf_handle.h b/apps/restconf/restconf_handle.h
new file mode 100644
index 00000000..464dd50d
--- /dev/null
+++ b/apps/restconf/restconf_handle.h
@@ -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_ */
diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c
index d325d11b..ea8b2cfe 100644
--- a/apps/restconf/restconf_lib.c
+++ b/apps/restconf/restconf_lib.c
@@ -60,6 +60,7 @@
#include
#include "restconf_api.h"
+#include "restconf_handle.h"
#include "restconf_lib.h"
/* See RFC 8040 Section 7: Mapping from NETCONF 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;
diff --git a/apps/restconf/restconf_lib.h b/apps/restconf/restconf_lib.h
index f0a6c254..bdb7c021 100644
--- a/apps/restconf/restconf_lib.h
+++ b/apps/restconf/restconf_lib.h
@@ -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);
diff --git a/apps/restconf/restconf_main_evhtp.c b/apps/restconf/restconf_main_evhtp.c
index dcc690ce..b42f39eb 100644
--- a/apps/restconf/restconf_main_evhtp.c
+++ b/apps/restconf/restconf_main_evhtp.c
@@ -54,6 +54,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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; ikey); 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 */
diff --git a/apps/restconf/restconf_main_fcgi.c b/apps/restconf/restconf_main_fcgi.c
index ebd0b56f..783653b3 100644
--- a/apps/restconf/restconf_main_fcgi.c
+++ b/apps/restconf/restconf_main_fcgi.c
@@ -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 = */
if (clixon_strsplit(envp[i], '=', ¶m, &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 "="
- * @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 = */
- if (clixon_strsplit(envp[i], '=', ¶m, 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);
diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c
index 112ca34f..4a299a91 100644
--- a/apps/restconf/restconf_methods.c
+++ b/apps/restconf/restconf_methods.c
@@ -120,6 +120,7 @@ Mapping netconf error-tag -> status code
#include
#include "restconf_lib.h"
+#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_methods.h"
diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c
index 8794d581..dbf58e1f 100644
--- a/apps/restconf/restconf_methods_get.c
+++ b/apps/restconf/restconf_methods_get.c
@@ -58,6 +58,7 @@
#include
#include "restconf_lib.h"
+#include "restconf_handle.h"
#include "restconf_api.h"
#include "restconf_err.h"
#include "restconf_methods_get.h"
diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c
index 60580941..e85dad9f 100644
--- a/apps/restconf/restconf_methods_post.c
+++ b/apps/restconf/restconf_methods_post.c
@@ -60,6 +60,7 @@
#include
#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");
diff --git a/apps/restconf/restconf_root.c b/apps/restconf/restconf_root.c
index d62f4797..8872e642 100644
--- a/apps/restconf/restconf_root.c
+++ b/apps/restconf/restconf_root.c
@@ -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;
}
diff --git a/apps/restconf/restconf_stream.c b/apps/restconf/restconf_stream.c
index c6bc72ed..771c072e 100644
--- a/apps/restconf/restconf_stream.c
+++ b/apps/restconf/restconf_stream.c
@@ -86,6 +86,7 @@
#include /* 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;
diff --git a/example/main/example_restconf.c b/example/main/example_restconf.c
index b5ca32b0..84eb48fa 100644
--- a/example/main/example_restconf.c
+++ b/example/main/example_restconf.c
@@ -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;
diff --git a/lib/clixon/clixon_handle.h b/lib/clixon/clixon_handle.h
index 20f2dbcd..026159c1 100644
--- a/lib/clixon/clixon_handle.h
+++ b/lib/clixon/clixon_handle.h
@@ -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.
diff --git a/lib/clixon/clixon_hash.h b/lib/clixon/clixon_hash.h
index 6fcca465..f4cd0ddd 100644
--- a/lib/clixon/clixon_hash.h
+++ b/lib/clixon/clixon_hash.h
@@ -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.
diff --git a/lib/src/clixon_data.c b/lib/src/clixon_data.c
index 4c24cab6..fe6aaaaf 100644
--- a/lib/src/clixon_data.c
+++ b/lib/src/clixon_data.c
@@ -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;
}
-
diff --git a/lib/src/clixon_handle.c b/lib/src/clixon_handle.c
index b4b5a303..f0ac5c65 100644
--- a/lib/src/clixon_handle.c
+++ b/lib/src/clixon_handle.c
@@ -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);
diff --git a/lib/src/clixon_hash.c b/lib/src/clixon_hash.c
index f757743b..21b7b2d8 100644
--- a/lib/src/clixon_hash.c
+++ b/lib/src/clixon_hash.c
@@ -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];