| @@ -0,0 +1,30 @@ | |||
| #pragma once | |||
| #cmakedefine CPPMICROHTTPD_DEBUG | |||
| #cmakedefine CPPMICROHTTPD_LOGGING_NONE | |||
| #cmakedefine CPPMICROHTTPD_LOGGING_STDCOUT | |||
| #cmakedefine CPPMICROHTTPD_LOGGING_CPPLOGGING | |||
| #if defined(CPPMICROHTTPD_LOGGING_CPPLOGGING) | |||
| #include <cpplogging/interface.h> | |||
| #define cppmicrohttpd_log(p_level) \ | |||
| cpplogging_global_log(p_level) | |||
| #define cppmicrohttpd_log_debug(...) \ | |||
| cppmicrohttpd_log(debug) << __VA_ARGS__ | |||
| #elif defined(CPPMICROHTTPD_LOGGING_STDCOUT) | |||
| #include <iostream> | |||
| #define cppmicrohttpd_log(p_level) \ | |||
| ::std::cout << #p_level << ' ' << __FILE__ << ':' << __LINE__ << " - " | |||
| #ifdef CPPMICROHTTPD_DEBUG | |||
| #define cppmicrohttpd_log_debug(...) \ | |||
| cppmicrohttpd_log(debug) << __VA_ARGS__ | |||
| #else | |||
| #define cppmicrohttpd_log_debug(...) \ | |||
| do { } while (0) | |||
| #endif | |||
| #else | |||
| #define cppmicrohttpd_log(...) \ | |||
| do { } while (0) | |||
| #define cppmicrohttpd_log_debug(...) \ | |||
| do { } while (0) | |||
| #endif | |||
| @@ -10,6 +10,9 @@ Option ( CPPMICROHTTPD_INSTALL_SHARED | |||
| Option ( CPPMICROHTTPD_INSTALL_DEBUG | |||
| "Install the stripped debug informations of cppmicrohttpd." | |||
| OFF ) | |||
| Option ( CPPMICROHTTPD_NO_STRIP | |||
| "Do not strip debug symbols from binary." | |||
| OFF ) | |||
| If ( NOT CPPMICROHTTPD_LOGGING ) | |||
| Set ( CPPMICROHTTPD_LOGGING none | |||
| CACHE STRING "Specify how cppmicrohttpd should write log entries." ) | |||
| Set_Property ( CACHE CPPMICROHTTPD_LOGGING | |||
| PROPERTY STRINGS none stdout cpplogging ) | |||
| EndIf ( ) | |||
| @@ -2,6 +2,7 @@ | |||
| #include <memory> | |||
| #include <microhttpd.h> | |||
| #include <cppcore/platform/fdset.h> | |||
| #include "types.h" | |||
| #include "request/request.h" | |||
| @@ -52,22 +53,28 @@ namespace cppmicrohttpd | |||
| /** | |||
| * @brief Run webserver operations using the given sets of ready socket handles. | |||
| * | |||
| * @param[in] read File descriptor set with all file handles that are ready to read data from. | |||
| * @param[in] write File descriptor set with all file handles that are ready to write data to. | |||
| * @param[in] except File descriptor set with all file handles that are in a exceptional condition. | |||
| * @param[in] p_read File descriptor set with all file handles that are ready to read data from. | |||
| * @param[in] p_write File descriptor set with all file handles that are ready to write data to. | |||
| * @param[in] p_except File descriptor set with all file handles that are in a exceptional condition. | |||
| */ | |||
| inline void run(const fd_set& read, const fd_set& write, const fd_set& except); | |||
| inline void run( | |||
| const ::cppcore::fdset& p_read, | |||
| const ::cppcore::fdset& p_write, | |||
| const ::cppcore::fdset& p_except); | |||
| /** | |||
| * @brief Write all file descriptors known by the daemon to the passed file descriptor sets. | |||
| * | |||
| * @param[in] read File descriptor set to listen for read operations. | |||
| * @param[in] write File descriptor set to listen for write operations. | |||
| * @param[in] except File descriptor set to listen for exceptional condition. | |||
| * @param[in] p_read File descriptor set to listen for read operations. | |||
| * @param[in] p_write File descriptor set to listen for write operations. | |||
| * @param[in] p_except File descriptor set to listen for exceptional condition. | |||
| * | |||
| * @return Greatest file descriptor. | |||
| */ | |||
| inline int prepare_fd_sets(fd_set& read, fd_set& write, fd_set& except) const; | |||
| inline int prepare_fdsets( | |||
| ::cppcore::fdset& p_read, | |||
| ::cppcore::fdset& p_write, | |||
| ::cppcore::fdset& p_except) const; | |||
| /** | |||
| * @brief Get the timeout in milliseconds to wait for the file descriptors. | |||
| @@ -103,6 +110,18 @@ namespace cppmicrohttpd | |||
| virtual response_ptr_u create_response( | |||
| const request& p_request); | |||
| /** | |||
| * @brief Create a default response object. | |||
| * | |||
| * @param[in] p_request Request to create response for. | |||
| * @param[in] p_error_only Only create responses for erroneous request. | |||
| * | |||
| * @return Created request or null if no request could be created. | |||
| */ | |||
| response_ptr_u create_default_response( | |||
| const request& p_request, | |||
| bool p_error_only); | |||
| public: | |||
| /** | |||
| * @brief Callback to handle requests. | |||
| @@ -16,16 +16,22 @@ namespace cppmicrohttpd | |||
| throw exception("Unable to execute MHD_run"); | |||
| } | |||
| void daemon::run(const fd_set& read, const fd_set& write, const fd_set& except) | |||
| void daemon::run( | |||
| const ::cppcore::fdset& p_read, | |||
| const ::cppcore::fdset& p_write, | |||
| const ::cppcore::fdset& p_except) | |||
| { | |||
| if (MHD_run_from_select(_handle.get(), &read, &write, &except) != MHD_YES) | |||
| if (MHD_run_from_select(_handle.get(), &p_read, &p_write, &p_except) != MHD_YES) | |||
| throw exception("Unable to execute MHD_run_from_select"); | |||
| } | |||
| int daemon::prepare_fd_sets(fd_set& read, fd_set& write, fd_set& except) const | |||
| int daemon::prepare_fdsets( | |||
| ::cppcore::fdset& p_read, | |||
| ::cppcore::fdset& p_write, | |||
| ::cppcore::fdset& p_except) const | |||
| { | |||
| int ret = 0; | |||
| if (MHD_get_fdset(_handle.get(), &read, &write, &except, &ret) != MHD_YES) | |||
| if (MHD_get_fdset(_handle.get(), &p_read, &p_write, &p_except, &ret) != MHD_YES) | |||
| throw exception("Unable to execute MHD_get_fdset"); | |||
| return ret; | |||
| } | |||
| @@ -20,7 +20,7 @@ namespace cppmicrohttpd | |||
| struct request | |||
| { | |||
| private: | |||
| using exception_ptr_u = std::unique_ptr<std::exception>; | |||
| using exception_ptr_u = std::unique_ptr<const std::exception>; | |||
| public: | |||
| MHD_Connection * const connection; //!< Connection this request was received at. | |||
| @@ -60,7 +60,7 @@ namespace cppmicrohttpd | |||
| use_pedantic_checks = MHD_USE_PEDANTIC_CHECKS, | |||
| /** | |||
| * Use poll() instead of select(). This allows sockets with descriptors >= FD_SETSIZE. This option currently only | |||
| * Use poll() instead of select(). This allows sockets with descriptors >= ::cppcore::fdsetSIZE. This option currently only | |||
| * works in conjunction with MHD_USE_THREAD_PER_CONNECTION or MHD_USE_INTERNAL_SELECT (at this point). | |||
| * If you specify MHD_USE_POLL and the local platform does not support it, MHD_start_daemon will return NULL. | |||
| */ | |||
| @@ -5,11 +5,26 @@ Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTI | |||
| Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS ) | |||
| Find_Package ( cppcore REQUIRED ) | |||
| Find_Package ( libmicrohttpd REQUIRED ) | |||
| If ( CPPMICROHTTPD_LOGGING MATCHES none ) | |||
| Set ( CPPMICROHTTPD_LOGGING_NONE true ) | |||
| ElseIf ( CPPMICROHTTPD_LOGGING MATCHES stdcout ) | |||
| Set ( CPPMICROHTTPD_LOGGING_STDCOUT true ) | |||
| ElseIf ( CPPMICROHTTPD_LOGGING MATCHES cpplogging ) | |||
| Find_Package ( cpplogging QUIET ) | |||
| If ( cpplogging_FOUND ) | |||
| Set ( CPPMICROHTTPD_LOGGING_CPPLOGGING true ) | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| # Object Library ################################################################################## | |||
| Set ( CMAKE_POSITION_INDEPENDENT_CODE ON ) | |||
| Set ( CPPMICROHTTPD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| Set ( CPPMICROHTTPD_GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated/include ) | |||
| Configure_File ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/config.h.in | |||
| ${CPPMICROHTTPD_GENERATED_INCLUDE_DIR}/cppmicrohttpd/config.h ) | |||
| File ( GLOB_RECURSE CPPMICROHTTPD_HEADER_FILES ${CPPMICROHTTPD_INCLUDE_DIR}/*.h ) | |||
| File ( GLOB_RECURSE CPPMICROHTTPD_INLINE_FILES ${CPPMICROHTTPD_INCLUDE_DIR}/*.inl ) | |||
| File ( GLOB_RECURSE CPPMICROHTTPD_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| @@ -21,10 +36,16 @@ Add_Library ( cppmicrohttpd-objects | |||
| Target_Include_Directories ( cppmicrohttpd-objects | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${CPPMICROHTTPD_INCLUDE_DIR}> | |||
| $<BUILD_INTERFACE:${CPPMICROHTTPD_GENERATED_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPMICROHTTPD_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( cppmicrohttpd-objects | |||
| PUBLIC | |||
| cppcore::cppcore ) | |||
| If ( CPPMICROHTTPD_LOGGING_CPPLOGGING ) | |||
| Target_Link_Libraries ( cppmicrohttpd-objects | |||
| PUBLIC | |||
| cpplogging::cpplogging-shared ) | |||
| EndIf ( ) | |||
| # Static Library ################################################################################## | |||
| @@ -36,10 +57,17 @@ Set_Target_Properties ( cppmicrohttpd-static | |||
| Target_Include_Directories ( cppmicrohttpd-static | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${CPPMICROHTTPD_INCLUDE_DIR}> | |||
| $<BUILD_INTERFACE:${CPPMICROHTTPD_GENERATED_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPMICROHTTPD_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( cppmicrohttpd-static | |||
| PUBLIC | |||
| cppcore::cppcore ) | |||
| cppcore::cppcore | |||
| libmicrohttpd::libmicrohttpd-static ) | |||
| If ( CPPMICROHTTPD_LOGGING_CPPLOGGING ) | |||
| Target_Link_Libraries ( cppmicrohttpd-static | |||
| PUBLIC | |||
| cpplogging::cpplogging-static ) | |||
| EndIf ( ) | |||
| # Shared Library ################################################################################## | |||
| @@ -52,10 +80,17 @@ Set_Target_Properties ( cppmicrohttpd-shared | |||
| Target_Include_Directories ( cppmicrohttpd-shared | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${CPPMICROHTTPD_INCLUDE_DIR}> | |||
| $<BUILD_INTERFACE:${CPPMICROHTTPD_GENERATED_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPMICROHTTPD_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( cppmicrohttpd-shared | |||
| PUBLIC | |||
| cppcore::cppcore ) | |||
| cppcore::cppcore | |||
| libmicrohttpd::libmicrohttpd-shared ) | |||
| If ( CPPMICROHTTPD_LOGGING_CPPLOGGING ) | |||
| Target_Link_Libraries ( cppmicrohttpd-shared | |||
| PUBLIC | |||
| cpplogging::cpplogging-shared ) | |||
| EndIf ( ) | |||
| # Optimization #################################################################################### | |||
| @@ -81,6 +116,8 @@ If ( CPPMICROHTTPD_INSTALL_HEADER ) | |||
| DESTINATION ${CPPMICROHTTPD_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPMICROHTTPD_INCLUDE_DIR}/cppmicrohttpd | |||
| DESTINATION ${CPPMICROHTTPD_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPMICROHTTPD_GENERATED_INCLUDE_DIR}/cppmicrohttpd | |||
| DESTINATION ${CPPMICROHTTPD_INSTALL_DIR_INCLUDE} ) | |||
| EndIf ( ) | |||
| # Static | |||
| @@ -1,4 +1,6 @@ | |||
| #include <vector> | |||
| #include <cppcore/conversion/string.h> | |||
| #include <cppmicrohttpd/config.h> | |||
| #include <cppmicrohttpd/daemon.h> | |||
| #include <cppmicrohttpd/request/request.inl> | |||
| @@ -37,21 +39,53 @@ request_ptr_u daemon::create_request( | |||
| response_ptr_u daemon::create_response( | |||
| const request& p_request) | |||
| { return create_default_response(p_request, true); } | |||
| response_ptr_u daemon::create_default_response( | |||
| const request& p_request, | |||
| bool p_error_only) | |||
| { | |||
| using namespace ::std; | |||
| if (p_request.error) | |||
| { | |||
| /* TODO | |||
| auto err = *request.httpError; | |||
| return Response::buildSimpleHtmlResponse( | |||
| request, | |||
| err.status, | |||
| err.title, | |||
| err.head, | |||
| err.message); | |||
| */ | |||
| auto* http_ex = dynamic_cast<const http_exception*>(p_request.error.get()); | |||
| auto* core_ex = dynamic_cast<const ::cppcore::exception*>(p_request.error.get()); | |||
| if (http_ex) | |||
| { | |||
| return response::build_simple_html_response( | |||
| p_request, | |||
| http_ex->status, | |||
| "Status "s + ::cppcore::to_string(http_ex->status), | |||
| "Status "s + ::cppcore::to_string(http_ex->status), | |||
| http_ex->print(::cppcore::exception::print_flags::empty())); | |||
| } | |||
| else if (core_ex) | |||
| { | |||
| return response::build_simple_html_response( | |||
| p_request, | |||
| 500, | |||
| "Status 500"s, | |||
| "Status 500"s, | |||
| core_ex->print(::cppcore::exception::print_flags::empty())); | |||
| } | |||
| else | |||
| { | |||
| return response::build_simple_html_response( | |||
| p_request, | |||
| 500, | |||
| "Status 500"s, | |||
| "Status 500"s, | |||
| "Unknown error. Check server error log."); | |||
| } | |||
| } | |||
| return nullptr; | |||
| return response::build_simple_html_response( | |||
| p_request, | |||
| 404, | |||
| "Status 404"s, | |||
| "Status 404"s, | |||
| "The requested URL could not be found on this server: "s + p_request.url); | |||
| } | |||
| int daemon::mhd_access_handler_callback( | |||
| @@ -86,9 +120,14 @@ int daemon::mhd_access_handler_callback( | |||
| return MHD_YES; | |||
| } | |||
| } | |||
| catch(const std::exception& ex) | |||
| { | |||
| cppmicrohttpd_log(error) << "Error while creating request: " << ex.what(); | |||
| return MHD_NO; | |||
| } | |||
| catch(...) | |||
| { | |||
| // TODO: log error | |||
| cppmicrohttpd_log(error) << "Error while creating request: unknown"; | |||
| return MHD_NO; | |||
| } | |||
| @@ -103,26 +142,28 @@ int daemon::mhd_access_handler_callback( | |||
| } | |||
| catch(const http_exception& ex) | |||
| { | |||
| cppmicrohttpd_log(warn) << "Error while handling post data: " << ex; | |||
| req.set_error(ex); | |||
| *data_size = 0; // Assume that all data has been progressed | |||
| return MHD_YES; | |||
| } | |||
| catch(const exception& ex) | |||
| { | |||
| cppmicrohttpd_log(warn) << "Error while handling post data: " << ex; | |||
| req.set_error(ex); | |||
| *data_size = 0; // Assume that all data has been progressed | |||
| return MHD_YES; | |||
| } | |||
| catch(std::exception& ex) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while handling post data: " << ex.what(); | |||
| req.set_error(exception(ex.what())); | |||
| *data_size = 0; // Assume that all data has been progressed | |||
| return MHD_YES; | |||
| } | |||
| catch(...) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while handling post data: unknown"; | |||
| req.set_error(exception("Unknown error")); | |||
| *data_size = 0; // Assume that all data has been progressed | |||
| return MHD_YES; | |||
| @@ -144,9 +185,14 @@ int daemon::mhd_access_handler_callback( | |||
| } | |||
| return MHD_YES; | |||
| } | |||
| catch(const std::exception& ex) | |||
| { | |||
| cppmicrohttpd_log(error) << "Error while creating response: " << ex.what(); | |||
| return MHD_NO; | |||
| } | |||
| catch(...) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(error) << "Error while creating response: unknown"; | |||
| return MHD_NO; | |||
| } | |||
| } | |||
| @@ -1,3 +1,4 @@ | |||
| #include <cppmicrohttpd/config.h> | |||
| #include <cppmicrohttpd/request/post_data_request.h> | |||
| #include <cppmicrohttpd/request/request.inl> | |||
| @@ -57,23 +58,23 @@ int post_data_request::mhd_post_data_iterator_callback( | |||
| } | |||
| catch(const http_exception& ex) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while iterating post data: " << ex; | |||
| req.set_error(ex); | |||
| } | |||
| catch(const exception& ex) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while iterating post data: " << ex; | |||
| req.set_error(ex); | |||
| } | |||
| catch(const std::exception& ex) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while iterating post data: " << ex.what(); | |||
| req.set_error(exception(ex.what())); | |||
| } | |||
| catch(...) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while iterating post data: unknown"; | |||
| req.set_error(exception("Unknown error")); | |||
| } | |||
| return MHD_YES; | |||
| return MHD_NO; | |||
| } | |||
| @@ -1,3 +1,4 @@ | |||
| #include <cppmicrohttpd/config.h> | |||
| #include <cppmicrohttpd/response/callback_response.h> | |||
| using namespace ::cppmicrohttpd; | |||
| @@ -16,9 +17,13 @@ ssize_t callback_response::mhd_content_reader_callback( | |||
| { | |||
| return res.read_content(pos, buf, max); | |||
| } | |||
| catch(const std::exception& ex) | |||
| { | |||
| cppmicrohttpd_log(warn) << "Error while generating response data: " << ex.what(); | |||
| } | |||
| catch(...) | |||
| { | |||
| // TODO log error | |||
| cppmicrohttpd_log(warn) << "Error while generating response data: unknown"; | |||
| } | |||
| /** | |||
| @@ -7,14 +7,14 @@ extern "C" | |||
| int MHD_get_fdset2( | |||
| struct MHD_Daemon *daemon, | |||
| fd_set * read_fd_set, | |||
| fd_set * write_fd_set, | |||
| fd_set * except_fd_set, | |||
| ::cppcore::fdset * read_::cppcore::fdset, | |||
| ::cppcore::fdset * write_::cppcore::fdset, | |||
| ::cppcore::fdset * except_::cppcore::fdset, | |||
| int * max_fd, | |||
| unsigned int fd_setsize) | |||
| unsigned int ::cppcore::fdsetsize) | |||
| { | |||
| return libmicrohttpd_mock::instance | |||
| ? libmicrohttpd_mock::instance->MHD_get_fdset2(daemon, read_fd_set, write_fd_set, except_fd_set, max_fd, fd_setsize) | |||
| ? libmicrohttpd_mock::instance->MHD_get_fdset2(daemon, read_::cppcore::fdset, write_::cppcore::fdset, except_::cppcore::fdset, max_fd, ::cppcore::fdsetsize) | |||
| : MHD_NO; | |||
| } | |||
| @@ -29,12 +29,12 @@ extern "C" | |||
| int MHD_run_from_select ( | |||
| struct MHD_Daemon * daemon, | |||
| const fd_set * read_fd_set, | |||
| const fd_set * write_fd_set, | |||
| const fd_set * except_fd_set) | |||
| const ::cppcore::fdset * read_::cppcore::fdset, | |||
| const ::cppcore::fdset * write_::cppcore::fdset, | |||
| const ::cppcore::fdset * except_::cppcore::fdset) | |||
| { | |||
| return libmicrohttpd_mock::instance | |||
| ? libmicrohttpd_mock::instance->MHD_run_from_select(daemon, read_fd_set, write_fd_set, except_fd_set) | |||
| ? libmicrohttpd_mock::instance->MHD_run_from_select(daemon, read_::cppcore::fdset, write_::cppcore::fdset, except_::cppcore::fdset) | |||
| : MHD_NO; | |||
| } | |||
| @@ -10,11 +10,11 @@ public: | |||
| MOCK_METHOD6( | |||
| MHD_get_fdset2, | |||
| int (struct MHD_Daemon *daemon, | |||
| fd_set * read_fd_set, | |||
| fd_set * write_fd_set, | |||
| fd_set * except_fd_set, | |||
| ::cppcore::fdset * read_::cppcore::fdset, | |||
| ::cppcore::fdset * write_::cppcore::fdset, | |||
| ::cppcore::fdset * except_::cppcore::fdset, | |||
| int * max_fd, | |||
| unsigned int fd_setsize)); | |||
| unsigned int ::cppcore::fdsetsize)); | |||
| MOCK_METHOD2( | |||
| MHD_get_timeout, | |||
| @@ -24,9 +24,9 @@ public: | |||
| MOCK_METHOD4( | |||
| MHD_run_from_select, | |||
| int (struct MHD_Daemon * daemon, | |||
| const fd_set * read_fd_set, | |||
| const fd_set * write_fd_set, | |||
| const fd_set * except_fd_set)); | |||
| const ::cppcore::fdset * read_::cppcore::fdset, | |||
| const ::cppcore::fdset * write_::cppcore::fdset, | |||
| const ::cppcore::fdset * except_::cppcore::fdset)); | |||
| MOCK_METHOD6( | |||
| MHD_start_daemon, | |||