From 38ba93805b383e1b6ead6ce4dbdd16ee4ce976b2 Mon Sep 17 00:00:00 2001 From: jbnadal Date: Fri, 13 Apr 2018 17:59:07 +0200 Subject: [PATCH] Update the uhttpd version --- ...CMakeLists.txt => CMakeLists.original.txt} | 3 ++ src/3P/uhttpd/builders/cmake/CMakeLists.txt | 50 +++++++++++++++++++ src/3P/uhttpd/cgi.c | 6 ++- src/3P/uhttpd/client.c | 19 ++++++- src/3P/uhttpd/file.c | 23 ++++++--- src/3P/uhttpd/handler.c | 30 ++++++++++- src/3P/uhttpd/listen.c | 1 + src/3P/uhttpd/main.c | 7 ++- src/3P/uhttpd/uhttpd.h | 5 ++ src/3P/uhttpd/utils.c | 4 ++ 10 files changed, 135 insertions(+), 13 deletions(-) rename src/3P/uhttpd/{CMakeLists.txt => CMakeLists.original.txt} (95%) create mode 100644 src/3P/uhttpd/builders/cmake/CMakeLists.txt diff --git a/src/3P/uhttpd/CMakeLists.txt b/src/3P/uhttpd/CMakeLists.original.txt similarity index 95% rename from src/3P/uhttpd/CMakeLists.txt rename to src/3P/uhttpd/CMakeLists.original.txt index 8514351b..7ae8ba4d 100644 --- a/src/3P/uhttpd/CMakeLists.txt +++ b/src/3P/uhttpd/CMakeLists.original.txt @@ -21,6 +21,9 @@ IF(LIBS STREQUAL "LIBS-NOTFOUND") SET(LIBS "") ENDIF() +FIND_PATH(ubox_include_dir libubox/usock.h) +INCLUDE_DIRECTORIES(${ubox_include_dir}) + SET(SOURCES main.c listen.c client.c utils.c file.c auth.c cgi.c relay.c proc.c plugin.c handler.c) IF(TLS_SUPPORT) SET(SOURCES ${SOURCES} tls.c) diff --git a/src/3P/uhttpd/builders/cmake/CMakeLists.txt b/src/3P/uhttpd/builders/cmake/CMakeLists.txt new file mode 100644 index 00000000..c1829cc3 --- /dev/null +++ b/src/3P/uhttpd/builders/cmake/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required (VERSION 3.0) + +project (uhttpd) + +ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 -Os -Wall -Wmissing-declarations --std=gnu99 -g3) + +set (CMAKE_MODULE_PATH "${MODULE_PATH}") + +set(DISABLE_TARGET_OPTIMIZATION ON) + +include (br) + +include_directories (${workspaceRoot}/src/3P/uhttpd/) + +# uhttpd +add_executable (uhttpd + + ${workspaceRoot}/src/3P/uhttpd/main.c + ${workspaceRoot}/src/3P/uhttpd/listen.c + ${workspaceRoot}/src/3P/uhttpd/client.c + ${workspaceRoot}/src/3P/uhttpd/utils.c + ${workspaceRoot}/src/3P/uhttpd/file.c + ${workspaceRoot}/src/3P/uhttpd/auth.c + ${workspaceRoot}/src/3P/uhttpd/cgi.c + ${workspaceRoot}/src/3P/uhttpd/relay.c + ${workspaceRoot}/src/3P/uhttpd/proc.c + ${workspaceRoot}/src/3P/uhttpd/plugin.c + ${workspaceRoot}/src/3P/uhttpd/handler.c +) + +if (REST_API_PLUGING) + add_definitions (-DHAVE_REST_API_PLUGING) +endif () + +IF (UBUS_SUPPORT) + ADD_DEFINITIONS (-DHAVE_UBUS) + ADD_LIBRARY (uhttpd_ubus MODULE + ${workspaceRoot}/src/3P/uhttpd/ubus.c + ) + TARGET_LINK_LIBRARIES (uhttpd_ubus ubus ubox blobmsg_json json-c) + SET_TARGET_PROPERTIES (uhttpd_ubus PROPERTIES PREFIX "") + INSTALL (TARGETS uhttpd_ubus LIBRARY DESTINATION local/lib/) +ENDIF () + +target_link_libraries (uhttpd ubox dl json_script blobmsg_json json-c crypt) + +install (TARGETS uhttpd DESTINATION local/bin) + +file (GLOB headers ${workspaceRoot}/src/3P/uhttpd/*.h) +install (FILES ${headers} DESTINATION include/uhttpd) diff --git a/src/3P/uhttpd/cgi.c b/src/3P/uhttpd/cgi.c index dc302a9a..0ffb1308 100644 --- a/src/3P/uhttpd/cgi.c +++ b/src/3P/uhttpd/cgi.c @@ -104,7 +104,11 @@ static bool check_cgi_path(struct path_info *pi, const char *url) } pi->ip = NULL; - return uh_path_match(conf.cgi_docroot_path, pi->phys); + + if (conf.cgi_docroot_path) + return uh_path_match(conf.cgi_docroot_path, pi->phys); + + return false; } struct dispatch_handler cgi_dispatch = { diff --git a/src/3P/uhttpd/client.c b/src/3P/uhttpd/client.c index 73e0e49c..2c7f74e9 100644 --- a/src/3P/uhttpd/client.c +++ b/src/3P/uhttpd/client.c @@ -19,6 +19,10 @@ #include #include +#include +#include +#include + #include "uhttpd.h" #include "tls.h" @@ -37,6 +41,8 @@ const char * const http_versions[] = { const char * const http_methods[] = { [UH_HTTP_MSG_GET] = "GET", + [UH_HTTP_MSG_PUT] = "PUT", + [UH_HTTP_MSG_DELETE] = "DELETE", [UH_HTTP_MSG_POST] = "POST", [UH_HTTP_MSG_HEAD] = "HEAD", [UH_HTTP_MSG_OPTIONS] = "OPTIONS", @@ -45,8 +51,10 @@ const char * const http_methods[] = { void uh_http_header(struct client *cl, int code, const char *summary) { struct http_request *r = &cl->request; + struct blob_attr *cur; const char *enc = "Transfer-Encoding: chunked\r\n"; const char *conn; + int rem; cl->http_code = code; @@ -64,12 +72,17 @@ void uh_http_header(struct client *cl, int code, const char *summary) if (!r->connection_close) ustream_printf(cl->us, "Keep-Alive: timeout=%d\r\n", conf.http_keepalive); + + blobmsg_for_each_attr(cur, cl->hdr_response.head, rem) + ustream_printf(cl->us, "%s: %s\r\n", blobmsg_name(cur), + blobmsg_get_string(cur)); } static void uh_connection_close(struct client *cl) { cl->state = CLIENT_STATE_CLOSE; cl->us->eof = true; + cl->refcount = 0; ustream_state_change(cl->us); } @@ -86,6 +99,7 @@ static void client_timeout(struct uloop_timeout *timeout) struct client *cl = container_of(timeout, struct client, timeout); cl->state = CLIENT_STATE_CLOSE; + uh_client_unref (cl); uh_connection_close(cl); } @@ -114,6 +128,7 @@ void uh_request_done(struct client *cl) { uh_chunk_eof(cl); uh_dispatch_done(cl); + blob_buf_init(&cl->hdr_response, 0); memset(&cl->dispatch, 0, sizeof(cl->dispatch)); if (!conf.http_keepalive || cl->request.connection_close) @@ -519,7 +534,7 @@ static void client_close(struct client *cl) cl->state = CLIENT_STATE_CLEANUP; return; } - + // printf ("client_close (%d)\n", n_clients); client_done = true; n_clients--; uh_dispatch_done(cl); @@ -530,6 +545,7 @@ static void client_close(struct client *cl) close(cl->sfd.fd.fd); list_del(&cl->list); blob_buf_free(&cl->hdr); + blob_buf_free(&cl->hdr_response); free(cl); uh_unblock_listeners(); @@ -580,6 +596,7 @@ static void set_addr(struct uh_addr *addr, void *src) addr->family = sin->sin_family; if (addr->family == AF_INET) { addr->port = ntohs(sin->sin_port); + printf("client id: %d - ip addr: %s\n", n_clients, inet_ntoa(sin->sin_addr)); memcpy(&addr->in, &sin->sin_addr, sizeof(addr->in)); } else { addr->port = ntohs(sin6->sin6_port); diff --git a/src/3P/uhttpd/file.c b/src/3P/uhttpd/file.c index 12aa1303..047b4dac 100644 --- a/src/3P/uhttpd/file.c +++ b/src/3P/uhttpd/file.c @@ -565,11 +565,12 @@ static void uh_file_free(struct client *cl) static void uh_file_data(struct client *cl, struct path_info *pi, int fd) { /* test preconditions */ - if (!uh_file_if_modified_since(cl, &pi->stat) || - !uh_file_if_match(cl, &pi->stat) || - !uh_file_if_range(cl, &pi->stat) || - !uh_file_if_unmodified_since(cl, &pi->stat) || - !uh_file_if_none_match(cl, &pi->stat)) { + if (!cl->dispatch.no_cache && + (!uh_file_if_modified_since(cl, &pi->stat) || + !uh_file_if_match(cl, &pi->stat) || + !uh_file_if_range(cl, &pi->stat) || + !uh_file_if_unmodified_since(cl, &pi->stat) || + !uh_file_if_none_match(cl, &pi->stat))) { ustream_printf(cl->us, "\r\n"); uh_request_done(cl); close(fd); @@ -863,6 +864,7 @@ void uh_handle_request(struct client *cl) char *url = blobmsg_data(blob_data(cl->hdr.head)); char *error_handler; + blob_buf_init(&cl->hdr_response, 0); url = uh_handle_alias(url); uh_handler_run(cl, &url, false); @@ -877,9 +879,14 @@ void uh_handle_request(struct client *cl) if (__handle_file_request(cl, url)) return; - if (uh_handler_run(cl, &url, true) && - (!url || __handle_file_request(cl, url))) - return; + if (uh_handler_run(cl, &url, true)) { + if (!url) + return; + + uh_handler_run(cl, &url, false); + if (__handle_file_request(cl, url)) + return; + } req->redirect_status = 404; if (conf.error_handler) { diff --git a/src/3P/uhttpd/handler.c b/src/3P/uhttpd/handler.c index 8e8b9c8c..04e71e0f 100644 --- a/src/3P/uhttpd/handler.c +++ b/src/3P/uhttpd/handler.c @@ -102,6 +102,32 @@ handle_set_uri(struct json_script_ctx *ctx, struct blob_attr *data) json_script_abort(ctx); } +static void +handle_add_header(struct json_script_ctx *ctx, struct blob_attr *data) +{ + struct client *cl = cur_client; + static struct blobmsg_policy policy[2] = { + { .type = BLOBMSG_TYPE_STRING }, + { .type = BLOBMSG_TYPE_STRING }, + }; + struct blob_attr *tb[2]; + + blobmsg_parse_array(policy, ARRAY_SIZE(tb), tb, blobmsg_data(data), blobmsg_data_len(data)); + if (!tb[0] || !tb[1]) + return; + + blobmsg_add_string(&cl->hdr_response, blobmsg_get_string(tb[0]), + blobmsg_get_string(tb[1])); +} + +static void +handle_no_cache(struct json_script_ctx *ctx, struct blob_attr *data) +{ + struct client *cl = cur_client; + + cl->dispatch.no_cache = true; +} + static void handle_command(struct json_script_ctx *ctx, const char *name, struct blob_attr *data, struct blob_attr *vars) @@ -111,7 +137,9 @@ handle_command(struct json_script_ctx *ctx, const char *name, void (*func)(struct json_script_ctx *ctx, struct blob_attr *data); } cmds[] = { { "redirect", handle_redirect }, - { "rewrite", handle_set_uri } + { "rewrite", handle_set_uri }, + { "add-header", handle_add_header }, + { "no-cache", handle_no_cache }, }; int i; diff --git a/src/3P/uhttpd/listen.c b/src/3P/uhttpd/listen.c index 92ca680a..8ab4d5b1 100644 --- a/src/3P/uhttpd/listen.c +++ b/src/3P/uhttpd/listen.c @@ -119,6 +119,7 @@ void uh_setup_listeners(void) #endif setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)); + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)); } l->fd.cb = listener_cb; diff --git a/src/3P/uhttpd/main.c b/src/3P/uhttpd/main.c index fb276657..cf0b19e3 100644 --- a/src/3P/uhttpd/main.c +++ b/src/3P/uhttpd/main.c @@ -42,7 +42,7 @@ static int run_server(void) uh_setup_listeners(); uh_plugin_post_init(); uloop_run(); - + free (optarg); return 0; } @@ -496,7 +496,10 @@ int main(int argc, char **argv) if (conf.ubus_prefix && uh_plugin_init("uhttpd_ubus.so")) return 1; #endif - +#ifdef HAVE_REST_API_PLUGING + if (uh_plugin_init("uhttpd_rest-api-plugin.so")) + return 1; +#endif /* fork (if not disabled) */ if (!nofork) { switch (fork()) { diff --git a/src/3P/uhttpd/uhttpd.h b/src/3P/uhttpd/uhttpd.h index f9ea7619..b4e0745e 100644 --- a/src/3P/uhttpd/uhttpd.h +++ b/src/3P/uhttpd/uhttpd.h @@ -89,6 +89,8 @@ struct auth_realm { enum http_method { UH_HTTP_MSG_GET, + UH_HTTP_MSG_PUT, + UH_HTTP_MSG_DELETE, UH_HTTP_MSG_POST, UH_HTTP_MSG_HEAD, UH_HTTP_MSG_OPTIONS, @@ -224,6 +226,7 @@ struct dispatch { void (*req_free)(struct client *cl); bool data_blocked; + bool no_cache; union { struct { @@ -258,7 +261,9 @@ struct client { struct uh_addr srv_addr, peer_addr; struct blob_buf hdr; + struct blob_buf hdr_response; struct dispatch dispatch; + struct timeval start_request; }; extern char uh_buf[4096]; diff --git a/src/3P/uhttpd/utils.c b/src/3P/uhttpd/utils.c index 29e03c0b..9342eb66 100644 --- a/src/3P/uhttpd/utils.c +++ b/src/3P/uhttpd/utils.c @@ -208,6 +208,10 @@ bool uh_path_match(const char *prefix, const char *url) { int len = strlen(prefix); + /* A prefix of "/" will - by definition - match any url */ + if (prefix[0] == '/' && len == 1) + return true; + if (strncmp(url, prefix, len) != 0) return false;