[med-svn] [Git][med-team/orthanc][upstream] New upstream version 1.5.3+dfsg

Sebastien Jodogne gitlab at salsa.debian.org
Sat Jan 26 07:48:39 GMT 2019


Sebastien Jodogne pushed to branch upstream at Debian Med / orthanc


Commits:
93758a64 by jodogne-guest at 2019-01-26T06:59:10Z
New upstream version 1.5.3+dfsg
- - - - -


28 changed files:

- .hg_archival.txt
- Core/DicomNetworking/DicomFindAnswers.cpp
- Core/DicomParsing/FromDcmtkBridge.cpp
- Core/HttpServer/FilesystemHttpSender.h
- Core/HttpServer/HttpOutput.cpp
- Core/HttpServer/HttpServer.cpp
- Core/HttpServer/IHttpOutputStream.h
- Core/HttpServer/StringHttpOutput.h
- Core/JobsEngine/JobsRegistry.cpp
- NEWS
- OrthancExplorer/explorer.html
- OrthancExplorer/file-upload.js
- + OrthancExplorer/orthanc-logo.png
- OrthancServer/OrthancFindRequestHandler.cpp
- OrthancServer/OrthancMoveRequestHandler.cpp
- OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
- OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
- OrthancServer/OrthancRestApi/OrthancRestResources.cpp
- OrthancServer/Search/DatabaseLookup.h
- OrthancServer/ServerContext.cpp
- OrthancServer/ServerContext.h
- OrthancServer/main.cpp
- Resources/CMake/Compiler.cmake
- Resources/CMake/OrthancFrameworkParameters.cmake
- Resources/Configuration.json
- Resources/DownloadOrthancFramework.cmake
- Resources/Patches/civetweb-1.11.patch
- TODO


Changes:

=====================================
.hg_archival.txt
=====================================
@@ -1,6 +1,6 @@
 repo: 3959d33612ccaadc0d4d707227fbed09ac35e5fe
-node: 169e0920634088ba788ac5816ec96c2b1739e1c8
-branch: Orthanc-1.5.2
+node: 6f5e38ec1f120b8c0ac9c7bfaeafd50ef819d863
+branch: Orthanc-1.5.3
 latesttag: dcmtk-3.6.1
-latesttagdistance: 660
-changessincelatesttag: 768
+latesttagdistance: 677
+changessincelatesttag: 786


=====================================
Core/DicomNetworking/DicomFindAnswers.cpp
=====================================
@@ -150,7 +150,35 @@ namespace Orthanc
 
   DcmDataset* DicomFindAnswers::ExtractDcmDataset(size_t index) const
   {
-    return new DcmDataset(*GetAnswer(index).GetDcmtkObject().getDataset());
+    // As "DicomFindAnswers" stores its content using class
+    // "ParsedDicomFile" (that internally uses "DcmFileFormat" from
+    // DCMTK), the dataset can contain tags that are reserved if
+    // storing the media on the disk, notably tag
+    // "MediaStorageSOPClassUID" (0002,0002). In this function, we
+    // remove all those tags whose group is below 0x0008. The
+    // resulting data set is clean for emission in the C-FIND SCP.
+
+    // http://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.4.html#sect_C.4.1.1.3
+    // https://groups.google.com/d/msg/orthanc-users/D3kpPuX8yV0/_zgHOzkMEQAJ
+
+    DcmDataset& source = *GetAnswer(index).GetDcmtkObject().getDataset();
+
+    std::auto_ptr<DcmDataset> target(new DcmDataset);
+
+    for (unsigned long i = 0; i < source.card(); i++)
+    {
+      const DcmElement* element = source.getElement(i);
+      assert(element != NULL);
+
+      if (element != NULL &&
+          element->getTag().getGroup() >= 0x0008 &&
+          element->getTag().getElement() != 0x0000)
+      {
+        target->insert(dynamic_cast<DcmElement*>(element->clone()));
+      }
+    }
+    
+    return target.release();
   }
 
 


=====================================
Core/DicomParsing/FromDcmtkBridge.cpp
=====================================
@@ -2055,7 +2055,7 @@ DCMTK_TO_CTYPE_CONVERTER(DcmtkToFloat64Converter, Float64, DcmFloatingPointDoubl
     if (output.type() != Json::objectValue)
     {
       throw OrthancException(ErrorCode_LuaBadOutput,
-                             "Lua: IncomingFindRequestFilter must return a table");
+                             "Lua: The script must return a table");
     }
 
     Json::Value::Members members = output.getMemberNames();
@@ -2065,7 +2065,7 @@ DCMTK_TO_CTYPE_CONVERTER(DcmtkToFloat64Converter, Float64, DcmFloatingPointDoubl
       if (output[members[i]].type() != Json::stringValue)
       {
         throw OrthancException(ErrorCode_LuaBadOutput,
-                               "Lua: IncomingFindRequestFilter must return a table "
+                               "Lua: The script must return a table "
                                "mapping names of DICOM tags to strings");
       }
 


=====================================
Core/HttpServer/FilesystemHttpSender.h
=====================================
@@ -61,6 +61,13 @@ namespace Orthanc
       Initialize(path);
     }
 
+    FilesystemHttpSender(const std::string& path,
+                         MimeType contentType)
+    {
+      SetContentType(contentType);
+      Initialize(path);
+    }
+
     FilesystemHttpSender(const FilesystemStorage& storage,
                          const std::string& uuid)
     {


=====================================
Core/HttpServer/HttpOutput.cpp
=====================================
@@ -407,12 +407,6 @@ namespace Orthanc
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
 
-    if (keepAlive_)
-    {
-      throw OrthancException(ErrorCode_NotImplemented,
-                             "Multipart answers are not implemented together with keep-alive connections");
-    }
-
     if (state_ != State_WritingHeader)
     {
       throw OrthancException(ErrorCode_BadSequenceOfCalls);
@@ -428,6 +422,20 @@ namespace Orthanc
 
     std::string header = "HTTP/1.1 200 OK\r\n";
 
+    if (keepAlive_)
+    {
+#if ORTHANC_ENABLE_MONGOOSE == 1
+      throw OrthancException(ErrorCode_NotImplemented,
+                             "Multipart answers are not implemented together "
+                             "with keep-alive connections if using Mongoose");
+#else
+      // Turn off Keep-Alive for multipart answers
+      // https://github.com/civetweb/civetweb/issues/727
+      stream_.DisableKeepAlive();
+      header += "Connection: close\r\n";
+#endif
+    }
+
     // Possibly add the cookies
     for (std::list<std::string>::const_iterator
            it = headers_.begin(); it != headers_.end(); ++it)


=====================================
Core/HttpServer/HttpServer.cpp
=====================================
@@ -108,6 +108,16 @@ namespace Orthanc
       {
         // Ignore this
       }
+
+      virtual void DisableKeepAlive()
+      {
+#if ORTHANC_ENABLE_MONGOOSE == 1
+        throw OrthancException(ErrorCode_NotImplemented,
+                               "Only available if using CivetWeb");
+#elif ORTHANC_ENABLE_CIVETWEB == 1
+        mg_disable_keep_alive(connection_);
+#endif
+      }
     };
 
 


=====================================
Core/HttpServer/IHttpOutputStream.h
=====================================
@@ -50,5 +50,9 @@ namespace Orthanc
     virtual void OnHttpStatusReceived(HttpStatus status) = 0;
 
     virtual void Send(bool isHeader, const void* buffer, size_t length) = 0;
+
+    // Disable HTTP keep alive for this single HTTP connection. Must
+    // be called before sending the "HTTP/1.1 200 OK" header.
+    virtual void DisableKeepAlive() = 0;
   };
 }


=====================================
Core/HttpServer/StringHttpOutput.h
=====================================
@@ -54,6 +54,10 @@ namespace Orthanc
 
     virtual void Send(bool isHeader, const void* buffer, size_t length);
 
+    virtual void DisableKeepAlive()
+    {
+    }
+
     void GetOutput(std::string& output);
   };
 }


=====================================
Core/JobsEngine/JobsRegistry.cpp
=====================================
@@ -755,9 +755,11 @@ namespace Orthanc
       {
         if (!GetStateInternal(state, id))
         {
-          // Job has finished and has been lost (should not happen)
-          state = JobState_Failure;
-          break;
+          // Job has finished and has been lost (typically happens if
+          // "JobsHistorySize" is 0)
+          throw OrthancException(ErrorCode_InexistentItem,
+                                 "Cannot retrieve the status of the job, "
+                                 "make sure that \"JobsHistorySize\" is not 0");
         }
         else if (state == JobState_Failure)
         {


=====================================
NEWS
=====================================
@@ -2,6 +2,24 @@ Pending changes in the mainline
 ===============================
 
 
+Version 1.5.3 (2019-01-25)
+==========================
+
+General
+-------
+
+* New configuration option: "SaveJobs" to specify whether jobs are stored in the database
+
+Maintenance
+-----------
+
+* Don't return tags whose group is below 0x0008 in C-FIND SCP answers
+* Fix compatibility with DICOMweb plugin (allow multipart answers over HTTP Keep-Alive)
+* Fix issue #73 (/modalities/{modalityId}/store raises 500 errors instead of 404)
+* Fix issue #90 (C-Find shall match missing tags to null/empty string)
+* Fix issue #119 (/patients/.../archive returns a 500 when JobsHistorySize is 0)
+* Fix issue #128 (Asynchronous C-MOVE: invalid number of remaining sub-operations)
+
 
 Version 1.5.2 (2019-01-18)
 ==========================
@@ -26,7 +44,7 @@ Plugins
 Maintenance
 -----------
 
-* Don't consider tags whose group is below 0x0008 in C-FIND SCP
+* Ignore tags whose group is below 0x0008 in C-FIND SCP requests
 * Compatibility with DCMTK 3.6.4
 * Fix issue #21 (DICOM files missing after uploading with Firefox)
 * Fix issue #32 (HTTP keep-alive is now enabled by default)


=====================================
OrthancExplorer/explorer.html
=====================================
@@ -50,6 +50,14 @@
       </div>
     </div>
     <div data-role="content">
+      <div data-role="content" id="content" style="padding:0px">
+        <p align="center">
+          <a href="http://www.orthanc-server.com/" target="_blank" alt="Orthanc homepage">
+            <img src="orthanc-logo.png" alt="Orthanc" style="max-width:100%" />
+          </a>
+        </p>
+      </div>
+      
       <form data-ajax="false" id="lookup-form">
         <div data-role="fieldcontain">
           <label for="lookup-patient-id">Patient ID:</label>


=====================================
OrthancExplorer/file-upload.js
=====================================
@@ -1,8 +1,15 @@
 var pendingUploads = [];
 var currentUpload = 0;
 var totalUpload = 0;
+var alreadyInitialized = false; // trying to debug Orthanc issue #1
 
 $(document).ready(function() {
+  if (alreadyInitialized) {
+    console.log("Orthanc issue #1: the fileupload has been initialized twice !");
+  } else {
+    alreadyInitialized = true;
+  }
+  
   // Initialize the jQuery File Upload widget:
   $('#fileupload').fileupload({
     //dataType: 'json',
@@ -27,7 +34,7 @@ $(document).ready(function() {
       $('#progress .label').text('Failure');
     })
     .bind('fileuploaddrop', function (e, data) {
-      console.log("dropped " + data.files.length + " files");
+      console.log("dropped " + data.files.length + " files: ", data);
       appendFilesToUploadList(data.files);
     })
     .bind('fileuploadsend', function (e, data) {


=====================================
OrthancExplorer/orthanc-logo.png
=====================================
Binary files /dev/null and b/OrthancExplorer/orthanc-logo.png differ


=====================================
OrthancServer/OrthancFindRequestHandler.cpp
=====================================
@@ -639,7 +639,7 @@ namespace Orthanc
       std::string value = element.GetValue().GetContent();
       if (value.size() == 0)
       {
-        // An empty string corresponds to a "*" wildcard constraint, so we ignore it
+        // An empty string corresponds to an universal constraint, so we ignore it
         continue;
       }
 


=====================================
OrthancServer/OrthancMoveRequestHandler.cpp
=====================================
@@ -125,6 +125,7 @@ namespace Orthanc
       ServerContext&                        context_;
       std::auto_ptr<DicomModalityStoreJob>  job_;
       size_t                                position_;
+      size_t                                countInstances_;
       
     public:
       AsynchronousMove(ServerContext& context,
@@ -156,6 +157,8 @@ namespace Orthanc
         std::list<std::string> tmp;
         context_.GetIndex().GetChildInstances(tmp, publicId);
 
+        countInstances_ = tmp.size();
+
         job_->Reserve(tmp.size());
 
         for (std::list<std::string>::iterator it = tmp.begin(); it != tmp.end(); ++it)
@@ -166,20 +169,23 @@ namespace Orthanc
 
       virtual unsigned int GetSubOperationCount() const
       {
-        return 1;
+        return countInstances_;
       }
 
       virtual Status DoNext()
       {
-        if (position_ == 0)
+        if (position_ >= countInstances_)
         {
-          context_.GetJobsEngine().GetRegistry().Submit(job_.release(), 0 /* priority */);
-          return Status_Success;
+          return Status_Failure;
         }
-        else
+        
+        if (position_ == 0)
         {
-          return Status_Failure;
+          context_.GetJobsEngine().GetRegistry().Submit(job_.release(), 0 /* priority */);
         }
+        
+        position_ ++;
+        return Status_Success;
       }
     };
   }


=====================================
OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
=====================================
@@ -144,8 +144,7 @@ namespace Orthanc
           (publicContent, job.release(), priority))
       {
         // The archive is now created: Prepare the sending of the ZIP file
-        FilesystemHttpSender sender(tmp->GetPath());
-        sender.SetContentType(MimeType_Gzip);
+        FilesystemHttpSender sender(tmp->GetPath(), MimeType_Zip);
         sender.SetContentFilename(filename);
 
         // Send the ZIP


=====================================
OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
=====================================
@@ -813,7 +813,7 @@ namespace Orthanc
    * DICOM C-Store SCU
    ***************************************************************************/
 
-  static bool GetInstancesToExport(Json::Value& otherArguments,
+  static void GetInstancesToExport(Json::Value& otherArguments,
                                    SetOfInstancesJob& job,
                                    const std::string& remote,
                                    RestApiPostCall& call)
@@ -834,7 +834,7 @@ namespace Orthanc
     else if (!call.ParseJsonRequest(request))
     {
       // Bad JSON request
-      return false;
+      throw OrthancException(ErrorCode_BadFileFormat, "Must provide a JSON value");
     }
 
     if (request.isString())
@@ -843,6 +843,11 @@ namespace Orthanc
       request = Json::arrayValue;
       request.append(item);
     }
+    else if (!request.isArray() &&
+             !request.isObject())
+    {
+      throw OrthancException(ErrorCode_BadFileFormat, "Must provide a JSON object, or a JSON array of strings");
+    }
 
     const Json::Value* resources;
     if (request.isArray())
@@ -854,13 +859,15 @@ namespace Orthanc
       if (request.type() != Json::objectValue ||
           !request.isMember(KEY_RESOURCES))
       {
-        return false;
+        throw OrthancException(ErrorCode_BadFileFormat,
+                               "Missing field in JSON: \"" + std::string(KEY_RESOURCES) + "\"");
       }
 
       resources = &request[KEY_RESOURCES];
       if (!resources->isArray())
       {
-        return false;
+        throw OrthancException(ErrorCode_BadFileFormat,
+                               "JSON field \"" + std::string(KEY_RESOURCES) + "\" must contain an array");
       }
 
       // Copy the remaining arguments
@@ -882,24 +889,24 @@ namespace Orthanc
     {
       if (!(*resources) [i].isString())
       {
-        return false;
+        throw OrthancException(ErrorCode_BadFileFormat,
+                               "Resources to be exported must be specified as a JSON array of strings");
       }
 
       std::string stripped = Toolbox::StripSpaces((*resources) [i].asString());
       if (!Toolbox::IsSHA1(stripped))
       {
-        return false;
+        throw OrthancException(ErrorCode_BadFileFormat,
+                               "This string is not a valid Orthanc identifier: " + stripped);
       }
 
+      context.AddChildInstances(job, stripped);
+
       if (logExportedResources)
       {
         context.GetIndex().LogExportedResource(stripped, remote);
       }
-
-      context.AddChildInstances(job, stripped);
     }
-
-    return true;
   }
 
 
@@ -912,26 +919,25 @@ namespace Orthanc
     Json::Value request;
     std::auto_ptr<DicomModalityStoreJob> job(new DicomModalityStoreJob(context));
 
-    if (GetInstancesToExport(request, *job, remote, call))
-    {
-      std::string localAet = Toolbox::GetJsonStringField
-        (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle());
-      std::string moveOriginatorAET = Toolbox::GetJsonStringField
-        (request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle());
-      int moveOriginatorID = Toolbox::GetJsonIntegerField
-        (request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */);
+    GetInstancesToExport(request, *job, remote, call);
 
-      job->SetLocalAet(localAet);
-      job->SetRemoteModality(MyGetModalityUsingSymbolicName(remote));
+    std::string localAet = Toolbox::GetJsonStringField
+      (request, "LocalAet", context.GetDefaultLocalApplicationEntityTitle());
+    std::string moveOriginatorAET = Toolbox::GetJsonStringField
+      (request, "MoveOriginatorAet", context.GetDefaultLocalApplicationEntityTitle());
+    int moveOriginatorID = Toolbox::GetJsonIntegerField
+      (request, "MoveOriginatorID", 0 /* By default, not a C-MOVE */);
 
-      if (moveOriginatorID != 0)
-      {
-        job->SetMoveOriginator(moveOriginatorAET, moveOriginatorID);
-      }
+    job->SetLocalAet(localAet);
+    job->SetRemoteModality(MyGetModalityUsingSymbolicName(remote));
 
-      OrthancRestApi::GetApi(call).SubmitCommandsJob
-        (call, job.release(), true /* synchronous by default */, request);
+    if (moveOriginatorID != 0)
+    {
+      job->SetMoveOriginator(moveOriginatorAET, moveOriginatorID);
     }
+
+    OrthancRestApi::GetApi(call).SubmitCommandsJob
+      (call, job.release(), true /* synchronous by default */, request);
   }
 
 
@@ -1059,22 +1065,21 @@ namespace Orthanc
     Json::Value request;
     std::auto_ptr<OrthancPeerStoreJob> job(new OrthancPeerStoreJob(context));
 
-    if (GetInstancesToExport(request, *job, remote, call))
-    {
-      OrthancConfiguration::ReaderLock lock;
+    GetInstancesToExport(request, *job, remote, call);
+    
+    OrthancConfiguration::ReaderLock lock;
 
-      WebServiceParameters peer;
-      if (lock.GetConfiguration().LookupOrthancPeer(peer, remote))
-      {
-        job->SetPeer(peer);    
-        OrthancRestApi::GetApi(call).SubmitCommandsJob
-          (call, job.release(), true /* synchronous by default */, request);
-      }
-      else
-      {
-        throw OrthancException(ErrorCode_UnknownResource,
-                               "No peer with symbolic name: " + remote);
-      }
+    WebServiceParameters peer;
+    if (lock.GetConfiguration().LookupOrthancPeer(peer, remote))
+    {
+      job->SetPeer(peer);    
+      OrthancRestApi::GetApi(call).SubmitCommandsJob
+        (call, job.release(), true /* synchronous by default */, request);
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_UnknownResource,
+                             "No peer with symbolic name: " + remote);
     }
   }
 


=====================================
OrthancServer/OrthancRestApi/OrthancRestResources.cpp
=====================================
@@ -1415,9 +1415,16 @@ namespace Orthanc
                                  "Tag \"" + members[i] + "\" should be associated with a string");
         }
 
-        query.AddRestConstraint(FromDcmtkBridge::ParseTag(members[i]), 
-                                request[KEY_QUERY][members[i]].asString(),
-                                caseSensitive, true);
+        const std::string value = request[KEY_QUERY][members[i]].asString();
+
+        if (!value.empty())
+        {
+          // An empty string corresponds to an universal constraint,
+          // so we ignore it. This mimics the behavior of class
+          // "OrthancFindRequestHandler"
+          query.AddRestConstraint(FromDcmtkBridge::ParseTag(members[i]), 
+                                  value, caseSensitive, true);
+        }
       }
 
       FindVisitor visitor;


=====================================
OrthancServer/Search/DatabaseLookup.h
=====================================
@@ -49,6 +49,9 @@ namespace Orthanc
                                     const std::string& dicomQuery,
                                     bool caseSensitive,
                                     bool mandatoryTag);
+
+    void AddConstraint(DicomTagConstraint* constraint);  // Takes ownership
+
   public:
     DatabaseLookup()
     {
@@ -68,8 +71,6 @@ namespace Orthanc
 
     const DicomTagConstraint& GetConstraint(size_t index) const;
 
-    void AddConstraint(DicomTagConstraint* constraint);  // Takes ownership
-
     bool IsMatch(const DicomMap& value) const;
 
     bool IsMatch(DcmItem& item,


=====================================
OrthancServer/ServerContext.cpp
=====================================
@@ -196,21 +196,24 @@ namespace Orthanc
 
   void ServerContext::SaveJobsEngine()
   {
-    VLOG(1) << "Serializing the content of the jobs engine";
-    
-    try
+    if (saveJobs_)
     {
-      Json::Value value;
-      jobsEngine_.GetRegistry().Serialize(value);
+      VLOG(1) << "Serializing the content of the jobs engine";
+    
+      try
+      {
+        Json::Value value;
+        jobsEngine_.GetRegistry().Serialize(value);
 
-      Json::FastWriter writer;
-      std::string serialized = writer.write(value);
+        Json::FastWriter writer;
+        std::string serialized = writer.write(value);
 
-      index_.SetGlobalProperty(GlobalProperty_JobsRegistry, serialized);
-    }
-    catch (OrthancException& e)
-    {
-      LOG(ERROR) << "Cannot serialize the jobs engine: " << e.What();
+        index_.SetGlobalProperty(GlobalProperty_JobsRegistry, serialized);
+      }
+      catch (OrthancException& e)
+      {
+        LOG(ERROR) << "Cannot serialize the jobs engine: " << e.What();
+      }
     }
   }
 
@@ -245,6 +248,7 @@ namespace Orthanc
         new SharedArchive(lock.GetConfiguration().GetUnsignedIntegerParameter("MediaArchiveSize", 1)));
       defaultLocalAet_ = lock.GetConfiguration().GetStringParameter("DicomAet", "ORTHANC");
       jobsEngine_.SetWorkersCount(lock.GetConfiguration().GetUnsignedIntegerParameter("ConcurrentJobs", 2));
+      saveJobs_ = lock.GetConfiguration().GetBooleanParameter("SaveJobs", true);
     }
 
     jobsEngine_.SetThreadSleep(unitTesting ? 20 : 200);


=====================================
OrthancServer/ServerContext.h
=====================================
@@ -216,6 +216,7 @@ namespace Orthanc
     std::auto_ptr<SharedArchive>  queryRetrieveArchive_;
     std::string defaultLocalAet_;
     OrthancHttpHandler  httpHandler_;
+    bool saveJobs_;
 
   public:
     class DicomCacheLocker : public boost::noncopyable


=====================================
OrthancServer/main.cpp
=====================================
@@ -1121,6 +1121,11 @@ static bool ConfigureServerContext(IDatabaseWrapper& database,
     DicomUserConnection::SetDefaultTimeout(lock.GetConfiguration().GetUnsignedIntegerParameter("DicomScuTimeout", 10));
 
     maxCompletedJobs = lock.GetConfiguration().GetUnsignedIntegerParameter("JobsHistorySize", 10);
+
+    if (maxCompletedJobs == 0)
+    {
+      LOG(WARNING) << "Setting option \"JobsHistorySize\" to zero is not recommended";
+    }
   }
   
   ServerContext context(database, storageArea, false /* not running unit tests */, maxCompletedJobs);


=====================================
Resources/CMake/Compiler.cmake
=====================================
@@ -73,9 +73,12 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
     ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
     ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
 
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD" AND
+      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
     # The "--no-undefined" linker flag makes the shared libraries
-    # (plugins ModalityWorklists and ServeFolders) fail to compile on OpenBSD
+    # (plugins ModalityWorklists and ServeFolders) fail to compile on
+    # OpenBSD, and make the PostgreSQL plugin complain about missing
+    # "environ" global variable in FreeBSD
     set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
   endif()


=====================================
Resources/CMake/OrthancFrameworkParameters.cmake
=====================================
@@ -3,7 +3,7 @@
 #####################################################################
 
 # Version of the build, should always be "mainline" except in release branches
-set(ORTHANC_VERSION "1.5.2")
+set(ORTHANC_VERSION "1.5.3")
 
 # Version of the database schema. History:
 #   * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning


=====================================
Resources/Configuration.json
=====================================
@@ -438,9 +438,20 @@
   // processing job is considered as complete once it is tagged as
   // "Success" or "Failure". Since Orthanc 1.5.0, a value of "0"
   // indicates to keep no job in memory (i.e. jobs are removed from
-  // the history as soon as they are completed).
+  // the history as soon as they are completed), which prevents the
+  // use of some features of Orthanc (typically, synchronous mode in
+  // REST API) and should be avoided for non-developers.
   "JobsHistorySize" : 10,
 
+  // Whether to save the jobs into the Orthanc database. If this
+  // option is set to "true", the pending/running/completed jobs are
+  // automatically reloaded from the database if Orthanc is stopped
+  // then restarted (except if the "--no-jobs" command-line argument
+  // is specified). This option should be set to "false" if multiple
+  // Orthanc servers are using the same database (e.g. if PostgreSQL
+  // or MariaDB/MySQL is used).
+  "SaveJobs" : true,
+
   // Specifies how Orthanc reacts when it receives a DICOM instance
   // whose SOPInstanceUID is already stored. If set to "true", the new
   // instance replaces the old one. If set to "false", the new


=====================================
Resources/DownloadOrthancFramework.cmake
=====================================
@@ -95,6 +95,8 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg" OR
         set(ORTHANC_FRAMEWORK_MD5 "4429d8d9dea4ff6648df80ec3c64d79e")
       elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.5.1")
         set(ORTHANC_FRAMEWORK_MD5 "099671538865e5da96208b37494d6718")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.5.2")
+        set(ORTHANC_FRAMEWORK_MD5 "8867050f3e9a1ce6157c1ea7a9433b1b")
       endif()
     endif()
   endif()


=====================================
Resources/Patches/civetweb-1.11.patch
=====================================
@@ -1,6 +1,20 @@
+diff -urEb civetweb-1.11.orig/include/civetweb.h civetweb-1.11/include/civetweb.h
+--- civetweb-1.11.orig/include/civetweb.h	2019-01-17 21:09:41.844888908 +0100
++++ civetweb-1.11/include/civetweb.h	2019-01-21 12:05:08.138998659 +0100
+@@ -1507,6 +1507,10 @@
+ #endif
+ 
+ 
++// Added by SJ
++CIVETWEB_API void mg_disable_keep_alive(struct mg_connection *conn);
++
++
+ #ifdef __cplusplus
+ }
+ #endif /* __cplusplus */
 diff -urEb civetweb-1.11.orig/src/civetweb.c civetweb-1.11/src/civetweb.c
 --- civetweb-1.11.orig/src/civetweb.c	2019-01-17 21:09:41.852888857 +0100
-+++ civetweb-1.11/src/civetweb.c	2019-01-17 21:23:54.273424124 +0100
++++ civetweb-1.11/src/civetweb.c	2019-01-21 12:06:35.826868284 +0100
 @@ -59,6 +59,9 @@
  #if defined(__linux__) && !defined(_XOPEN_SOURCE)
  #define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
@@ -68,3 +82,17 @@ diff -urEb civetweb-1.11.orig/src/civetweb.c civetweb-1.11/src/civetweb.c
  	conn->host = alloc_get_host(conn);
  	if (!conn->host) {
  		mg_snprintf(conn,
+@@ -19857,4 +19882,13 @@
+ }
+ 
+ 
++// Added by SJ
++void mg_disable_keep_alive(struct mg_connection *conn)
++{
++  if (conn != NULL) {
++    conn->must_close = 1;
++  }
++}
++
++
+ /* End of civetweb.c */


=====================================
TODO
=====================================
@@ -95,6 +95,8 @@ SDK
 * Add plugins for normalized operations (notably so as to support
   Print SCU/SCP):
   https://www.medicalconnections.co.uk/kb/DICOM_Print_Service
+* Provide access to the Orthanc::DicomUserConnection class in plugins:
+  https://groups.google.com/d/msg/orthanc-users/ycDA1xPuTRY/nsT2_GOtEgAJ
 
 ----------------
 Ideas of plugins



View it on GitLab: https://salsa.debian.org/med-team/orthanc/commit/93758a64eea4859acd323cd547ec941c018a8739

-- 
View it on GitLab: https://salsa.debian.org/med-team/orthanc/commit/93758a64eea4859acd323cd547ec941c018a8739
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20190126/5f7b3207/attachment-0001.html>


More information about the debian-med-commit mailing list