changeset 2377:32bea64e070b

Experimental support of actively maintained Civetweb to replace Mongoose 3.8
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 28 Aug 2017 14:09:24 +0200
parents c33ff8a7ffa9
children 116ade1eff82
files CMakeLists.txt Core/HttpServer/MongooseServer.cpp NEWS Resources/CMake/CivetwebConfiguration.cmake TODO
diffstat 5 files changed, 139 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Aug 26 12:18:45 2017 +0200
+++ b/CMakeLists.txt	Mon Aug 28 14:09:24 2017 +0200
@@ -34,23 +34,25 @@
 SET(BUILD_RECOVER_COMPRESSED_FILE ON CACHE BOOL "Whether to build the companion tool to recover files compressed using Orthanc")
 SET(ENABLE_PKCS11 OFF CACHE BOOL "Enable PKCS#11 for HTTPS client authentication using hardware security modules and smart cards")
 SET(ENABLE_PROFILING OFF CACHE BOOL "Whether to enable the generation of profiling information with gprof")
+SET(ENABLE_CIVETWEB OFF CACHE BOOL "Use Civetweb instead of Mongoose (experimental)")
 
 # Advanced parameters to fine-tune linking against system libraries
-SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
+SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost")
+SET(USE_SYSTEM_CIVETWEB ON CACHE BOOL "Use the system version of Civetweb (experimental)")
+SET(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
+SET(USE_SYSTEM_DCMTK ON CACHE BOOL "Use the system version of DCMTK")
 SET(USE_SYSTEM_GOOGLE_TEST ON CACHE BOOL "Use the system version of Google Test")
-SET(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite")
-SET(USE_SYSTEM_MONGOOSE ON CACHE BOOL "Use the system version of Mongoose")
-SET(USE_SYSTEM_LUA ON CACHE BOOL "Use the system version of Lua")
-SET(USE_SYSTEM_DCMTK ON CACHE BOOL "Use the system version of DCMTK")
-SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost")
+SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
 SET(USE_SYSTEM_LIBICONV ON CACHE BOOL "Use the system version of libiconv")
+SET(USE_SYSTEM_LIBJPEG ON CACHE BOOL "Use the system version of libjpeg")
+SET(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11 wrapper library)")
 SET(USE_SYSTEM_LIBPNG ON CACHE BOOL "Use the system version of libpng")
-SET(USE_SYSTEM_LIBJPEG ON CACHE BOOL "Use the system version of libjpeg")
-SET(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
+SET(USE_SYSTEM_LUA ON CACHE BOOL "Use the system version of Lua")
+SET(USE_SYSTEM_MONGOOSE ON CACHE BOOL "Use the system version of Mongoose")
 SET(USE_SYSTEM_OPENSSL ON CACHE BOOL "Use the system version of OpenSSL")
+SET(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml")
+SET(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite")
 SET(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of ZLib")
-SET(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml")
-SET(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11 wrapper library)")
 
 # Advanced parameters
 SET(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
@@ -303,7 +305,6 @@
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibPngConfiguration.cmake)
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibJpegConfiguration.cmake)
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/LuaConfiguration.cmake)
-include(${CMAKE_SOURCE_DIR}/Resources/CMake/MongooseConfiguration.cmake)
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/PugixmlConfiguration.cmake)
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/SQLiteConfiguration.cmake)
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/ZlibConfiguration.cmake)
@@ -311,6 +312,20 @@
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibIconvConfiguration.cmake)
 include(${CMAKE_SOURCE_DIR}/Resources/CMake/OpenSslConfiguration.cmake)
 
+if (ENABLE_CIVETWEB)
+  include(${CMAKE_SOURCE_DIR}/Resources/CMake/CivetwebConfiguration.cmake)
+  add_definitions(
+    -DORTHANC_ENABLE_CIVETWEB=1
+    -DORTHANC_ENABLE_MONGOOSE=0
+    )
+else()
+  include(${CMAKE_SOURCE_DIR}/Resources/CMake/MongooseConfiguration.cmake)
+  add_definitions(
+    -DORTHANC_ENABLE_CIVETWEB=0
+    -DORTHANC_ENABLE_MONGOOSE=1
+    )
+endif()
+
 # These are the two most heavyweight dependencies. We put them as the
 # last includes to quickly spot problems when configuring static
 # builds.
@@ -484,6 +499,7 @@
   ${LIBP11_SOURCES}
   ${LIBPNG_SOURCES}
   ${LUA_SOURCES}
+  ${CIVETWEB_SOURCES}
   ${MONGOOSE_SOURCES}
   ${PUGIXML_SOURCES}
   ${SQLITE_SOURCES}
--- a/Core/HttpServer/MongooseServer.cpp	Sat Aug 26 12:18:45 2017 +0200
+++ b/Core/HttpServer/MongooseServer.cpp	Mon Aug 28 14:09:24 2017 +0200
@@ -39,7 +39,17 @@
 #include "../Logging.h"
 #include "../ChunkedBuffer.h"
 #include "HttpToolbox.h"
-#include "mongoose.h"
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
+#  include "mongoose.h"
+
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+#  include "civetweb.h"
+#  define MONGOOSE_USE_CALLBACKS 1
+
+#else
+#  error "Either Mongoose or Civetweb must be enabled to compile this file"
+#endif
 
 #include <algorithm>
 #include <string.h>
@@ -60,8 +70,6 @@
 
 #define ORTHANC_REALM "Orthanc Secure Area"
 
-static const long LOCALHOST = (127ll << 24) + 1ll;
-
 
 namespace Orthanc
 {
@@ -586,9 +594,22 @@
                                struct mg_connection *connection,
                                const struct mg_request_info *request)
   {
+    bool localhost;
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
+    static const long LOCALHOST = (127ll << 24) + 1ll;
+    localhost = (request->remote_ip == LOCALHOST);
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+    // The "remote_ip" field of "struct mg_request_info" is tagged as
+    // deprecated in Civetweb, using "remote_addr" instead.
+    localhost = (std::string(request->remote_addr) == "127.0.0.1");
+#else
+#error
+#endif
+    
     // Check remote calls
     if (!server.IsRemoteAccessAllowed() &&
-        request->remote_ip != LOCALHOST)
+        !localhost)
     {
       output.SendUnauthorized(ORTHANC_REALM);
       return;
@@ -638,7 +659,8 @@
       return;
     }
 
-
+    
+#if ORTHANC_ENABLE_MONGOOSE == 1
     // Apply the filter, if it is installed
     char remoteIp[24];
     sprintf(remoteIp, "%d.%d.%d.%d", 
@@ -646,6 +668,11 @@
             reinterpret_cast<const uint8_t*>(&request->remote_ip) [2], 
             reinterpret_cast<const uint8_t*>(&request->remote_ip) [1], 
             reinterpret_cast<const uint8_t*>(&request->remote_ip) [0]);
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+    const char* remoteIp = request->remote_addr;
+#else
+#error
+#endif
 
     std::string username = GetAuthenticatedUsername(headers);
 
@@ -747,8 +774,19 @@
   {
     try
     {
-      MongooseServer* server = reinterpret_cast<MongooseServer*>(request->user_data);
+      void* that = NULL;
+
+#if ORTHANC_ENABLE_MONGOOSE == 1
+      that = request->user_data;
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+      // https://github.com/civetweb/civetweb/issues/409
+      that = mg_get_user_data(mg_get_context(connection));
+#else
+#error
+#endif                              
       
+      MongooseServer* server = reinterpret_cast<MongooseServer*>(that);
+
       if (server == NULL)
       {
         MongooseOutputStream stream(connection);
@@ -756,7 +794,7 @@
         output.SendStatus(HttpStatus_500_InternalServerError);
         return;
       }
-      
+
       MongooseOutputStream stream(connection);
       HttpOutput output(stream, server->IsKeepAliveEnabled());
       HttpMethod method = HttpMethod_Get;
@@ -846,7 +884,7 @@
 #elif MONGOOSE_USE_CALLBACKS == 1
   static int Callback(struct mg_connection *connection)
   {
-    struct mg_request_info *request = mg_get_request_info(connection);
+    const struct mg_request_info *request = mg_get_request_info(connection);
 
     ProtectedCallback(connection, request);
 
@@ -906,6 +944,14 @@
 
   void MongooseServer::Start()
   {
+#if ORTHANC_ENABLE_MONGOOSE == 1
+    LOG(INFO) << "Starting embedded Web server using Mongoose";
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+    LOG(INFO) << "Starting embedded Web server using Civetweb";
+#else
+#error
+#endif  
+
     if (!IsRunning())
     {
       std::string port = boost::lexical_cast<std::string>(port_);
--- a/NEWS	Sat Aug 26 12:18:45 2017 +0200
+++ b/NEWS	Mon Aug 28 14:09:24 2017 +0200
@@ -2,6 +2,7 @@
 ===============================
 
 * New security-related options: "DicomAlwaysAllowEcho"
+* Experimental support of actively maintained Civetweb to replace Mongoose 3.8
 * Fix issue 64 (OpenBSD support)
 * Fix static compilation of DCMTK 3.6.2 on Fedora
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/CMake/CivetwebConfiguration.cmake	Mon Aug 28 14:09:24 2017 +0200
@@ -0,0 +1,57 @@
+if (STATIC_BUILD OR NOT USE_SYSTEM_CIVETWEB)
+  set(CIVETWEB_SOURCES_DIR ${CMAKE_BINARY_DIR}/civetweb-1.9.1)
+  set(CIVETWEB_URL "http://www.orthanc-server.com/downloads/third-party/civetweb-1.9.1.tar.gz")
+  set(CIVETWEB_MD5 "c713f7336582d1a78897971260c67c2a")
+
+  DownloadPackage(${CIVETWEB_MD5} ${CIVETWEB_URL} "${CIVETWEB_SOURCES_DIR}")
+
+  include_directories(
+    ${CIVETWEB_SOURCES_DIR}/src
+    )
+
+  set(CIVETWEB_SOURCES
+    ${CIVETWEB_SOURCES_DIR}/src/civetweb.c
+    )
+
+
+  if (ENABLE_SSL)
+    add_definitions(
+      -DNO_SSL_DL=1
+      )
+    if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
+        ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
+      link_libraries(dl)
+    endif()
+
+  else()
+    add_definitions(
+      -DNO_SSL=1   # Remove SSL support from civetweb
+      )
+  endif()
+
+
+  if (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND
+      CMAKE_COMPILER_IS_GNUCXX)
+    # This is a patch for MinGW64
+    add_definitions(-D_TIMESPEC_DEFINED=1)
+  endif()
+
+  source_group(ThirdParty\\Civetweb REGULAR_EXPRESSION ${CIVETWEB_SOURCES_DIR}/.*)
+
+else()
+  include(CMakePushCheckState)
+  
+  CHECK_INCLUDE_FILE_CXX(civetweb.h HAVE_CIVETWEB_H)
+  if (NOT HAVE_CIVETWEB_H)
+    message(FATAL_ERROR "Please install the libcivetweb-devel package")
+  endif()
+
+  cmake_reset_check_state()
+  set(CMAKE_REQUIRED_LIBRARIES dl pthread)
+  CHECK_LIBRARY_EXISTS(civetweb mg_start "" HAVE_CIVETWEB_LIB)
+  if (NOT HAVE_CIVETWEB_LIB)
+    message(FATAL_ERROR "Please install the libcivetweb-devel package")
+  endif()
+
+  link_libraries(civetweb)
+endif()
--- a/TODO	Sat Aug 26 12:18:45 2017 +0200
+++ b/TODO	Mon Aug 28 14:09:24 2017 +0200
@@ -24,9 +24,6 @@
 Dependencies
 ============
 
-* Switch to CivetWeb because of licensing issues with recent
-  versions of Mongoose (versions > 3.8 are GPLv2 and not GPLv2+):
-  https://www.mail-archive.com/mongoose-users@googlegroups.com/msg00625.html
 * Switch from libiconv to libICU (http://site.icu-project.org/download),
   as recommended by Boost:
   http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/building_boost_locale.html