* Updated "evhtp" restconf mode

* No reliance on libevent or libevhtp, but on libssl >= 1.1 directly
    * Moved out event handling to clixon event handling
    * Moved out all ssl calls to clixon
  * New code MUST use libevhtp from https://github.com/clixon/clixon-libevhtp.git
    * This does NOT work: libevhtp from https://github.com/criticalstack/libevhtp.git
This commit is contained in:
Olof hagsand 2021-03-19 09:39:55 +01:00
parent 95a820c862
commit c7e7598e3b
26 changed files with 1506 additions and 944 deletions

View file

@ -32,29 +32,25 @@
***** END LICENSE BLOCK *****
* Concrete functions for libevhtp of the
* Concrete functions for openssl of the
* Virtual clixon restconf API functions.
* @see restconf_api.h for virtual API
*/
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "clixon_config.h" /* generated by config & autoconf */
#endif
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <syslog.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include <signal.h>
#include <dlfcn.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
/* evhtp */
#include <evhtp/evhtp.h>
#include <evhtp/sslutils.h>
/* cligen */
#include <cligen/cligen.h>
@ -65,15 +61,6 @@
#include "restconf_lib.h"
#include "restconf_api.h" /* Virtual api */
/* evhtp_safe_free is a macro that may not be present in a libevhtp release
*/
#ifndef evhtp_safe_free
#define evhtp_safe_free(_var, _freefn) do { \
_freefn((_var)); \
(_var) = NULL; \
} while (0)
#endif
/*! Add HTTP header field name and value to reply, evhtp specific
* @param[in] req Evhtp http request handle
* @param[in] name HTTP header field name
@ -85,7 +72,6 @@ restconf_reply_header(void *req0,
const char *name,
const char *vfmt,
...)
{
evhtp_request_t *req = (evhtp_request_t *)req0;
int retval = -1;
@ -139,8 +125,9 @@ restconf_reply_send(void *req0,
{
evhtp_request_t *req = (evhtp_request_t *)req0;
int retval = -1;
struct evbuffer *eb = NULL;
const char *reason_phrase;
evhtp_connection_t *conn;
struct evbuffer *eb = NULL;
req->status = code;
if ((reason_phrase = restconf_code2reason(code)) == NULL)
@ -149,17 +136,10 @@ restconf_reply_send(void *req0,
if (restconf_reply_header(req, "Status", "%d %s", code, reason_phrase) < 0)
goto done;
#endif
#if 0 /* Optional? */
{
evhtp_connection_t *conn;
if ((conn = evhtp_request_get_connection(req)) == NULL){
clicon_err(OE_DAEMON, EFAULT, "evhtp_request_get_connection");
goto done;
}
htp_sslutil_add_xheaders(req->headers_out, conn->ssl, HTP_SSLUTILS_XHDR_ALL);
if ((conn = evhtp_request_get_connection(req)) == NULL){
clicon_err(OE_DAEMON, EFAULT, "evhtp_request_get_connection");
goto done;
}
#endif
/* If body, add a content-length header */
if (cb != NULL && cbuf_len(cb)){
@ -167,14 +147,13 @@ restconf_reply_send(void *req0,
if (restconf_reply_header(req, "Content-Length", "%d", cbuf_len(cb)) < 0)
goto done;
}
/* create evbuffer* : bufferevent_write_buffer/ drain,
ie send everything , except body */
evhtp_send_reply_start(req, req->status);
evhtp_send_reply(req, req->status);
/* Write a body if cbuf is nonzero */
if (cb != NULL && cbuf_len(cb)){
/* Suboptimal, copy from cbuf to evbuffer */
if ((eb = evbuffer_new()) == NULL){
clicon_err(OE_CFG, errno, "evbuffer_new");
clicon_err(OE_RESTCONF, errno, "evbuffer_new");
goto done;
}
if (evbuffer_add(eb, cbuf_get(cb), cbuf_len(cb)) < 0){
@ -217,3 +196,4 @@ restconf_get_indata(void *req0)
return cb;
}