# HG changeset patch # User Sebastien Jodogne # Date 1547745863 -3600 # Node ID 5a3b961e9524ef5f5762d1cc908cade7f7ba9611 # Parent f948deef53d9b14774381c31e71e8273e4463f38 New configuration option: 'TcpNoDelay' to disable Nagle's algorithm in HTTP server diff -r f948deef53d9 -r 5a3b961e9524 Core/HttpServer/MongooseServer.cpp --- a/Core/HttpServer/MongooseServer.cpp Thu Jan 17 16:26:44 2019 +0100 +++ b/Core/HttpServer/MongooseServer.cpp Thu Jan 17 18:24:23 2019 +0100 @@ -934,6 +934,7 @@ exceptionFormatter_ = NULL; realm_ = ORTHANC_REALM; threadsCount_ = 50; // Default value in mongoose + tcpNoDelay_ = true; #if ORTHANC_ENABLE_SSL == 1 // Check for the Heartbleed exploit @@ -994,8 +995,10 @@ #if ORTHANC_ENABLE_CIVETWEB == 1 // Disable TCP Nagle's algorithm to maximize speed (this - // option is not available in Mongoose) - "tcp_nodelay", "1", + // option is not available in Mongoose). + // https://groups.google.com/d/topic/civetweb/35HBR9seFjU/discussion + // https://eklitzke.org/the-caveats-of-tcp-nodelay + "tcp_nodelay", (tcpNoDelay_ ? "1" : "0"), #endif // Set the number of threads @@ -1086,6 +1089,13 @@ Stop(); keepAlive_ = enabled; LOG(INFO) << "HTTP keep alive is " << (enabled ? "enabled" : "disabled"); + +#if ORTHANC_ENABLE_MONGOOSE == 1 + if (enabled) + { + LOG(WARNING) << "You should disable HTTP keep alive, as you are using Mongoose"; + } +#endif } @@ -1162,4 +1172,13 @@ Stop(); threadsCount_ = threads; } + + + void MongooseServer::SetTcpNoDelay(bool tcpNoDelay) + { + Stop(); + tcpNoDelay_ = tcpNoDelay; + LOG(INFO) << "TCP_NODELAY for the HTTP sockets is set to " + << (tcpNoDelay ? "true" : "false"); + } } diff -r f948deef53d9 -r 5a3b961e9524 Core/HttpServer/MongooseServer.h --- a/Core/HttpServer/MongooseServer.h Thu Jan 17 16:26:44 2019 +0100 +++ b/Core/HttpServer/MongooseServer.h Thu Jan 17 18:24:23 2019 +0100 @@ -97,6 +97,7 @@ IHttpExceptionFormatter* exceptionFormatter_; std::string realm_; unsigned int threadsCount_; + bool tcpNoDelay_; bool IsRunning() const; @@ -206,5 +207,13 @@ { return threadsCount_; } + + // New in Orthanc 1.5.2, not available for Mongoose + void SetTcpNoDelay(bool tcpNoDelay); + + bool IsTcpNoDelay() const + { + return tcpNoDelay_; + } }; } diff -r f948deef53d9 -r 5a3b961e9524 NEWS --- a/NEWS Thu Jan 17 16:26:44 2019 +0100 +++ b/NEWS Thu Jan 17 18:24:23 2019 +0100 @@ -1,6 +1,11 @@ Pending changes in the mainline =============================== +General +------- + +* New configuration option: "TcpNoDelay" to disable Nagle's algorithm in HTTP server + Maintenance ----------- diff -r f948deef53d9 -r 5a3b961e9524 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Thu Jan 17 16:26:44 2019 +0100 +++ b/OrthancServer/main.cpp Thu Jan 17 18:24:23 2019 +0100 @@ -800,6 +800,14 @@ MongooseServer httpServer; bool httpDescribeErrors; +#if ORTHANC_ENABLE_MONGOOSE == 1 + const bool defaultKeepAlive = false; +#elif ORTHANC_ENABLE_CIVETWEB == 1 + const bool defaultKeepAlive = true; +#else +# error "Either Mongoose or Civetweb must be enabled to compile this file" +#endif + { OrthancConfiguration::ReaderLock lock; @@ -809,9 +817,10 @@ //httpServer.SetThreadsCount(50); httpServer.SetPortNumber(lock.GetConfiguration().GetUnsignedIntegerParameter("HttpPort", 8042)); httpServer.SetRemoteAccessAllowed(lock.GetConfiguration().GetBooleanParameter("RemoteAccessAllowed", false)); - httpServer.SetKeepAliveEnabled(lock.GetConfiguration().GetBooleanParameter("KeepAlive", true)); + httpServer.SetKeepAliveEnabled(lock.GetConfiguration().GetBooleanParameter("KeepAlive", defaultKeepAlive)); httpServer.SetHttpCompressionEnabled(lock.GetConfiguration().GetBooleanParameter("HttpCompressionEnabled", true)); httpServer.SetAuthenticationEnabled(lock.GetConfiguration().GetBooleanParameter("AuthenticationEnabled", false)); + httpServer.SetTcpNoDelay(lock.GetConfiguration().GetBooleanParameter("TcpNoDelay", true)); lock.GetConfiguration().SetupRegisteredUsers(httpServer); diff -r f948deef53d9 -r 5a3b961e9524 Resources/Configuration.json --- a/Resources/Configuration.json Thu Jan 17 16:26:44 2019 +0100 +++ b/Resources/Configuration.json Thu Jan 17 18:24:23 2019 +0100 @@ -349,11 +349,20 @@ // Enable or disable HTTP Keep-Alive (persistent HTTP // connections). Setting this option to "true" prevents Orthanc // issue #32 ("HttpServer does not support multiple HTTP requests in - // the same TCP stream"), but can slow down HTTP clients that do not - // support persistent connections. The default behavior used to be - // "false" in Orthanc <= 1.5.1. + // the same TCP stream"), but can possibly slow down HTTP clients + // that do not support persistent connections. The default behavior + // used to be "false" in Orthanc <= 1.5.1. Setting this option to + // "false" is also recommended if Orthanc is compiled against + // Mongoose. "KeepAlive" : true, + // Enable or disable Nagle's algorithm. Only taken into + // consideration if Orthanc is compiled to use CivetWeb. Experiments + // show that best performance can be obtained by setting both + // "KeepAlive" and "TcpNoDelay" to "true". Beware however of + // caveats: https://eklitzke.org/the-caveats-of-tcp-nodelay + "TcpNoDelay" : true, + // If this option is set to "false", Orthanc will run in index-only // mode. The DICOM files will not be stored on the drive. Note that // this option might prevent the upgrade to newer versions of Orthanc.