From bb3593bb9961f0f08043e2ed105d7b04571c2ad1 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 4 Jun 2020 09:07:22 +0200 Subject: [PATCH] evhtp next step --- apps/restconf/restconf_evhtp_main.c | 130 ++++++++++++++++++++-------- apps/restconf/restconf_fcgi_lib.c | 12 +-- 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/apps/restconf/restconf_evhtp_main.c b/apps/restconf/restconf_evhtp_main.c index d2a1be3c..ec499578 100644 --- a/apps/restconf/restconf_evhtp_main.c +++ b/apps/restconf/restconf_evhtp_main.c @@ -40,6 +40,11 @@ #ifdef HAVE_CONFIG_H #include "clixon_config.h" /* generated by config & autoconf */ #endif +/* compilation withotu threading support + * XXX: could be disabled already in configure? + */ +#define EVHTP_DISABLE_EVTHR +#define EVHTP_DISABLE_REGEX #include #include @@ -117,13 +122,12 @@ restconf_sig_child(int arg) } } -/*! Generic callback called if no other callbacks are matched - */ static void -cx_generic_callback(evhtp_request_t *req, - void *arg) +cx_gencb(evhtp_request_t *req, + void *arg) { - evhtp_connection_t * conn; + evhtp_connection_t *conn; + // clicon_handle h = arg; fprintf(stderr, "%s\n", __FUNCTION__); if (req == NULL){ @@ -131,14 +135,78 @@ cx_generic_callback(evhtp_request_t *req, return; } if ((conn = evhtp_request_get_connection(req)) == NULL) - return; - + goto done; htp_sslutil_add_xheaders( req->headers_out, conn->ssl, 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 @@ -185,11 +253,8 @@ main(int argc, char *dir; int logdst = CLICON_LOG_SYSLOG; yang_stmt *yspec = NULL; - int finish = 0; - int start = 1; char *str; clixon_plugin *cp = NULL; - uint32_t id = 0; cvec *nsctx_global = NULL; /* Global namespace context */ size_t cligen_buflen; size_t cligen_bufthreshold; @@ -452,9 +517,21 @@ main(int argc, clicon_err(OE_UNIX, errno, "evhtp_new"); goto done; } - /* * Generic callback called if no other callbacks are matched - */ - evhtp_set_gencb(htp, cx_generic_callback, NULL); + /* Generic callback called if no other callbacks are matched */ + evhtp_set_gencb(htp, cx_gencb, h); + + /* 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 */ if (evhtp_bind_socket(htp, "127.0.0.1", port, 128) < 0){ clicon_err(OE_UNIX, errno, "evhtp_bind_socket"); @@ -463,29 +540,10 @@ main(int argc, event_base_loop(evbase, 0); - if (0) - while (finish == 0) { - finish = 1; /* If zero, dont finish request, initiate new */ - clicon_debug(1, "------------"); + evhtp_unbind_socket(htp); - if (start == 0){ - /* Send hello request to backend to get session-id back - * 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. - */ + // evhtp_safe_free(htp, evhtp_free); + // evhtp_safe_free(evbase, event_base_free); retval = 0; done: diff --git a/apps/restconf/restconf_fcgi_lib.c b/apps/restconf/restconf_fcgi_lib.c index 63815d7f..b817738d 100644 --- a/apps/restconf/restconf_fcgi_lib.c +++ b/apps/restconf/restconf_fcgi_lib.c @@ -93,7 +93,7 @@ restconf_badrequest(FCGX_Request *r) { char *path; - path = FCGX_GetParam("DOCUMENT_URI", r->envp); + path = FCGX_GetParam("REQUEST_URI", r->envp); FCGX_SetExitStatus(400, r->out); 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"); @@ -111,7 +111,7 @@ restconf_unauthorized(FCGX_Request *r) { char *path; - path = FCGX_GetParam("DOCUMENT_URI", r->envp); + path = FCGX_GetParam("REQUEST_URI", r->envp); FCGX_SetExitStatus(401, r->out); FCGX_FPrintF(r->out, "Status: 401 Unauthorized\r\n"); /* 401 unauthorized */ FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); @@ -128,7 +128,7 @@ restconf_forbidden(FCGX_Request *r) { char *path; - path = FCGX_GetParam("DOCUMENT_URI", r->envp); + path = FCGX_GetParam("REQUEST_URI", r->envp); FCGX_SetExitStatus(403, r->out); FCGX_FPrintF(r->out, "Status: 403 Forbidden\r\n"); /* 403 forbidden */ FCGX_FPrintF(r->out, "Content-Type: text/html\r\n\r\n"); @@ -145,7 +145,7 @@ restconf_notfound(FCGX_Request *r) { char *path; - path = FCGX_GetParam("DOCUMENT_URI", r->envp); + path = FCGX_GetParam("REQUEST_URI", r->envp); FCGX_SetExitStatus(404, r->out); 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"); @@ -164,7 +164,7 @@ restconf_notacceptable(FCGX_Request *r) { char *path; - path = FCGX_GetParam("DOCUMENT_URI", r->envp); + path = FCGX_GetParam("REQUEST_URI", r->envp); FCGX_SetExitStatus(406, r->out); 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; 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, "Content-Type: text/html\r\n\r\n"); FCGX_FPrintF(r->out, "

Internal server error when accessing %s

\n", path);