evhtp next step

This commit is contained in:
Olof hagsand 2020-06-04 09:07:22 +02:00
parent e00dffadc5
commit bb3593bb99
2 changed files with 100 additions and 42 deletions

View file

@ -40,6 +40,11 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "clixon_config.h" /* generated by config & autoconf */ #include "clixon_config.h" /* generated by config & autoconf */
#endif #endif
/* compilation withotu threading support
* XXX: could be disabled already in configure?
*/
#define EVHTP_DISABLE_EVTHR
#define EVHTP_DISABLE_REGEX
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -117,13 +122,12 @@ restconf_sig_child(int arg)
} }
} }
/*! Generic callback called if no other callbacks are matched
*/
static void static void
cx_generic_callback(evhtp_request_t *req, cx_gencb(evhtp_request_t *req,
void *arg) void *arg)
{ {
evhtp_connection_t *conn; evhtp_connection_t *conn;
// clicon_handle h = arg;
fprintf(stderr, "%s\n", __FUNCTION__); fprintf(stderr, "%s\n", __FUNCTION__);
if (req == NULL){ if (req == NULL){
@ -131,14 +135,78 @@ cx_generic_callback(evhtp_request_t *req,
return; return;
} }
if ((conn = evhtp_request_get_connection(req)) == NULL) if ((conn = evhtp_request_get_connection(req)) == NULL)
return; goto done;
htp_sslutil_add_xheaders( htp_sslutil_add_xheaders(
req->headers_out, req->headers_out,
conn->ssl, conn->ssl,
HTP_SSLUTILS_XHDR_ALL); HTP_SSLUTILS_XHDR_ALL);
evhtp_send_reply(req, EVHTP_RES_NOTFOUND);
done:
return; /* void */
}
return evhtp_send_reply(req, EVHTP_RES_OK); static evhtp_res
cx_pre_accept(evhtp_connection_t *conn,
void *arg)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return EVHTP_RES_OK;
}
static evhtp_res
cx_post_accept(evhtp_connection_t *conn,
void *arg)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return EVHTP_RES_OK;
}
static int
print_header_(evhtp_header_t * header, void * arg) {
fprintf(stderr, "%s: %s\n", header->key, header->val);
return 0;
}
/*! Generic callback called if no other callbacks are matched
*/
static void
cx_path_restconf(evhtp_request_t *req,
void *arg)
{
evhtp_connection_t *conn;
// clicon_handle h = arg;
struct evbuffer *b = NULL;
htp_method meth;
fprintf(stderr, "%s\n", __FUNCTION__);
if (req == NULL){
errno = EINVAL;
goto done;
}
if ((conn = evhtp_request_get_connection(req)) == NULL)
goto done;
meth = evhtp_request_get_method(req);
fprintf(stderr, "%s method:%d\n", __FUNCTION__, meth);
evhtp_headers_for_each(req->headers_in, print_header_, NULL);
if ((b = evbuffer_new()) == NULL){
goto done;
}
htp_sslutil_add_xheaders(
req->headers_out,
conn->ssl,
HTP_SSLUTILS_XHDR_ALL);
evhtp_send_reply_start(req, EVHTP_RES_OK);
evbuffer_add(b, "hej\n", strlen("hej\n\n"));
evhtp_send_reply_body(req, b);
evhtp_send_reply_end(req);
// evhtp_headers_add_header(request->headers_out, evhtp_header_new("Host", "localhost", 0, 0)); evhtp_headers_add_headers(request->headers_out, headers);
done:
return; /* void */
} }
/*! Usage help routine /*! Usage help routine
@ -185,11 +253,8 @@ main(int argc,
char *dir; char *dir;
int logdst = CLICON_LOG_SYSLOG; int logdst = CLICON_LOG_SYSLOG;
yang_stmt *yspec = NULL; yang_stmt *yspec = NULL;
int finish = 0;
int start = 1;
char *str; char *str;
clixon_plugin *cp = NULL; clixon_plugin *cp = NULL;
uint32_t id = 0;
cvec *nsctx_global = NULL; /* Global namespace context */ cvec *nsctx_global = NULL; /* Global namespace context */
size_t cligen_buflen; size_t cligen_buflen;
size_t cligen_bufthreshold; size_t cligen_bufthreshold;
@ -452,9 +517,21 @@ main(int argc,
clicon_err(OE_UNIX, errno, "evhtp_new"); clicon_err(OE_UNIX, errno, "evhtp_new");
goto done; goto done;
} }
/* * Generic callback called if no other callbacks are matched /* Generic callback called if no other callbacks are matched */
*/ evhtp_set_gencb(htp, cx_gencb, h);
evhtp_set_gencb(htp, cx_generic_callback, NULL);
/* Callback before the connection is accepted. */
evhtp_set_pre_accept_cb(htp, cx_pre_accept, h);
/* Callback right after a connection is accepted. */
evhtp_set_post_accept_cb(htp, cx_post_accept, h);
/* Callback to be executed on a specific path */
if (evhtp_set_cb(htp, "/" RESTCONF_API, cx_path_restconf, h) == NULL){
clicon_err(OE_EVENTS, errno, "evhtp_set_cb");
goto done;
}
/* bind to a socket, optionally with specific protocol support formatting */ /* bind to a socket, optionally with specific protocol support formatting */
if (evhtp_bind_socket(htp, "127.0.0.1", port, 128) < 0){ if (evhtp_bind_socket(htp, "127.0.0.1", port, 128) < 0){
clicon_err(OE_UNIX, errno, "evhtp_bind_socket"); clicon_err(OE_UNIX, errno, "evhtp_bind_socket");
@ -463,29 +540,10 @@ main(int argc,
event_base_loop(evbase, 0); event_base_loop(evbase, 0);
if (0) evhtp_unbind_socket(htp);
while (finish == 0) {
finish = 1; /* If zero, dont finish request, initiate new */
clicon_debug(1, "------------");
if (start == 0){ // evhtp_safe_free(htp, evhtp_free);
/* Send hello request to backend to get session-id back // evhtp_safe_free(evbase, event_base_free);
* This is done once at the beginning of the session and then this is
* used by the client, even though new TCP sessions are created for
* each message sent to the backend.
*/
if (clicon_hello_req(h, &id) < 0)
goto done;
clicon_session_id_set(h, id);
start++;
}
break; /* XXX */
}
/* Use options to select the port and document root among other things.
* Use callbacks to add your own hooks.
*/
retval = 0; retval = 0;
done: done:

View file

@ -93,7 +93,7 @@ restconf_badrequest(FCGX_Request *r)
{ {
char *path; char *path;
path = FCGX_GetParam("DOCUMENT_URI", r->envp); path = FCGX_GetParam("REQUEST_URI", r->envp);
FCGX_SetExitStatus(400, r->out); FCGX_SetExitStatus(400, r->out);
FCGX_FPrintF(r->out, "Status: 400 Bad Request\r\n"); /* 400 bad request */ FCGX_FPrintF(r->out, "Status: 400 Bad Request\r\n"); /* 400 bad request */
FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n");
@ -111,7 +111,7 @@ restconf_unauthorized(FCGX_Request *r)
{ {
char *path; char *path;
path = FCGX_GetParam("DOCUMENT_URI", r->envp); path = FCGX_GetParam("REQUEST_URI", r->envp);
FCGX_SetExitStatus(401, r->out); FCGX_SetExitStatus(401, r->out);
FCGX_FPrintF(r->out, "Status: 401 Unauthorized\r\n"); /* 401 unauthorized */ FCGX_FPrintF(r->out, "Status: 401 Unauthorized\r\n"); /* 401 unauthorized */
FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n");
@ -128,7 +128,7 @@ restconf_forbidden(FCGX_Request *r)
{ {
char *path; char *path;
path = FCGX_GetParam("DOCUMENT_URI", r->envp); path = FCGX_GetParam("REQUEST_URI", r->envp);
FCGX_SetExitStatus(403, r->out); FCGX_SetExitStatus(403, r->out);
FCGX_FPrintF(r->out, "Status: 403 Forbidden\r\n"); /* 403 forbidden */ FCGX_FPrintF(r->out, "Status: 403 Forbidden\r\n"); /* 403 forbidden */
FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n");
@ -145,7 +145,7 @@ restconf_notfound(FCGX_Request *r)
{ {
char *path; char *path;
path = FCGX_GetParam("DOCUMENT_URI", r->envp); path = FCGX_GetParam("REQUEST_URI", r->envp);
FCGX_SetExitStatus(404, r->out); FCGX_SetExitStatus(404, r->out);
FCGX_FPrintF(r->out, "Status: 404 Not Found\r\n"); /* 404 not found */ FCGX_FPrintF(r->out, "Status: 404 Not Found\r\n"); /* 404 not found */
FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n");
@ -164,7 +164,7 @@ restconf_notacceptable(FCGX_Request *r)
{ {
char *path; char *path;
path = FCGX_GetParam("DOCUMENT_URI", r->envp); path = FCGX_GetParam("REQUEST_URI", r->envp);
FCGX_SetExitStatus(406, r->out); FCGX_SetExitStatus(406, r->out);
FCGX_FPrintF(r->out, "Status: 406 Not Acceptable\r\n"); /* 406 not acceptible */ FCGX_FPrintF(r->out, "Status: 406 Not Acceptable\r\n"); /* 406 not acceptible */
@ -211,7 +211,7 @@ restconf_internal_server_error(FCGX_Request *r)
char *path; char *path;
clicon_debug(1, "%s", __FUNCTION__); clicon_debug(1, "%s", __FUNCTION__);
path = FCGX_GetParam("DOCUMENT_URI", r->envp); path = FCGX_GetParam("REQUEST_URI", r->envp);
FCGX_FPrintF(r->out, "Status: 500 Internal Server Error\r\n"); /* 500 internal server error */ FCGX_FPrintF(r->out, "Status: 500 Internal Server Error\r\n"); /* 500 internal server error */
FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n");
FCGX_FPrintF(r->out, "<h1>Internal server error when accessing %s</h1>\n", path); FCGX_FPrintF(r->out, "<h1>Internal server error when accessing %s</h1>\n", path);