changeset 3356:f744730c294b

Orthanc now accepts chunked transfer encoding
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 29 Apr 2019 17:24:30 +0200
parents e60e194531e5
children c0aa5f1cf2f5
files Core/HttpServer/HttpServer.cpp NEWS
diffstat 2 files changed, 62 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/Core/HttpServer/HttpServer.cpp	Tue Apr 23 22:56:17 2019 +0200
+++ b/Core/HttpServer/HttpServer.cpp	Mon Apr 29 17:24:30 2019 +0200
@@ -308,41 +308,73 @@
     IHttpHandler::Arguments::const_iterator cs = headers.find("content-length");
     if (cs == headers.end())
     {
-      return PostDataStatus_NoLength;
-    }
-
-    int length;      
-    try
-    {
-      length = boost::lexical_cast<int>(cs->second);
-    }
-    catch (boost::bad_lexical_cast&)
-    {
-      return PostDataStatus_NoLength;
-    }
+      // TODO - Avoid storing this entirely in RAM, use temporary
+      // files instead. The amount of RAM needed to receive one body
+      // of "N" bytes is currently "2*N" bytes (one copy in "buffer",
+      // one copy in "postData"). With a
+      // "ChunkedBufferInTemporaryFiles", one would need "N" bytes (in
+      // "postData" only).
+       
+      std::string tmp(1024 * 1024, 0);
+      
+      ChunkedBuffer buffer;
 
-    if (length < 0)
-    {
-      length = 0;
-    }
-
-    postData.resize(length);
-
-    size_t pos = 0;
-    while (length > 0)
-    {
-      int r = mg_read(connection, &postData[pos], length);
-      if (r <= 0)
+      for (;;)
       {
-        return PostDataStatus_Failure;
+        int r = mg_read(connection, &tmp[0], tmp.size());
+        if (r < 0)
+        {
+          return PostDataStatus_Failure;
+        }
+        else if (r == 0)
+        {
+          break;
+        }
+        else
+        {
+          buffer.AddChunk(tmp.c_str(), r);
+        }
       }
 
-      assert(r <= length);
-      length -= r;
-      pos += r;
+      buffer.Flatten(postData);
+
+      return PostDataStatus_Success;
     }
+    else
+    {
+      int length;      
+      try
+      {
+        length = boost::lexical_cast<int>(cs->second);
+      }
+      catch (boost::bad_lexical_cast&)
+      {
+        return PostDataStatus_NoLength;
+      }
 
-    return PostDataStatus_Success;
+      if (length < 0)
+      {
+        length = 0;
+      }
+
+      postData.resize(length);
+
+      size_t pos = 0;
+      while (length > 0)
+      {
+        int r = mg_read(connection, &postData[pos], length);
+        if (r <= 0)
+        {
+          return PostDataStatus_Failure;
+        }
+
+        assert(r <= length);
+        length -= r;
+        pos += r;
+      }
+
+      return PostDataStatus_Success;
+    }
   }
 
 
--- a/NEWS	Tue Apr 23 22:56:17 2019 +0200
+++ b/NEWS	Mon Apr 29 17:24:30 2019 +0200
@@ -5,6 +5,7 @@
 Maintenance
 -----------
 
+* Orthanc now accepts "-H 'Transfer-Encoding: chunked'" option from curl
 * Size of the Orthanc static binaries are reduced by compressing ICU data
 * Anonymization: Preserve hierarchical relationships in (0008,1115) [] (0020,000e)
 * Fix issue #136 (C-FIND request fails when found DICOM file does not have certain tags)