diff OrthancFramework/Sources/HttpServer/HttpOutput.cpp @ 5406:aaf7c49a9ddc am-http-compression

tentative to implement smart HTTP compression with detection of transfer syntax
author Alain Mazy <am@osimis.io>
date Sat, 04 Nov 2023 13:42:30 +0100
parents 0ea402b4d901
children
line wrap: on
line diff
--- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp	Tue Oct 17 15:06:11 2023 +0200
+++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp	Sat Nov 04 13:42:30 2023 +0100
@@ -51,6 +51,7 @@
                                          unsigned int keepAliveTimeout) : 
     stream_(stream),
     state_(State_WritingHeader),
+    contentCompression_(ContentCompression_Unknown),
     status_(HttpStatus_200_Ok),
     hasContentLength_(false),
     contentLength_(0),
@@ -102,6 +103,20 @@
     AddHeader("Content-Type", contentType);
   }
 
+  void HttpOutput::StateMachine::SetContentCompression(ContentCompression contentCompression)
+  {
+    contentCompression_ = contentCompression;
+  }
+
+  bool HttpOutput::StateMachine::IsContentCompressible() const
+  {
+    // We assume that all files that compress correctly (mainly JSON, XML) are clearly identified.
+    // Therefore, only the content identified as NotCompressed are compressed again.
+    // We consider that the content whose compression is Unknown, likely DICOM file whose transfer syntax
+    // could not be determined, must not be compressed either. 
+    return contentCompression_ == ContentCompression_NotCompressed;
+  }
+
   void HttpOutput::StateMachine::SetContentFilename(const char* filename)
   {
     // TODO Escape double quotes
@@ -275,13 +290,11 @@
 
   HttpCompression HttpOutput::GetPreferredCompression(size_t bodySize) const
   {
-#if 0
-    // TODO Do not compress small files?
-    if (bodySize < 512)
+    // Do not compress small files since there is no real size benefit.
+    if (bodySize < 2048)
     {
       return HttpCompression_None;
     }
-#endif
 
     // Prefer "gzip" over "deflate" if the choice is offered
 
@@ -375,6 +388,11 @@
     stateMachine_.SetContentType(contentType.c_str());
   }
 
+  void HttpOutput::SetContentCompression(ContentCompression contentCompression)
+  {
+    stateMachine_.SetContentCompression(contentCompression);
+  }
+
   void HttpOutput::SetContentFilename(const char *filename)
   {
     stateMachine_.SetContentFilename(filename);
@@ -442,7 +460,7 @@
 
     HttpCompression compression = GetPreferredCompression(length);
 
-    if (compression == HttpCompression_None)
+    if (compression == HttpCompression_None || !IsContentCompressible())
     {
       stateMachine_.SetContentLength(length);
       stateMachine_.SendBody(buffer, length);
@@ -816,6 +834,11 @@
   {
     HttpCompression compression = stream.SetupHttpCompression(isGzipAllowed_, isDeflateAllowed_);
 
+    if (!IsContentCompressible())
+    {
+      compression = HttpCompression_None;
+    }
+
     switch (compression)
     {
       case HttpCompression_None: