libhttp mods

This commit is contained in:
Olof hagsand 2020-06-02 10:13:15 +02:00
parent a5ef243225
commit 290558e7fa

View file

@ -76,7 +76,7 @@
#endif #endif
/* Command line options to be passed to getopt(3) */ /* Command line options to be passed to getopt(3) */
#define RESTCONF_OPTS "hD:f:l:p:d:y:a:u:o:" #define RESTCONF_OPTS "hD:f:l:p:d:y:a:u:o:P:"
/* Need global variable to for signal handler XXX */ /* Need global variable to for signal handler XXX */
static clicon_handle _CLICON_HANDLE = NULL; static clicon_handle _CLICON_HANDLE = NULL;
@ -137,47 +137,73 @@ usage(clicon_handle h,
"\t-y <file>\t Load yang spec file (override yang main module)\n" "\t-y <file>\t Load yang spec file (override yang main module)\n"
"\t-a UNIX|IPv4|IPv6 Internal backend socket family\n" "\t-a UNIX|IPv4|IPv6 Internal backend socket family\n"
"\t-u <path|addr>\t Internal socket domain path or IP addr (see -a)\n" "\t-u <path|addr>\t Internal socket domain path or IP addr (see -a)\n"
"\t-o \"<option>=<value>\" Give configuration option overriding config file (see clixon-config.yang)\n", "\t-o \"<option>=<value>\" Give configuration option overriding config file (see clixon-config.yang)\n"
"\t-P <port>\t HTTP port (default 80)\n"
,
argv0, argv0,
clicon_restconf_dir(h) clicon_restconf_dir(h)
); );
exit(0); exit(0);
} }
#if 0 /*! Create and append a libhttp option.
/*! This function will be called by the server on every new request.
*/ */
static int static int
begin_request_handler(struct httplib_connection *conn) lh_opts_append(struct lh_opt_t **options,
int *len,
char *name,
char *value)
{ {
const struct httplib_request_info *request_info = httplib_get_request_info(conn); int retval = -1;
char content[100]; struct lh_opt_t *opt = NULL;
/* Prepare the message we're going to send */ (*len)++;
int content_length = snprintf(content, sizeof(content), if ((*options = realloc(*options, *len*sizeof(*opt))) == NULL){
"Hello from clixon-civerweb! Remote port: %d", clicon_err(OE_FATAL, errno, "realloc");
request_info->remote_port); goto done;
}
/* Send HTTP reply to the client */ opt = &(*options)[*len-1];
httplib_printf(conn, memset(opt, 0, sizeof(*opt));
"HTTP/1.1 200 OK\r\n" if (name && (opt->name = strdup(name)) == NULL){
"Content-Type: text/plain\r\n" clicon_err(OE_FATAL, errno, "strdup");
"Content-Length: %d\r\n" // Always set Content-Length goto done;
"\r\n" }
"%s", if (value && (opt->value = strdup(value)) == NULL){
content_length, content); clicon_err(OE_FATAL, errno, "strdup");
goto done;
/* Returning non-zero tells the server that our function has replied to }
* the client, and should not send client any more data. retval = 0;
*/ done:
return 1; return retval;
} }
#endif
LIBHTTP_API struct lh_ctx_t * httplib_start( const struct lh_clb_t *callbacks, void *user_data, const struct lh_opt_t *options );
/*! Free a libhttp options list
*/
static int static int
my_begin_request(struct lh_ctx_t *ctx, lh_opts_free(struct lh_opt_t *options,
int len)
{
struct lh_opt_t *opt = NULL;
int i;
for (i=0; i<len; i++){
opt = &options[i];
if (opt->name)
free((char*)opt->name);
if (opt->value)
free((char*)opt->value);
}
if (options)
free(options);
return 0;
}
/*! Libhttp icoming request
*/
static int
cx_begin_request(struct lh_ctx_t *ctx,
struct lh_con_t *conn) struct lh_con_t *conn)
{ {
const struct lh_rqi_t *request_info = httplib_get_request_info(conn); const struct lh_rqi_t *request_info = httplib_get_request_info(conn);
@ -185,7 +211,7 @@ my_begin_request(struct lh_ctx_t *ctx,
// Prepare the message we're going to send // Prepare the message we're going to send
int content_length = snprintf(content, sizeof(content), int content_length = snprintf(content, sizeof(content),
"Hello from Clixon! Remote port: %d", "Hello from Clixon FOO! Remote port: %d",
request_info->remote_port); request_info->remote_port);
fprintf(stderr, "%s\n", __FUNCTION__); fprintf(stderr, "%s\n", __FUNCTION__);
httplib_printf(ctx, conn, httplib_printf(ctx, conn,
@ -198,6 +224,94 @@ my_begin_request(struct lh_ctx_t *ctx,
return 0; return 0;
} }
static void
cx_end_request(struct lh_ctx_t *ctx,
const struct lh_con_t *conn,
int reply_status_code )
{
fprintf(stderr, "%s\n", __FUNCTION__);
}
static int
cx_log_message(struct lh_ctx_t *ctx,
const struct lh_con_t *conn,
const char *message)
{
fprintf(stderr, "ERROR: %s\n", message);
return 0;
}
static int
cx_log_access(struct lh_ctx_t *ctx,
const struct lh_con_t *conn,
const char *message)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return 0;
}
static int
cx_init_ssl(struct lh_ctx_t *ctx,
void *ssl_context,
void *user_data)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return 0;
}
static void
cx_connection_close(struct lh_ctx_t *ctx,
const struct lh_con_t *conn)
{
fprintf(stderr, "%s\n", __FUNCTION__);
}
static const char *
cx_open_file(struct lh_ctx_t *ctx,
const struct lh_con_t *conn,
const char *path,
size_t *data_len)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return NULL;
}
static void
cx_init_lua(struct lh_ctx_t *ctx,
const struct lh_con_t *conn,
void *lua_context)
{
fprintf(stderr, "%s\n", __FUNCTION__);
}
static int
cx_http_error(struct lh_ctx_t *ctx,
struct lh_con_t *conn,
int status)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return 0;
}
static void
cx_init_context(struct lh_ctx_t *ctx)
{
fprintf(stderr, "%s\n", __FUNCTION__);
}
static void
cx_init_thread(struct lh_ctx_t *ctx,
int thread_type)
{
fprintf(stderr, "%s\n", __FUNCTION__);
}
static void
cx_exit_context(struct lh_ctx_t *ctx)
{
fprintf(stderr, "%s\n", __FUNCTION__);
}
/*! Main routine for libhttp restconf /*! Main routine for libhttp restconf
*/ */
int int
@ -205,11 +319,8 @@ main(int argc,
char **argv) char **argv)
{ {
int retval = -1; int retval = -1;
// int sock;
char *argv0 = argv[0]; char *argv0 = argv[0];
int c; int c;
// char *sockpath;
// char *path;
clicon_handle h; clicon_handle h;
char *dir; char *dir;
int logdst = CLICON_LOG_SYSLOG; int logdst = CLICON_LOG_SYSLOG;
@ -222,14 +333,17 @@ main(int argc,
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;
char *portstr = "80";
#ifdef _LIBHTTP_NYI #ifdef _LIBHTTP_NYI
char *stream_path; char *stream_path;
#endif #endif
struct lh_ctx_t *ctx = NULL; struct lh_ctx_t *ctx = NULL;
/* See XX_httplib_free_config_options, XX_httplib_init_options */ /* See XX_httplib_free_config_options, XX_httplib_init_options */
const struct lh_opt_t options[] = {{"listening_ports", "8080"}, {NULL, NULL}}; struct lh_opt_t *lh_opts = NULL;
const struct lh_clb_t callbacks = {my_begin_request,NULL}; int lh_opts_len = 0;
const struct lh_clb_t lh_callbacks = {cx_begin_request, cx_end_request, cx_log_message, cx_log_access, cx_init_ssl,
cx_connection_close, cx_open_file, cx_init_lua, cx_http_error,
cx_init_context, cx_init_thread, cx_exit_context};
/* In the startup, logs to stderr & debug flag set later */ /* In the startup, logs to stderr & debug flag set later */
clicon_log_init(__PROGRAM__, LOG_INFO, logdst); clicon_log_init(__PROGRAM__, LOG_INFO, logdst);
@ -263,6 +377,7 @@ main(int argc,
goto done; goto done;
break; break;
} /* switch getopt */ } /* switch getopt */
/* /*
* Logs, error and debug to stderr or syslog, set debug level * Logs, error and debug to stderr or syslog, set debug level
*/ */
@ -328,6 +443,11 @@ main(int argc,
goto done; goto done;
break; break;
} }
case 'P': /* http port */
if (!strlen(optarg))
usage(h, argv[0]);
portstr=optarg;
break;
default: default:
usage(h, argv[0]); usage(h, argv[0]);
break; break;
@ -335,6 +455,15 @@ main(int argc,
argc -= optind; argc -= optind;
argv += optind; argv += optind;
/* See here for libhttp options XX_httplib_process_options
* - https://github.com/lammertb/libhttp/blob/master/doc/UserManual.md
* some options seem documented here: https://github.com/civetweb/civetweb/blob/master/docs/UserManual.md
*/
if (lh_opts_append(&lh_opts, &lh_opts_len, "listening_ports", portstr) < 0)
goto done;
if (lh_opts_append(&lh_opts, &lh_opts_len, "num_threads", "5") < 0)
goto done;
/* Access the remaining argv/argc options (after --) w clicon-argv_get() */ /* Access the remaining argv/argc options (after --) w clicon-argv_get() */
clicon_argv_set(h, argv0, argc, argv); clicon_argv_set(h, argv0, argc, argv);
@ -429,10 +558,14 @@ main(int argc,
if (clicon_options_main(h) < 0) if (clicon_options_main(h) < 0)
goto done; goto done;
/* Terminate options list with NULL (must be the last) */
if (lh_opts_append(&lh_opts, &lh_opts_len, NULL, NULL) < 0)
goto done;
/* Start the web server. */ /* Start the web server. */
if ((ctx = httplib_start(&callbacks, /* callbacks */ if ((ctx = httplib_start(&lh_callbacks, /* callbacks */
NULL, /* user-data */ h, /* userdata - clixon handle*/
options /* options */ lh_opts /* options */
)) == NULL) )) == NULL)
goto done; goto done;
@ -466,6 +599,7 @@ main(int argc,
#ifdef _LIBHTTP_NYI #ifdef _LIBHTTP_NYI
stream_child_freeall(h); stream_child_freeall(h);
#endif #endif
lh_opts_free(lh_opts, lh_opts_len);
restconf_terminate(h); restconf_terminate(h);
return retval; return retval;
} }