From 7c2529a9fbcb7d2408a77d77fa330b04fd6ee157 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Tue, 24 May 2022 17:12:50 +0100 Subject: [PATCH] Fix httpd not accepting empty last post variable Also enable IPv6 Also add -lfmt to Makefile --- Makefile | 2 +- httpdclient.c | 92 +++++++++++++++++++++++++++------------------------ httpdclient.h | 4 ++- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/Makefile b/Makefile index ab27093..4750574 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ install-i18n: $(I18Nmsgs) $(SOFILE): $(OBJS) @echo LD $@ - $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -ljsoncpp -lconfig++ -lmicrohttpd -o $@ + $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -ljsoncpp -lconfig++ -lmicrohttpd -lfmt -o $@ install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) diff --git a/httpdclient.c b/httpdclient.c index 8772714..f815c52 100644 --- a/httpdclient.c +++ b/httpdclient.c @@ -25,7 +25,7 @@ bool HTTPDClient::StartServer(std::string _docRoot, int port, const char* _confi logger = spd::get("jsonserver_spdlog"); - httpdserver = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL, + httpdserver = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_IPv6, port, NULL, NULL, &HTTPDClient::handle_connection, NULL, MHD_OPTION_NOTIFY_CONNECTION, &HTTPDClient::connection_notify, NULL, MHD_OPTION_NOTIFY_COMPLETED, &HTTPDClient::request_completed, NULL, @@ -93,39 +93,58 @@ int HTTPDClient::handle_connection(void* cls, struct MHD_Connection* mhd_connect const char* version, const char* upload_data, size_t* upload_data_size, void** userData) { -/* - logger->debug("handle_connection called"); - logger->debug("hc: cls {}", (void*)cls); - logger->debug("hc: mhd_connection {}", (void*)mhd_connection); - logger->debug("hc: url {}", (void*)url); - if (url) logger->debug("hc: url: {}", url); - logger->debug("hc: method {}", (void*)method); - if (url) logger->debug("hc: method: {}", method); - logger->debug("hc: version {}", (void*)version); - if (url) logger->debug("hc: version: {}", version); - logger->debug("hc: upload_data {}", (void*)upload_data); - logger->debug("hc: upload_data_size {}", *upload_data_size); - logger->debug("hc: userData {}", (void*)*userData); -*/ - const MHD_ConnectionInfo* mhdc = MHD_get_connection_info(mhd_connection, MHD_CONNECTION_INFO_SOCKET_CONTEXT); - HTTPDClient* httpdclient = (HTTPDClient*)mhdc->socket_context; + return httpdclient->handleConnection(url, method, version, upload_data, upload_data_size, userData); +} + +// End of static callbacks, now for the client object itself + +HTTPDClient::HTTPDClient(struct MHD_Connection* _mhd_connection, const std::string& _configDir) +: postprocessor(NULL), url(NULL), mhd_connection(_mhd_connection), vdrclient(_configDir) +{ +// printf("HTTPDClient created %p\n", this); +} + +HTTPDClient::~HTTPDClient() +{ +// printf("%p HTTPDClient destructor\n", this); + if (url) free(url); +} + +int HTTPDClient::handleConnection(const char* turl, const char* method, + const char* version, const char* upload_data, + size_t* upload_data_size, void** userData) +{ + /* + logger->debug("handle_connection called"); + logger->debug("hc: cls {}", (void*)cls); + logger->debug("hc: mhd_connection {}", (void*)mhd_connection); + logger->debug("hc: url {}", (void*)url); + if (url) logger->debug("hc: url: {}", url); + logger->debug("hc: method {}", (void*)method); + if (url) logger->debug("hc: method: {}", method); + logger->debug("hc: version {}", (void*)version); + if (url) logger->debug("hc: version: {}", version); + logger->debug("hc: upload_data {}", (void*)upload_data); + logger->debug("hc: upload_data_size {}", *upload_data_size); + logger->debug("hc: userData {}", (void*)*userData); + */ // Now we are going to use userData as a flag to say first run or not if (!*userData) // new request { *userData = (void*)1; - httpdclient->setUrl(url); + int size __attribute__((unused)) = asprintf(&url, "%s", turl); if (!strcmp(method, "POST")) { - MHD_get_connection_values(mhd_connection, MHD_GET_ARGUMENT_KIND, HTTPDClient::uri_key_value, (void*)httpdclient); + MHD_get_connection_values(mhd_connection, MHD_GET_ARGUMENT_KIND, HTTPDClient::uri_key_value, (void*)this); // The following returns NULL if there are no POST fields to come - httpdclient->postprocessor = MHD_create_post_processor(mhd_connection, POSTBUFFERSIZE, - HTTPDClient::iterate_post, (void*)httpdclient); + postprocessor = MHD_create_post_processor(mhd_connection, POSTBUFFERSIZE, + HTTPDClient::iterate_post, (void*)this); } else if (!strcmp(method, "GET")) { @@ -143,7 +162,7 @@ int HTTPDClient::handle_connection(void* cls, struct MHD_Connection* mhd_connect if (!strcmp(method, "GET")) { - return httpdclient->processGET(); + return processGET(); } else if (!strcmp(method, "POST")) { @@ -153,36 +172,26 @@ int HTTPDClient::handle_connection(void* cls, struct MHD_Connection* mhd_connect if (*upload_data_size != 0) // There is more to process, and signal run again { - MHD_post_process(httpdclient->postprocessor, upload_data, *upload_data_size); + MHD_post_process(postprocessor, upload_data, *upload_data_size); *upload_data_size = 0; return MHD_YES; } else { // printf("hc: zero post provided, end of upload\n"); - return httpdclient->processPOST(); + + MHD_destroy_post_processor(postprocessor); + postprocessor = NULL; + + return processPOST(); } } else { - return httpdclient->sendStockResponse(405); + return sendStockResponse(405); } } -// End of static callbacks, now for the client object itself - -HTTPDClient::HTTPDClient(struct MHD_Connection* _mhd_connection, const std::string& _configDir) -: postprocessor(NULL), url(NULL), mhd_connection(_mhd_connection), vdrclient(_configDir) -{ -// printf("HTTPDClient created %p\n", this); -} - -HTTPDClient::~HTTPDClient() -{ -// printf("%p HTTPDClient destructor\n", this); - if (url) free(url); -} - void HTTPDClient::requestComplete() { // printf("%p HTTPDClient request complete\n", this); @@ -194,11 +203,6 @@ void HTTPDClient::requestComplete() } } -void HTTPDClient::setUrl(const char* _url) -{ - int size __attribute__((unused)) = asprintf(&url, "%s", _url); -} - void HTTPDClient::addGetVar(const char* key, const char* value) { if (strlen(key) > 50) return; diff --git a/httpdclient.h b/httpdclient.h index 0721780..b44d928 100644 --- a/httpdclient.h +++ b/httpdclient.h @@ -45,7 +45,9 @@ class HTTPDClient HTTPDClient(struct MHD_Connection*, const std::string& configDir); ~HTTPDClient(); - void setUrl(const char* url); + int handleConnection(const char *url, const char *method, + const char *version, const char *upload_data, + size_t *upload_data_size, void **con_cls); int processGET(); int processPOST(); -- 2.39.2