changeset 2984:db8f360fcb41

OrthancPluginAutodetectMimeType()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 08 Dec 2018 20:59:37 +0100
parents af068a6b476b
children 32ec5078e32b
files Core/Enumerations.cpp Core/Enumerations.h Core/SystemToolbox.cpp NEWS Plugins/Engine/OrthancPlugins.cpp Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Plugins/Samples/Common/OrthancPluginCppWrapper.h UnitTestsSources/UnitTestsMain.cpp
diffstat 9 files changed, 160 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Enumerations.cpp	Sat Dec 08 11:54:14 2018 +0100
+++ b/Core/Enumerations.cpp	Sat Dec 08 20:59:37 2018 +0100
@@ -51,8 +51,12 @@
   static const char* const MIME_HTML = "text/html";
   static const char* const MIME_JAVASCRIPT = "application/javascript";
   static const char* const MIME_JPEG2000 = "image/jp2";
+  static const char* const MIME_NACL = "application/x-nacl";
   static const char* const MIME_PLAIN_TEXT = "text/plain";
+  static const char* const MIME_PNACL = "application/x-pnacl";
+  static const char* const MIME_SVG = "image/svg+xml";
   static const char* const MIME_WEB_ASSEMBLY = "application/wasm";
+  static const char* const MIME_WOFF = "application/x-font-woff";
   static const char* const MIME_XML_2 = "text/xml";
   static const char* const MIME_ZIP = "application/zip";
 
@@ -1088,6 +1092,18 @@
       case MimeType_Zip:
         return MIME_ZIP;
                 
+      case MimeType_NaCl:
+        return MIME_NACL;
+                
+      case MimeType_PNaCl:
+        return MIME_PNACL;
+                
+      case MimeType_Svg:
+        return MIME_SVG;
+                
+      case MimeType_Woff:
+        return MIME_WOFF;
+                
       default:
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
@@ -1680,6 +1696,22 @@
     {
       return MimeType_Zip;
     }
+    else if (mime == MIME_NACL)
+    {
+      return MimeType_NaCl;
+    }
+    else if (mime == MIME_PNACL)
+    {
+      return MimeType_PNaCl;
+    }
+    else if (mime == MIME_SVG)
+    {
+      return MimeType_Svg;
+    }
+    else if (mime == MIME_WOFF)
+    {
+      return MimeType_Woff;
+    }
     else
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
--- a/Core/Enumerations.h	Sat Dec 08 11:54:14 2018 +0100
+++ b/Core/Enumerations.h	Sat Dec 08 20:59:37 2018 +0100
@@ -86,21 +86,25 @@
   enum MimeType
   {
     MimeType_Binary,
+    MimeType_Css,
     MimeType_Dicom,
+    MimeType_Gif,
+    MimeType_Gzip,
     MimeType_Html,
+    MimeType_JavaScript,
     MimeType_Jpeg,
     MimeType_Jpeg2000,
     MimeType_Json,
+    MimeType_NaCl,
+    MimeType_PNaCl,
     MimeType_Pam,
     MimeType_Pdf,
     MimeType_PlainText,
     MimeType_Png,
+    MimeType_Svg,
+    MimeType_WebAssembly,
     MimeType_Xml,
-    MimeType_Gzip,
-    MimeType_JavaScript,
-    MimeType_Css,
-    MimeType_WebAssembly,
-    MimeType_Gif,
+    MimeType_Woff,  // Web Open Font Format
     MimeType_Zip
   };
 
--- a/Core/SystemToolbox.cpp	Sat Dec 08 11:54:14 2018 +0100
+++ b/Core/SystemToolbox.cpp	Sat Dec 08 20:59:37 2018 +0100
@@ -649,7 +649,8 @@
     {
       return MimeType_JavaScript;
     }
-    else if (extension == ".json")
+    else if (extension == ".json" ||
+             extension == ".nmf"  /* manifest */)
     {
       return MimeType_Json;
     }
@@ -661,6 +662,14 @@
     {
       return MimeType_WebAssembly;
     }
+    else if (extension == ".nexe")
+    {
+      return MimeType_NaCl;
+    }
+    else if (extension == ".pexe")
+    {
+      return MimeType_PNaCl;
+    }
 
     // Images types
     else if (extension == ".jpg" ||
@@ -680,8 +689,21 @@
     {
       return MimeType_Pam;
     }
+    else if (extension == ".svg")
+    {
+      return MimeType_Svg;
+    }
+
+    // Various types
+    else if (extension == ".woff")
+    {
+      return MimeType_Woff;
+    }
+
+    // Default type
     else
     {
+      LOG(INFO) << "Unknown MIME type for extension \"" << extension << "\"";
       return MimeType_Binary;
     }
   }
--- a/NEWS	Sat Dec 08 11:54:14 2018 +0100
+++ b/NEWS	Sat Dec 08 20:59:37 2018 +0100
@@ -36,7 +36,9 @@
 Plugins
 -------
 
-* New function in the SDK: "OrthancPluginSetHttpErrorDetails()"
+* New functions in the SDK:
+  - "OrthancPluginSetHttpErrorDetails()"
+  - "OrthancPluginAutodetectMimeType()"
 
 Maintenance
 -----------
--- a/Plugins/Engine/OrthancPlugins.cpp	Sat Dec 08 11:54:14 2018 +0100
+++ b/Plugins/Engine/OrthancPlugins.cpp	Sat Dec 08 20:59:37 2018 +0100
@@ -3080,6 +3080,14 @@
         return true;
       }
 
+      case _OrthancPluginService_AutodetectMimeType:
+      {
+        const _OrthancPluginRetrieveStaticString& p =
+          *reinterpret_cast<const _OrthancPluginRetrieveStaticString*>(parameters);
+        *p.result = EnumerationToString(SystemToolbox::AutodetectMimeType(p.argument));
+        return true;
+      }
+
       default:
         return false;
     }
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Sat Dec 08 11:54:14 2018 +0100
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Sat Dec 08 20:59:37 2018 +0100
@@ -423,7 +423,8 @@
     _OrthancPluginService_CallHttpClient2 = 27,
     _OrthancPluginService_GenerateUuid = 28,
     _OrthancPluginService_RegisterPrivateDictionaryTag = 29,
-
+    _OrthancPluginService_AutodetectMimeType = 30,
+    
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
     _OrthancPluginService_RegisterOnStoredInstanceCallback = 1001,
@@ -6468,6 +6469,45 @@
 
 
 
+  typedef struct
+  {
+    const char** result;
+    const char*  argument;
+  } _OrthancPluginRetrieveStaticString;
+
+  /**
+   * @brief Detect the MIME type of a file.
+   *
+   * This function returns the MIME type of a file by inspecting its extension.
+   * 
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param path Path to the file.
+   * @return The MIME type. This is a statically-allocated
+   * string, do not free it.
+   * @ingroup Toolbox
+   **/
+  ORTHANC_PLUGIN_INLINE const char* OrthancPluginAutodetectMimeType(
+    OrthancPluginContext*  context,
+    const char*            path)
+  {
+    const char* result = NULL;
+
+    _OrthancPluginRetrieveStaticString params;
+    params.result = &result;
+    params.argument = path;
+
+    if (context->InvokeService(context, _OrthancPluginService_AutodetectMimeType, &params) != OrthancPluginErrorCode_Success)
+    {
+      /* Error */
+      return NULL;
+    }
+    else
+    {
+      return result;
+    }
+  }
+
+
 #ifdef  __cplusplus
 }
 #endif
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Sat Dec 08 11:54:14 2018 +0100
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Sat Dec 08 20:59:37 2018 +0100
@@ -1356,61 +1356,23 @@
     }
   }
 
-  const char* GetMimeType(const std::string& path)
+  
+  const char* AutodetectMimeType(const std::string& path)
   {
-    size_t dot = path.find_last_of('.');
-
-    std::string extension = (dot == std::string::npos) ? "" : path.substr(dot);
-    std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
+    const char* mime = OrthancPluginAutodetectMimeType(GetGlobalContext(), path.c_str());
 
-    if (extension == ".html")
-    {
-      return "text/html";
-    }
-    else if (extension == ".css")
-    {
-      return "text/css";
-    }
-    else if (extension == ".js")
-    {
-      return "application/javascript";
-    }
-    else if (extension == ".gif")
+    if (mime == NULL)
     {
-      return "image/gif";
-    }
-    else if (extension == ".svg")
-    {
-      return "image/svg+xml";
-    }
-    else if (extension == ".json")
-    {
-      return "application/json";
-    }
-    else if (extension == ".xml")
-    {
-      return "application/xml";
-    }
-    else if (extension == ".wasm")
-    {
-      return "application/wasm";
-    }
-    else if (extension == ".png")
-    {
-      return "image/png";
-    }
-    else if (extension == ".jpg" || extension == ".jpeg")
-    {
-      return "image/jpeg";
+      // Should never happen, just for safety
+      return "application/octet-stream";
     }
     else
     {
-      return "application/octet-stream";
+      return mime;
     }
   }
 
 
-
 #if HAS_ORTHANC_PLUGIN_PEERS == 1
   size_t OrthancPeers::GetPeerIndex(const std::string& name) const
   {
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Sat Dec 08 11:54:14 2018 +0100
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Sat Dec 08 20:59:37 2018 +0100
@@ -492,8 +492,7 @@
 
   void AnswerMethodNotAllowed(OrthancPluginRestOutput* output, const char* allowedMethods);
 
-  const char* GetMimeType(const std::string& path);
-
+  const char* AutodetectMimeType(const std::string& path);
 
   void LogError(const std::string& message);
 
--- a/UnitTestsSources/UnitTestsMain.cpp	Sat Dec 08 11:54:14 2018 +0100
+++ b/UnitTestsSources/UnitTestsMain.cpp	Sat Dec 08 20:59:37 2018 +0100
@@ -325,6 +325,30 @@
   ASSERT_EQ(MimeType_Jpeg, SystemToolbox::AutodetectMimeType("NOTES.jpg"));
   ASSERT_EQ(MimeType_Jpeg, SystemToolbox::AutodetectMimeType("NOTES.jpeg"));
   ASSERT_EQ(MimeType_Png, SystemToolbox::AutodetectMimeType("NOTES.png"));
+  ASSERT_EQ(MimeType_NaCl, SystemToolbox::AutodetectMimeType("NOTES.nexe"));
+  ASSERT_EQ(MimeType_Json, SystemToolbox::AutodetectMimeType("NOTES.nmf"));
+  ASSERT_EQ(MimeType_PNaCl, SystemToolbox::AutodetectMimeType("NOTES.pexe"));
+  ASSERT_EQ(MimeType_Svg, SystemToolbox::AutodetectMimeType("NOTES.svg"));
+  ASSERT_EQ(MimeType_Woff, SystemToolbox::AutodetectMimeType("NOTES.woff"));
+
+  // Test primitives from the "RegisterDefaultExtensions()" that was
+  // present in the sample "Serve Folders plugin" of Orthanc 1.4.2
+  ASSERT_STREQ("application/javascript", EnumerationToString(SystemToolbox::AutodetectMimeType(".js")));
+  ASSERT_STREQ("application/json", EnumerationToString(SystemToolbox::AutodetectMimeType(".json")));
+  ASSERT_STREQ("application/json", EnumerationToString(SystemToolbox::AutodetectMimeType(".nmf")));
+  ASSERT_STREQ("application/octet-stream", EnumerationToString(SystemToolbox::AutodetectMimeType("")));
+  ASSERT_STREQ("application/wasm", EnumerationToString(SystemToolbox::AutodetectMimeType(".wasm")));
+  ASSERT_STREQ("application/x-font-woff", EnumerationToString(SystemToolbox::AutodetectMimeType(".woff")));
+  ASSERT_STREQ("application/x-nacl", EnumerationToString(SystemToolbox::AutodetectMimeType(".nexe")));
+  ASSERT_STREQ("application/x-pnacl", EnumerationToString(SystemToolbox::AutodetectMimeType(".pexe")));
+  ASSERT_STREQ("application/xml", EnumerationToString(SystemToolbox::AutodetectMimeType(".xml")));
+  ASSERT_STREQ("image/gif", EnumerationToString(SystemToolbox::AutodetectMimeType(".gif")));
+  ASSERT_STREQ("image/jpeg", EnumerationToString(SystemToolbox::AutodetectMimeType(".jpeg")));
+  ASSERT_STREQ("image/jpeg", EnumerationToString(SystemToolbox::AutodetectMimeType(".jpg")));
+  ASSERT_STREQ("image/png", EnumerationToString(SystemToolbox::AutodetectMimeType(".png")));
+  ASSERT_STREQ("image/svg+xml", EnumerationToString(SystemToolbox::AutodetectMimeType(".svg")));
+  ASSERT_STREQ("text/css", EnumerationToString(SystemToolbox::AutodetectMimeType(".css")));
+  ASSERT_STREQ("text/html", EnumerationToString(SystemToolbox::AutodetectMimeType(".html")));
 }
 
 TEST(Toolbox, ComputeMD5)
@@ -711,23 +735,26 @@
   ASSERT_THROW(StringToJobState("nope"), OrthancException);
 
   ASSERT_EQ(MimeType_Binary, StringToMimeType(EnumerationToString(MimeType_Binary)));
+  ASSERT_EQ(MimeType_Css, StringToMimeType(EnumerationToString(MimeType_Css)));
   ASSERT_EQ(MimeType_Dicom, StringToMimeType(EnumerationToString(MimeType_Dicom)));
+  ASSERT_EQ(MimeType_Gif, StringToMimeType(EnumerationToString(MimeType_Gif)));
+  ASSERT_EQ(MimeType_Gzip, StringToMimeType(EnumerationToString(MimeType_Gzip)));
+  ASSERT_EQ(MimeType_Html, StringToMimeType(EnumerationToString(MimeType_Html)));
+  ASSERT_EQ(MimeType_JavaScript, StringToMimeType(EnumerationToString(MimeType_JavaScript)));
   ASSERT_EQ(MimeType_Jpeg, StringToMimeType(EnumerationToString(MimeType_Jpeg)));
   ASSERT_EQ(MimeType_Jpeg2000, StringToMimeType(EnumerationToString(MimeType_Jpeg2000)));
   ASSERT_EQ(MimeType_Json, StringToMimeType(EnumerationToString(MimeType_Json)));
+  ASSERT_EQ(MimeType_NaCl, StringToMimeType(EnumerationToString(MimeType_NaCl)));
+  ASSERT_EQ(MimeType_PNaCl, StringToMimeType(EnumerationToString(MimeType_PNaCl)));
+  ASSERT_EQ(MimeType_Pam, StringToMimeType(EnumerationToString(MimeType_Pam)));
   ASSERT_EQ(MimeType_Pdf, StringToMimeType(EnumerationToString(MimeType_Pdf)));
+  ASSERT_EQ(MimeType_PlainText, StringToMimeType(EnumerationToString(MimeType_PlainText)));
   ASSERT_EQ(MimeType_Png, StringToMimeType(EnumerationToString(MimeType_Png)));
-  ASSERT_EQ(MimeType_Xml, StringToMimeType(EnumerationToString(MimeType_Xml)));
+  ASSERT_EQ(MimeType_Svg, StringToMimeType(EnumerationToString(MimeType_Svg)));
+  ASSERT_EQ(MimeType_WebAssembly, StringToMimeType(EnumerationToString(MimeType_WebAssembly)));
   ASSERT_EQ(MimeType_Xml, StringToMimeType("application/xml"));
   ASSERT_EQ(MimeType_Xml, StringToMimeType("text/xml"));
-  ASSERT_EQ(MimeType_PlainText, StringToMimeType(EnumerationToString(MimeType_PlainText)));
-  ASSERT_EQ(MimeType_Pam, StringToMimeType(EnumerationToString(MimeType_Pam)));
-  ASSERT_EQ(MimeType_Html, StringToMimeType(EnumerationToString(MimeType_Html)));
-  ASSERT_EQ(MimeType_Gzip, StringToMimeType(EnumerationToString(MimeType_Gzip)));
-  ASSERT_EQ(MimeType_JavaScript, StringToMimeType(EnumerationToString(MimeType_JavaScript)));
-  ASSERT_EQ(MimeType_Gif, StringToMimeType(EnumerationToString(MimeType_Gif)));
-  ASSERT_EQ(MimeType_WebAssembly, StringToMimeType(EnumerationToString(MimeType_WebAssembly)));
-  ASSERT_EQ(MimeType_Css, StringToMimeType(EnumerationToString(MimeType_Css)));
+  ASSERT_EQ(MimeType_Xml, StringToMimeType(EnumerationToString(MimeType_Xml)));
   ASSERT_THROW(StringToMimeType("nope"), OrthancException);
 }