changeset 4301:6919242d2265

Fix keep-alive in the embedded HTTP server by setting the "Keep-Alive" HTTP header
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 06 Nov 2020 09:58:48 +0100
parents b30a8de92ad9
children 4c91fbede7d2
files NEWS OrthancFramework/Sources/HttpServer/HttpOutput.cpp OrthancFramework/Sources/HttpServer/HttpServer.cpp
diffstat 3 files changed, 28 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Nov 05 19:33:18 2020 +0100
+++ b/NEWS	Fri Nov 06 09:58:48 2020 +0100
@@ -5,7 +5,7 @@
 -------
 
 * Logging categories (cf. command-line options starting with "--verbose-" and "--trace=")
-* Command-line option "--trace-dicom" can be used to access debug information from DCMTK
+* New command-line option "--trace-dicom" to access full debug information from DCMTK
 
 REST API
 --------
@@ -17,7 +17,8 @@
 
 * C-GET SCP: Fix responses and handling of cancel
 * Fix decoding sequence if "BuiltinDecoderTranscoderOrder" is "Before"
-* REST API returns 404 error if deleting an inexistent peer or modality
+* Fix keep-alive in the embedded HTTP server by setting the "Keep-Alive" HTTP header
+* REST API now returns 404 error if deleting an inexistent peer or modality
 * Upgraded dependencies for static builds (notably on Windows and LSB):
   - civetweb 1.13
 
--- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp	Thu Nov 05 19:33:18 2020 +0100
+++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp	Fri Nov 06 09:58:48 2020 +0100
@@ -174,6 +174,21 @@
       if (keepAlive_)
       {
         s += "Connection: keep-alive\r\n";
+
+        /**
+         * [LIFY-2311] The "Keep-Alive" HTTP header was missing in
+         * Orthanc <= 1.8.0, which notably caused failures if
+         * uploading DICOM instances by applying Java's
+         * "org.apache.http.client.methods.HttpPost()" on "/instances"
+         * URI, if "PoolingHttpClientConnectionManager" was in used. A
+         * workaround was to manually set a timeout for the keep-alive
+         * client to, say, 200 milliseconds, by using
+         * "HttpClients.custom().setKeepAliveStrategy((httpResponse,httpContext)->200)".
+         * Note that the "timeout" value can only be integer in the
+         * HTTP header, so we can't use the milliseconds granularity.
+         **/
+        s += ("Keep-Alive: timeout=" +
+              boost::lexical_cast<std::string>(CIVETWEB_KEEP_ALIVE_TIMEOUT_SECONDS) + "\r\n");
       }
       else
       {
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Thu Nov 05 19:33:18 2020 +0100
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Fri Nov 06 09:58:48 2020 +0100
@@ -1543,6 +1543,7 @@
       std::string port = boost::lexical_cast<std::string>(port_);
       std::string numThreads = boost::lexical_cast<std::string>(threadsCount_);
       std::string requestTimeoutMilliseconds = boost::lexical_cast<std::string>(requestTimeout_ * 1000);
+      std::string keepAliveTimeoutMilliseconds = boost::lexical_cast<std::string>(CIVETWEB_KEEP_ALIVE_TIMEOUT_SECONDS * 1000);
 
       if (ssl_)
       {
@@ -1561,9 +1562,16 @@
       options.push_back(keepAlive_ ? "yes" : "no");
 
 #if ORTHANC_ENABLE_CIVETWEB == 1
-      // https://github.com/civetweb/civetweb/blob/master/docs/UserManual.md#enable_keep_alive-no
+      /**
+       * The "keep_alive_timeout_ms" cannot use milliseconds, as the
+       * value of "timeout" in the HTTP header "Keep-Alive" must be
+       * expressed in seconds (at least for the Java client).
+       * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive
+       * https://github.com/civetweb/civetweb/blob/master/docs/UserManual.md#enable_keep_alive-no
+       * https://github.com/civetweb/civetweb/blob/master/docs/UserManual.md#keep_alive_timeout_ms-500-or-0
+       **/
       options.push_back("keep_alive_timeout_ms");
-      options.push_back(keepAlive_ ? "500" : "0");
+      options.push_back(keepAlive_ ? keepAliveTimeoutMilliseconds.c_str() : "0");
 #endif
 
 #if ORTHANC_ENABLE_CIVETWEB == 1