changeset 5097:d842e4446e63

Allow the HTTP server to return responses > 2GB (fixes asynchronous download of zip studies > 2GB)
author Alain Mazy <am@osimis.io>
date Thu, 13 Oct 2022 17:11:43 +0200
parents 1faae6dc282f
children edefb278cb77
files NEWS OrthancFramework/Sources/HttpServer/HttpServer.cpp
diffstat 2 files changed, 20 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Oct 13 17:11:12 2022 +0200
+++ b/NEWS	Thu Oct 13 17:11:43 2022 +0200
@@ -19,6 +19,7 @@
   Users should be careful to preserve the DICOM model when modifying high level tags.  E.g.
   if you modify the PatientID at study level, also make sure to modify all other Patient related
   tags (PatientName, PatientBirthDate, ...)
+* Allow the HTTP server to return responses > 2GB (fixes asynchronous download of zip studies > 2GB)
 
 
 OrthancFramework (C++)
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Thu Oct 13 17:11:12 2022 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp	Thu Oct 13 17:11:43 2022 +0200
@@ -35,6 +35,7 @@
 #include "IHttpHandler.h"
 #include "MultipartStreamReader.h"
 #include "StringHttpOutput.h"
+#include <algorithm>
 
 #if ORTHANC_ENABLE_PUGIXML == 1
 #  include "IWebDavBucket.h"
@@ -109,12 +110,25 @@
       {
         if (length > 0)
         {
-          int status = mg_write(connection_, buffer, length);
-          if (status != static_cast<int>(length))
+          // mg_write does not support buffers > 2GB (INT_MAX) -> need to split it
+          size_t offset = 0;
+          size_t remainingSize = length;
+
+          while (remainingSize > 0)
           {
-            // status == 0 when the connection has been closed, -1 on error
-            throw OrthancException(ErrorCode_NetworkProtocol);
-          }
+            size_t packetSize = std::min(remainingSize, static_cast<size_t>(INT_MAX));
+
+            int status = mg_write(connection_, &(reinterpret_cast<const char*>(buffer)[offset]), packetSize);  
+
+            if (status != static_cast<int>(packetSize))
+            {
+              // status == 0 when the connection has been closed, -1 on error
+              throw OrthancException(ErrorCode_NetworkProtocol);
+            }
+
+            offset += packetSize;
+            remainingSize -= packetSize;
+          }  
         }
       }