From 17099e86dec60d1eff1c49f081b0a13f1f4e8bd2 Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Wed, 20 Mar 2019 23:17:41 +0300 Subject: [PATCH] --static stub --- src/http.c | 74 +++++++++++++++++++++++++++++++++++++++++++++--------- src/http.h | 1 + src/main.c | 16 +++++++----- 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/src/http.c b/src/http.c index ee7f403..6b34704 100644 --- a/src/http.c +++ b/src/http.c @@ -61,7 +61,8 @@ static bool _http_get_param_true(struct evkeyvalq *params, const char *key); static char *_http_get_param_uri(struct evkeyvalq *params, const char *key); static int _http_preprocess_request(struct evhttp_request *request, struct http_server_t *server); -static void _http_callback_root(struct evhttp_request *request, void *arg); +static void _http_callback_root(struct evhttp_request *request, void *v_server); +static void _http_callback_static(struct evhttp_request *request, void *v_server); static void _http_callback_state(struct evhttp_request *request, void *v_server); static void _http_callback_snapshot(struct evhttp_request *request, void *v_server); @@ -91,6 +92,9 @@ struct http_server_t *http_server_init(struct stream_t *stream) { A_CALLOC(server, 1); server->host = "127.0.0.1"; server->port = 8080; + server->user = ""; + server->passwd = ""; + server->static_path = ""; server->timeout = 10; server->run = run; @@ -100,12 +104,6 @@ struct http_server_t *http_server_init(struct stream_t *stream) { assert((run->base = event_base_new())); assert((run->http = evhttp_new(run->base))); evhttp_set_allowed_methods(run->http, EVHTTP_REQ_GET|EVHTTP_REQ_HEAD); - - assert(!evhttp_set_cb(run->http, "/", _http_callback_root, (void *)server)); - assert(!evhttp_set_cb(run->http, "/state", _http_callback_state, (void *)server)); - assert(!evhttp_set_cb(run->http, "/snapshot", _http_callback_snapshot, (void *)server)); - assert(!evhttp_set_cb(run->http, "/stream", _http_callback_stream, (void *)server)); - return server; } @@ -141,6 +139,17 @@ void http_server_destroy(struct http_server_t *server) { } int http_server_listen(struct http_server_t *server) { + { + if (server->static_path[0] != '\0') { + evhttp_set_gencb(server->run->http, _http_callback_static, (void *)server); + } else { + assert(!evhttp_set_cb(server->run->http, "/", _http_callback_root, (void *)server)); + } + assert(!evhttp_set_cb(server->run->http, "/state", _http_callback_state, (void *)server)); + assert(!evhttp_set_cb(server->run->http, "/snapshot", _http_callback_snapshot, (void *)server)); + assert(!evhttp_set_cb(server->run->http, "/stream", _http_callback_stream, (void *)server)); + } + { struct timeval refresh_interval; @@ -150,6 +159,7 @@ int http_server_listen(struct http_server_t *server) { } else { refresh_interval.tv_usec = 16000; // ~60fps } + assert((server->run->refresh = event_new(server->run->base, -1, EV_PERSIST, _http_exposed_refresh, server))); assert(!event_add(server->run->refresh, &refresh_interval)); } @@ -162,13 +172,12 @@ int http_server_listen(struct http_server_t *server) { evhttp_set_timeout(server->run->http, server->timeout); - if (server->user != NULL && strlen(server->user) > 0) { - char *passwd = (server->passwd != NULL ? server->passwd : ""); + if (server->user[0] != '\0') { char *raw_token; char *encoded_token; - A_CALLOC(raw_token, strlen(server->user) + strlen(passwd) + 2); - sprintf(raw_token, "%s:%s", server->user, passwd); + A_CALLOC(raw_token, strlen(server->user) + strlen(server->passwd) + 2); + sprintf(raw_token, "%s:%s", server->user, server->passwd); encoded_token = base64_encode((unsigned char *)raw_token); free(raw_token); @@ -290,7 +299,7 @@ static int _http_preprocess_request(struct evhttp_request *request, struct http_ } \ } -static void _http_callback_root(struct evhttp_request *request, UNUSED void *v_server) { +static void _http_callback_root(struct evhttp_request *request, void *v_server) { struct http_server_t *server = (struct http_server_t *)v_server; struct evbuffer *buf; @@ -303,6 +312,47 @@ static void _http_callback_root(struct evhttp_request *request, UNUSED void *v_s evbuffer_free(buf); } +static void _http_callback_static(struct evhttp_request *request, void *v_server) { + struct http_server_t *server = (struct http_server_t *)v_server; + struct evbuffer *buf = NULL; + struct evhttp_uri *uri = NULL; + char *uri_path; + char *decoded_path = NULL; + + PREPROCESS_REQUEST; + + if ((uri = evhttp_uri_parse(evhttp_request_get_uri(request))) == NULL) { + goto bad_request; + } + if ((uri_path = (char *)evhttp_uri_get_path(uri)) == NULL) { + uri_path = "/"; + } + + if ((decoded_path = evhttp_uridecode(uri_path, 0, NULL)) == NULL) { + goto bad_request; + } + + assert((buf = evbuffer_new())); + assert(evbuffer_add_printf(buf, "|%s|", decoded_path)); // TODO + evhttp_send_reply(request, HTTP_OK, "OK", buf); + goto cleanup; + + bad_request: + evhttp_send_error(request, HTTP_BADREQUEST, NULL); + goto cleanup; + + cleanup: + if (buf) { + evbuffer_free(buf); + } + if (decoded_path) { + free(decoded_path); + } + if (uri) { + evhttp_uri_free(uri); + } +} + static void _http_callback_state(struct evhttp_request *request, void *v_server) { struct http_server_t *server = (struct http_server_t *)v_server; struct evbuffer *buf; diff --git a/src/http.h b/src/http.h index c3d8a66..74b1a42 100644 --- a/src/http.h +++ b/src/http.h @@ -87,6 +87,7 @@ struct http_server_t { mode_t unix_mode; char *user; char *passwd; + char *static_path; unsigned drop_same_frames; bool slowdown; unsigned fake_width; diff --git a/src/main.c b/src/main.c index 6cd7a20..130db1e 100644 --- a/src/main.c +++ b/src/main.c @@ -81,11 +81,12 @@ static const struct option _LONG_OPTS[] = { {"unix-mode", required_argument, NULL, 'o'}, {"user", required_argument, NULL, 3000}, {"passwd", required_argument, NULL, 3001}, + {"static", required_argument, NULL, 3002}, {"drop-same-frames", required_argument, NULL, 'e'}, {"slowdown", no_argument, NULL, 'l'}, - {"fake-width", required_argument, NULL, 3002}, - {"fake-height", required_argument, NULL, 3003}, - {"server-timeout", required_argument, NULL, 3004}, + {"fake-width", required_argument, NULL, 3003}, + {"fake-height", required_argument, NULL, 3004}, + {"server-timeout", required_argument, NULL, 3005}, {"perf", no_argument, NULL, 5000}, {"verbose", no_argument, NULL, 5001}, @@ -163,6 +164,8 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s printf(" -o|--unix-mode ────── Set UNIX socket file permissions (like 777). Default: disabled\n\n"); printf(" --user ────────────── HTTP basic auth user. Default: disabled\n\n"); printf(" --passwd ───────────── HTTP basic auth passwd. Default: empty\n\n"); + printf(" --static ───────────── Serve static files instead of embedded root index page.\n"); + printf(" Default: disabled.\n\n"); printf(" -e|--drop-same-frames ── Don't send same frames to clients, but no more than specified number.\n"); printf(" It can significantly reduce the outgoing traffic, but will increase\n"); printf(" the CPU loading. Don't use this option with analog signal sources\n"); @@ -280,11 +283,12 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e case 'o': OPT_CHMOD(server->unix_mode, "--unix-mode"); case 3000: OPT_SET(server->user, optarg); case 3001: OPT_SET(server->passwd, optarg); + case 3002: OPT_SET(server->static_path, optarg); case 'e': OPT_UNSIGNED(server->drop_same_frames, "--drop-same-frames", 0, 30); case 'l': OPT_SET(server->slowdown, true); - case 3002: OPT_UNSIGNED(server->fake_width, "--fake-width", 0, 1920); - case 3003: OPT_UNSIGNED(server->fake_height, "--fake-height", 0, 1200); - case 3004: OPT_UNSIGNED(server->timeout, "--server-timeout", 1, 60); + case 3003: OPT_UNSIGNED(server->fake_width, "--fake-width", 0, 1920); + case 3004: OPT_UNSIGNED(server->fake_height, "--fake-height", 0, 1200); + case 3005: OPT_UNSIGNED(server->timeout, "--server-timeout", 1, 60); case 5000: OPT_SET(log_level, LOG_LEVEL_PERF); case 5001: OPT_SET(log_level, LOG_LEVEL_VERBOSE);