Added restconf handle specialization to implement restconf parameters
This commit is contained in:
parent
1597bd303c
commit
73bbcded87
22 changed files with 351 additions and 162 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
174
apps/restconf/restconf_handle.c
Normal file
174
apps/restconf/restconf_handle.c
Normal 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;
|
||||
}
|
||||
51
apps/restconf/restconf_handle.h
Normal file
51
apps/restconf/restconf_handle.h
Normal 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_ */
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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], '=', ¶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 "<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], '=', ¶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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue