# HG changeset patch # User Sebastien Jodogne # Date 1604653128 -3600 # Node ID 6919242d22658593ce8e3e786a02342960b2b694 # Parent b30a8de92ad931129d627d03e997cd7cfa338ff9 Fix keep-alive in the embedded HTTP server by setting the "Keep-Alive" HTTP header diff -r b30a8de92ad9 -r 6919242d2265 NEWS --- 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 diff -r b30a8de92ad9 -r 6919242d2265 OrthancFramework/Sources/HttpServer/HttpOutput.cpp --- 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(CIVETWEB_KEEP_ALIVE_TIMEOUT_SECONDS) + "\r\n"); } else { diff -r b30a8de92ad9 -r 6919242d2265 OrthancFramework/Sources/HttpServer/HttpServer.cpp --- 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(port_); std::string numThreads = boost::lexical_cast(threadsCount_); std::string requestTimeoutMilliseconds = boost::lexical_cast(requestTimeout_ * 1000); + std::string keepAliveTimeoutMilliseconds = boost::lexical_cast(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